Vulkan wrong depth values

Hi!
First of all when I select the house the character is over the house…

I tried to change my shader but there is somethings which is surprising…
When I change the compraison from < to > here :

if (frags[j - 1].depth > frags[j].depth) {

Nothing change, I’ve the same rendering frame…, or logically if I change the sign, the render frame have to change because the sort of the fragments is reverted.

I have not this problem with openGL…
Thanks.

I use the same algorithm than Sacha Willems examples on git, but, that doesn’t work when I select this object…
I do several submits. (one for non selected objects and one for selected object)
I don’t clear the linked list after the first submit so why I’ve this strange rendering ?

Ok it seems I have to enable a feature for store and atomic operations :

The feature is avalaible :

bool Device::isDeviceSuitable(VkPhysicalDevice device,  VkSurfaceKHR surface) {
            QueueFamilyIndices indices = findQueueFamilies(device, surface);
            if (surface != VK_NULL_HANDLE) {
                bool extensionsSupported = checkDeviceExtensionSupport(device);
                bool swapChainAdequate;
                if (extensionsSupported) {
                    SwapChainSupportDetails swapChainSupport = querySwapChainSupport(device, surface);
                    swapChainAdequate = !swapChainSupport.formats.empty() && !swapChainSupport.presentModes.empty();
                } else {
                    swapChainAdequate = true;
                }
                VkPhysicalDeviceFeatures supportedFeatures;
                vkGetPhysicalDeviceFeatures(device, &supportedFeatures);
                VkPhysicalDeviceFeatures2 physical_features2 = {};
                physical_features2.sType =  VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;

                VkPhysicalDeviceVulkan11Features features11 = {};
                features11.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
                physical_features2.pNext = &features11;
                vkGetPhysicalDeviceFeatures2(device, &physical_features2);

                VkPhysicalDeviceVulkan12Features features12 = {};
                features12.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
                physical_features2.pNext = &features12;
                vkGetPhysicalDeviceFeatures2(device, &physical_features2);
                return indices.isComplete() && extensionsSupported && swapChainAdequate && supportedFeatures.samplerAnisotropy && supportedFeatures.fragmentStoresAndAtomics == VK_TRUE &&
                features11.shaderDrawParameters == VK_TRUE && features12.runtimeDescriptorArray == VK_TRUE;
            }
...

But when I want to enable it :

void Device::createLogicalDevice(VkSurfaceKHR surface) {
            if (device == VK_NULL_HANDLE) {
                std::vector<VkDeviceQueueCreateInfo> queueCreateInfos;
                std::set<uint32_t> uniqueQueueFamilies;
                 QueueFamilyIndices indices;
                if (surface != VK_NULL_HANDLE) {
                    indices = findQueueFamilies(physicalDevice, surface);
                    uniqueQueueFamilies = {indices.graphicsFamily.value(), indices.presentFamily.value()};
                } else {
                    indices = findQueueFamilies(physicalDevice, surface);
                    uniqueQueueFamilies = {indices.graphicsFamily.value()};
                }
                float queuePriority = 1.0f;
                for (uint32_t queueFamily : uniqueQueueFamilies) {
                    VkDeviceQueueCreateInfo queueCreateInfo{};
                    queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
                    queueCreateInfo.queueFamilyIndex = queueFamily;
                    queueCreateInfo.queueCount = 1;
                    queueCreateInfo.pQueuePriorities = &queuePriority;
                    queueCreateInfos.push_back(queueCreateInfo);
                }



                VkPhysicalDeviceFeatures deviceFeatures;
                deviceFeatures.samplerAnisotropy = VK_TRUE;
                deviceFeatures.fragmentStoresAndAtomics = VK_TRUE;
                //vkGetPhysicalDeviceFeatures(physicalDevice, &deviceFeatures);
                VkPhysicalDeviceVulkan11Features features11 = {};
                features11.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
                VkPhysicalDeviceVulkan12Features features12 = {};
                features12.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;


                VkPhysicalDeviceFeatures2 physical_features21;
                physical_features21.sType =  VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
                physical_features21.pNext = &features11;
                vkGetPhysicalDeviceFeatures2(physicalDevice, &physical_features21);

                VkPhysicalDeviceFeatures2 physical_features22;
                physical_features22.sType =  VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
                physical_features22.pNext = &features12;
                vkGetPhysicalDeviceFeatures2(physicalDevice, &physical_features22);

                features11.pNext = &features12;



                //features12.pNext = &deviceFeatures;

                PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR = reinterpret_cast<PFN_vkGetPhysicalDeviceProperties2KHR>(vkGetInstanceProcAddr(vkSettup.getInstance(), "vkGetPhysicalDeviceProperties2KHR"));
                if (!vkGetPhysicalDeviceProperties2KHR) {
                    throw core::Erreur(0, "Could not get a valid function pointer for vkGetPhysicalDeviceProperties2KHR", 1);
                }
                VkPhysicalDeviceProperties2KHR deviceProps2{};
                pushDescriptorProps.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR;
                deviceProps2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR;
                deviceProps2.pNext = &pushDescriptorProps;
                vkGetPhysicalDeviceProperties2KHR(physicalDevice, &deviceProps2);

                VkDeviceCreateInfo createInfo{};
                createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
                createInfo.pNext = &physical_features21;

                createInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size());
                createInfo.pQueueCreateInfos = queueCreateInfos.data();

                createInfo.pEnabledFeatures = &deviceFeatures;

                createInfo.enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size());
                createInfo.ppEnabledExtensionNames = nullptr;

                if (enableValidationLayers) {
                    createInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
                    createInfo.ppEnabledLayerNames = validationLayers.data();
                } else {
                    createInfo.enabledLayerCount = 0;
                }

                if (vkCreateDevice(physicalDevice, &createInfo, nullptr, &device) != VK_SUCCESS) {
                    throw core::Erreur(0, "failed to create logical device!", 1);
                }
                vkGetDeviceQueue(device, indices.graphicsFamily.value(), 0, &graphicsQueue);
                if (surface != VK_NULL_HANDLE) {
                    vkGetDeviceQueue(device, indices.presentFamily.value(), 0, &presentQueue);
                }
            }
        }
       

Vulkan crash…

Thanks.

Ok I’ve set up the feature correctly now it runs but the driver crash when I pass a memory barrier to vkCmdPipelineBarrier :

 VkBufferMemoryBarrier memoryBarrier;
                memoryBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
                memoryBarrier.pNext = VK_NULL_HANDLE;
                memoryBarrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
                memoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
                memoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
                memoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
                memoryBarrier.buffer = linkedListShaderStorageBuffers[i];
                memoryBarrier.offset = 0;
                memoryBarrier.size = nodeSize * maxNodes;
                VkImageSubresourceRange    subresourceRange;
                subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
                subresourceRange.baseMipLevel = 0;
                subresourceRange.levelCount = 1;
                subresourceRange.baseArrayLayer = 0;
                subresourceRange.layerCount = 1;
                VkImageMemoryBarrier imgMemoryBarrier;
                imgMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
                imgMemoryBarrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
                imgMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
                imgMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_GENERAL;
                imgMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_GENERAL;
                imgMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
                imgMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
                imgMemoryBarrier.image = headPtrTextureImage;
                imgMemoryBarrier.subresourceRange = subresourceRange;


                vkCmdPipelineBarrier(commandBuffers[i], VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0, &memoryBarrier, 1, &imgMemoryBarrier);

Ok I just needed to initialize pNext to null…

But the depth values are still wrong…

I printed the depth values in the textures and the output is very strange.

Hi! I tried to solve the problem using a timeline semaphore but even with this the second submit doesn’t wait that the first submit is done in the GPU.

void RenderTexture::display() {
            if (getCommandBuffers().size() > 0) {
                //std::cout<<"render texture end command buffer"<<std::endl;

                for (unsigned int i = 0; i < getCommandBuffers().size(); i++) {
                    if (vkEndCommandBuffer(getCommandBuffers()[i]) != VK_SUCCESS) {
                        throw core::Erreur(0, "failed to record command buffer!", 1);
                    }
                }
                 vkWaitForFences(vkDevice.getDevice(), 1, &inFlightFences[currentFrame], VK_TRUE, UINT64_MAX);
                const uint64_t waitValue = value; // Wait until semaphore value is >= 2
                const uint64_t signalValue = value+1;

                VkTimelineSemaphoreSubmitInfo timelineInfo;
                timelineInfo.sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO;
                timelineInfo.pNext = NULL;
                timelineInfo.waitSemaphoreValueCount = 1;
                timelineInfo.pWaitSemaphoreValues = &waitValue;
                timelineInfo.signalSemaphoreValueCount = 1;
                timelineInfo.pSignalSemaphoreValues = &signalValue;


                VkSubmitInfo submitInfo{};
                submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;



                VkSemaphore waitSemaphores[] = {renderFinishedSemaphores[currentFrame]};
                VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
                submitInfo.pNext = &timelineInfo;
                submitInfo.waitSemaphoreCount = 1;
                submitInfo.pWaitSemaphores = waitSemaphores;
                submitInfo.pWaitDstStageMask = waitStages;
                submitInfo.commandBufferCount = 1;
                submitInfo.pCommandBuffers = &getCommandBuffers()[currentFrame];
                submitInfo.signalSemaphoreCount = 1;
                submitInfo.pSignalSemaphores = waitSemaphores;


                vkResetFences(vkDevice.getDevice(), 1, &inFlightFences[currentFrame]);
                if (vkQueueSubmit(vkDevice.getGraphicsQueue(), 1, &submitInfo, inFlightFences[currentFrame]) != VK_SUCCESS) {
                    throw core::Erreur(0, "échec de l'envoi d'un command buffer!", 1);
                }
                vkDeviceWaitIdle(vkDevice.getDevice());
                value++;
            }
        }

Thanks.

EDIT : Or it’s not a synchronization issue, the colors are good but it seems the depth value is not initalized here :

void main() {
                                                           uint nodeIdx = atomicCounterIncrement(nextNodeCounter);
                                                           //sampler2D tex = sampler2D(GetTexture(texIndex-1));
                                                           vec4 color = (texIndex != 0) ? frontColor * texture(textures[texIndex-1], fTexCoords.xy) : frontColor;
                                                           if (nodeIdx < maxNodes) {
                                                                uint prevHead = imageAtomicExchange(headPointers, ivec2(gl_FragCoord.xy), nodeIdx);
                                                                nodes[nodeIdx].color = color;
                                                                nodes[nodeIdx].depth = gl_FragCoord.z;
                                                                nodes[nodeIdx].next = prevHead;
                                                           }
                                                           //fcolor = vec4(0, 0, 0, 0);
                                                      })";

Hi! I printed the values of gl_FragCoord.z in the red component of the texture, and, they are wrong when fragments are overlapping…, when fragments are not overlapping the color is red, but when fragments are overlapping, the color is black it’s like gl_Fragcoord.z is equal to 0…
Not normal.

Hi! I’ve found why my depth value is wrong, I had to invert min and max depth, because I work with 1 in the near plane and 0 at the far plane.

But the caracter is always displayed over the selected house, event with semaphores, barrier and fence and I don’t know why. I don’t have this problem with opengl…

Ok I tried VkEvents but it seems it don’t synchronize anything. vkCmdWaitEvents doesn’t wait…

I launched renderdocs and this is not a synchronization issue but the problem is that I use two render passes and in my second render pass the values of the depth is always equal to 0…

Ok the depth texture show me in renderdoc that the values of gl_FragCoord.z are always 0 for my second renderer object, but they are good for my first renderer object. And I it’s the same renderer class so if it’s ok for my first renderer object it should be ok for my second renderer object.
And I enabled the depth test with op always…

Driver bug ?

Here is what renderdocs show for my depth texture :
The first depth texture is ok :


But the second not, we see that this is black. (depth = 0)

I create my render pass here : (I’ve followed the tutorial about vulkan, the only difference is that I need the stencil buffer)

 void RenderTexture::createRenderPass() {
            for (unsigned int i = 0; i < 2; i++) {
                if (i == 0) {
                    VkAttachmentDescription colorAttachment{};
                    colorAttachment.format =    getSwapchainImageFormat();
                    colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
                    colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
                    colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
                    colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
                    colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
                    colorAttachment.initialLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
                    colorAttachment.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;

                    VkAttachmentReference colorAttachmentRef{};
                    colorAttachmentRef.attachment = 0;
                    colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;


                    VkSubpassDescription subpass{};
                    subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
                    subpass.colorAttachmentCount = 1;
                    subpass.pColorAttachments = &colorAttachmentRef;
                    subpass.pDepthStencilAttachment = nullptr;

                    std::array<VkAttachmentDescription, 1> attachments = {colorAttachment};

                    VkRenderPassCreateInfo renderPassInfo{};
                    renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
                    renderPassInfo.attachmentCount = static_cast<uint32_t>(attachments.size());
                    renderPassInfo.pAttachments = attachments.data();
                    renderPassInfo.subpassCount = 1;
                    renderPassInfo.pSubpasses = &subpass;
                    VkSubpassDependency dependency{};
                    dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
                    dependency.dstSubpass = 0;
                    dependency.srcStageMask =  VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
                    dependency.srcAccessMask = 0;
                    dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
                    dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
                    renderPassInfo.dependencyCount = 1;
                    renderPassInfo.pDependencies = &dependency;
                    VkRenderPass renderPass;
                    if (vkCreateRenderPass(vkDevice.getDevice(), &renderPassInfo, nullptr, &renderPass) != VK_SUCCESS) {
                        throw core::Erreur(0, "failed to create render pass!", 1);
                    }
                    renderPasses.push_back(renderPass);

                } else {
                    VkAttachmentDescription colorAttachment{};
                    colorAttachment.format =    getSwapchainImageFormat();
                    colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
                    colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
                    colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
                    colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
                    colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
                    colorAttachment.initialLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
                    colorAttachment.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;

                    VkAttachmentDescription depthAttachment{};
                    depthAttachment.format = getDepthTexture().findDepthFormat();
                    depthAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
                    depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
                    depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
                    depthAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
                    depthAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
                    depthAttachment.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
                    depthAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;

                    VkAttachmentReference colorAttachmentRef{};
                    colorAttachmentRef.attachment = 0;
                    colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;

                    VkAttachmentReference depthAttachmentRef{};
                    depthAttachmentRef.attachment = 1;
                    depthAttachmentRef.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;

                    VkSubpassDescription subpass{};
                    subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
                    subpass.colorAttachmentCount = 1;
                    subpass.pColorAttachments = &colorAttachmentRef;
                    subpass.pDepthStencilAttachment = &depthAttachmentRef;

                    std::array<VkAttachmentDescription, 2> attachments = {colorAttachment, depthAttachment};

                    VkRenderPassCreateInfo renderPassInfo{};
                    renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
                    renderPassInfo.attachmentCount = static_cast<uint32_t>(attachments.size());
                    renderPassInfo.pAttachments = attachments.data();
                    renderPassInfo.subpassCount = 1;
                    renderPassInfo.pSubpasses = &subpass;
                    VkSubpassDependency dependency{};
                    dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
                    dependency.dstSubpass = 0;
                    dependency.srcStageMask =  VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
                    dependency.srcAccessMask = 0;
                    dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
                    dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
                    renderPassInfo.dependencyCount = 1;
                    renderPassInfo.pDependencies = &dependency;
                    VkRenderPass renderPass;
                    if (vkCreateRenderPass(vkDevice.getDevice(), &renderPassInfo, nullptr, &renderPass) != VK_SUCCESS) {
                        throw core::Erreur(0, "failed to create render pass!", 1);
                    }
                    renderPasses.push_back(renderPass);
                }
            }

        }

When I draw I get the right renderpass if the depth or stencil test is enabled or not :

void RenderTarget::drawIndirect(VkCommandBuffer& cmd, unsigned int i, unsigned int nbIndirectCommands, unsigned int stride, VertexBuffer& vertexBuffer, VkBuffer vboIndirect, unsigned int depthStencilId, RenderStates states) {
            Shader* shader = const_cast<Shader*>(states.shader);
            //std::cout<<"draw indirect depth stencil id :"<<depthStencilId<<std::endl;

            VkRenderPassBeginInfo renderPassInfo{};
            renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
            renderPassInfo.renderPass = (depthTestEnabled || stencilTestEnabled) ? getRenderPass(1) : getRenderPass(0);
            renderPassInfo.framebuffer = (depthTestEnabled || stencilTestEnabled) ? getSwapchainFrameBuffers(1)[getImageIndex()] : getSwapchainFrameBuffers(0)[getImageIndex()];
            renderPassInfo.renderArea.offset = {0, 0};
            renderPassInfo.renderArea.extent = getSwapchainExtents();

            VkClearValue clrColor = {clearColor.r / 255.f,clearColor.g / 255.f, clearColor.b / 255.f, clearColor.a / 255.f};
            renderPassInfo.clearValueCount = 1;
            renderPassInfo.pClearValues = &clrColor;

            vkCmdBeginRenderPass(cmd, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
            vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline[shader->getId() * (Batcher::nbPrimitiveTypes - 1)+vertexBuffer.getPrimitiveType()][id][depthStencilId]);
            VkBuffer vertexBuffers[] = {vertexBuffer.getVertexBuffer()};
            VkDeviceSize offsets[] = {0, 0};
            vkCmdBindVertexBuffers(cmd, 0, 1, vertexBuffers, offsets);

            VkViewport viewport{};
            viewport.x = 0.0f;
            viewport.y = 0.0f;
            viewport.width = getSwapchainExtents().width;
            viewport.height = getSwapchainExtents().height;
            viewport.minDepth = 0.0f;
            viewport.maxDepth = 1.0f;
            vkCmdSetViewport(cmd, 0, 1, &viewport);

            VkRect2D scissor{};
            scissor.offset = {0, 0};
            scissor.extent = getSwapchainExtents();
            vkCmdSetScissor(cmd, 0, 1, &scissor);
            if(vertexBuffer.getIndicesSize() > 0) {
                vkCmdBindIndexBuffer(cmd, vertexBuffer.getIndexBuffer(), 0, VK_INDEX_TYPE_UINT16);
            }
            if(vertexBuffer.getIndicesSize() > 0) {
                vkCmdDrawIndexedIndirect(cmd, vboIndirect, 0, nbIndirectCommands, stride);
            } else {
                vkCmdDrawIndirect(cmd, vboIndirect, 0, nbIndirectCommands, stride);
            }
            vkCmdEndRenderPass(cmd);
        }

I’ve found what’s wrong, it’s because the y axis is inversed on vulkan so here depth = 0 :

VkSettup settup;
    Device device(settup);
    RenderWindow window(sf::VideoMode(800, 600), "test",device);
    Vec3f pos(100, 50, 0);
    Matrix4f projection = window.getView().getProjMatrix().getMatrix();
    Matrix4f view = window.getView().getViewMatrix().getMatrix();
    TransformMatrix tm;
    tm.setTranslation(Vec3f(10, 10, 10));
    tm.update();
    Matrix4f model = tm.getMatrix();
    Matrix4f tProj = projection.transpose();
    tProj.m22 *= -1;
    Matrix4f tView = view.transpose();
    Matrix4f tModel = model.transpose();

    Vec3f mvpcpu = tProj * tView * model * pos;
    std::cout<<mvpcpu<<std::endl;
    Vec3f mvpgpu = tProj * tView * tModel * pos;
    std::cout<<mvpgpu<<std::endl;

i don’t know how to change my matrices to have the same result when I transform vertices with the CPU and with the GPU.

Hi! I think there is a bug with the driver, when I apply mvp transformations like this on the CPU :

VkSettup settup;
    Device device(settup);
    RenderWindow window(sf::VideoMode(800, 600), "test",device);
    Vec3f pos(100, 50, 100);
    Matrix4f proj = window.getView().getProjMatrix().getMatrix();
    Matrix4f view = window.getView().getViewMatrix().getMatrix();
    proj.m22 *= -1;
    TransformMatrix tm;
    tm.setTranslation(Vec3f(100, 50, 50));
    tm.setOrigin(Vec3f(50, 25, 0));
    Matrix4f model = tm.getMatrix(); 
    Vec3f mvpcpu = proj * view * model * pos;
    std::cout<<mvpcpu<<std::endl;

The z coordonate is not null so it’s correct.

But when I transform with the model matrix in the CPU like this :

math::Matrix4f m = tm.getMatrix();
                    /*#ifdef VULKAN
                    m = m.toLeftHanded();
                    math::Vec3f t = m * (math::Vec3f(va[i].position.x, va[i].position.z, va[i].position.y));
                    Vertex v (sf::Vector3f(t.x, t.z, t.y), va[i].color, va[i].texCoords);
                    #else*/
                    math::Vec3f t = m * (math::Vec3f(va[i].position.x, va[i].position.y, va[i].position.z));
                    Vertex v (sf::Vector3f(t.x, t.y, t.z), va[i].color, va[i].texCoords);

And then I transform them with the GPU (with the identity matrix for the model matrix because I already done this transform with the CPU, and I inverse the multiplication order because with the CPU it’s row-major but with the GPU it’s column major) :

R"(#version 460
                                                            #define M_PI 3.1415926535897932384626433832795
                                                            #define FPI M_PI/4
                                                            layout (location = 0) in vec3 position;
                                                            layout (location = 1) in vec4 color;
                                                            layout (location = 2) in vec2 texCoords;
                                                            //layout (location = 3) in vec3 normals;
                                                            layout (push_constant) uniform PushConsts {
                                                                mat4 projectionMatrix;
                                                                mat4 viewMatrix;
                                                                vec4 resolution;
                                                                float time;
                                                            } pushConsts;
                                                            struct ModelData {
                                                                mat4 modelMatrix;
                                                            };
                                                            struct MaterialData {
                                                                uint textureIndex;
                                                                uint materialType;
                                                            };
                                                            layout(set = 0, binding = 4) buffer modelData {
                                                                ModelData modelDatas[];
                                                            };
                                                            layout(set = 0, binding = 5) buffer materialData {
                                                                MaterialData materialDatas[];
                                                            };
                                                            layout(location = 0) out vec4 frontColor;
                                                            layout(location = 1) out vec2 fTexCoords;
                                                            layout(location = 2) out uint texIndex;
                                                            void main() {
                                                                gl_PointSize = 2.0f;
                                                                MaterialData materialData = materialDatas[gl_DrawID];
                                                                ModelData modelData = modelDatas[gl_InstanceIndex];
                                                                float xOff = 0;
                                                                float yOff = 0;
                                                                if (materialData.materialType == 1) {
                                                                    yOff = 0.05*sin(position.x*12+pushConsts.time*FPI)*pushConsts.resolution.y;
                                                                    xOff = 0.025*cos(position.x*12+pushConsts.time*FPI)*pushConsts.resolution.x;
                                                                }
                                                                uint textureIndex =  materialData.textureIndex;
                                                                gl_Position = vec4((position.x - xOff), (position.y + yOff), position.z, 1.f) * modelData.modelMatrix * pushConsts.viewMatrix * pushConsts.projectionMatrix;
                                                                fTexCoords = texCoords;
                                                                frontColor = color;
                                                                texIndex = textureIndex;
                                                            }
                                                            )";

The depth in my depthtexture is always null…

Hi!
Ah *** I didn’t changed the fromat of my input attrib description from 2D vertices position to 3D…

attributeDescriptions[0].format = VK_FORMAT_R32G32B32_SFLOAT;

Now it’s ok