Vulkan renders only one out of two meshes

225 views Asked by At

I have a problem with Vulkan. I want to render two copies of the same cube so I translate them to a different position as I show in the function VulkanRenderer::initUniformBuffer(). But I can only see the first cube. I have no idea what I am doing wrong. I tried to change the offset in vkCmdBindDescriptorSets() but it did not change anything. Maybe something is wrong with my descriptors? Or I missed to set something else.

I have two uniform buffers (one per mesh), one command buffer, one pipeline and one renderpass. Here is my render loop:

bool VulkanRenderer::Run() {
    InitSemaphore(&_semaphoreA);
    if(_window != nullptr) {
        _window->UpdateWindow();

        auto res = VK_SUCCESS;

        InitRenderPass(_imageKHRindex);

        vkCmdBindPipeline(_commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, GetPipeline());

        const VkDeviceSize offsets [1] = { 0 };

        VkMemoryRequirements memoryRequirements;
        vkGetBufferMemoryRequirements(_deviceHandler, _uniformDataBuffer, &memoryRequirements);

        VkMemoryAllocateInfo memoryAllocatorInfo {};
        memoryAllocatorInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;

        memoryAllocatorInfo.allocationSize = memoryRequirements.size;

        uint32_t memoryTypeCount = _memoryProperties.memoryTypeCount;
        for(uint32_t i = 0; i < memoryTypeCount; ++i) {
            if((memoryRequirements.memoryTypeBits & 1) == 1) {
                if((_memoryProperties.memoryTypes [i].propertyFlags &
                   VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) {
                    memoryAllocatorInfo.memoryTypeIndex = i;
                }
            }
            memoryRequirements.memoryTypeBits >>= 1;
        }

        vkCmdBindVertexBuffers(_commandBuffer, 0, 1, &_vertexBuffer, offsets);
        vkCmdSetViewport(_commandBuffer, 0, 1, &_viewport);
        VkRect2D rect2d;
        rect2d.extent.width = _winWidth;
        rect2d.extent.height = _winHeight;
        rect2d.offset.x = 0;
        rect2d.offset.y = 0;
        vkCmdSetScissor(_commandBuffer, 0, 1, &rect2d);

        for(int i = 0; i < 2; i++) {
            const uint32_t offset = i * sizeof(_mvp);

            vkCmdBindDescriptorSets(_commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, GetPipelineLayout(),
                                    0, 1, _descriptorSets.data(), 0, 0);

            vkCmdDraw(_commandBuffer, vertices.size(), 2, 0, 0);
        }

        vkCmdEndRenderPass(_commandBuffer);

        prePresentBarrier.image = GetSwapchainImage() [_imageKHRindex];

        vkCmdPipelineBarrier(_commandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
                             VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 1, &prePresentBarrier);

        const VkCommandBuffer cmdBufs [] = { _commandBuffer };


        VkPipelineStageFlags pipelineStageFlags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
        vkResetFences(_deviceHandler, 1, &_drawFence);

        VkSubmitInfo submitInfo [1] = {};
        submitInfo [0].pNext = NULL;
        submitInfo [0].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
        submitInfo [0].waitSemaphoreCount = 1;
        submitInfo [0].pWaitSemaphores = &_semaphoreA;
        submitInfo [0].pWaitDstStageMask = &pipelineStageFlags;
        submitInfo [0].commandBufferCount = 1;
        submitInfo [0].pCommandBuffers = cmdBufs;
        submitInfo [0].signalSemaphoreCount = 0;
        submitInfo [0].pSignalSemaphores = NULL;

        ErrorCheck(vkEndCommandBuffer(_commandBuffer));
        ErrorCheck(vkQueueSubmit(_queue, 1, submitInfo, _drawFence));

        VkPresentInfoKHR present {};
        present.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
        present.swapchainCount = 1;
        present.pSwapchains = pGetVulcanSwapchainKHR();
        present.pImageIndices = &_imageKHRindex;

        do {
            res = vkWaitForFences(_deviceHandler, 1, &_drawFence, VK_TRUE, UINT64_MAX);
        } while(res == VK_TIMEOUT);

        assert(res == VK_SUCCESS);
        ErrorCheck(vkQueuePresentKHR(_queue, &present));

        ExecuteBeginCommandBuffer();

        return _window->isOpened();
    }

    ExecuteBeginCommandBuffer();
    return true;
}

and the initUniformBuffer() function:

void VulkanRenderer::initUniformBuffer() {

    float fov = glm::radians(45.0f);
    if(_winWidth > _winHeight) {
        fov *= static_cast<float>(_winHeight) / static_cast<float>(_winWidth);
    }

    _projection = glm::perspective(fov, static_cast<float>(_winWidth) / static_cast<float>(_winHeight), 0.1f, 100.0f);

    vulkanCamera.cameraPosition = glm::vec3(5, 3, 10);

    _view = glm::lookAt(vulkanCamera.cameraPosition,//Camera Position,
                        glm::vec3(0, 0, 0), // look at
                        glm::vec3(0, -1, 0) /*head up */);
    _model = glm::mat4(1.0f);

    // Vulkan clip space has inverted Y and half Z.
    _clip = glm::mat4(1.0f, 0.0f, 0.0f, 0.0f,
                      0.0f, -1.0f, 0.0f, 0.0f,
                      0.0f, 0.0f, 0.5f, 0.0f,
                      0.0f, 0.0f, 0.5f, 1.0f);

    _mvp = _clip * _projection * _view * _model;

    _model = glm::translate(_model, glm::vec3(4, 4, 4));

    glm::mat4 mvp2 = _clip * _projection * _view * _model;

    //Create uniform buffer

    VkBufferCreateInfo uniformBufferCreateInfo {};
    uniformBufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
    uniformBufferCreateInfo.usage = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
    uniformBufferCreateInfo.size = sizeof(_mvp) * 2;
    uniformBufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
    uniformBufferCreateInfo.flags = 0;
    ErrorCheck(vkCreateBuffer(_deviceHandler, &uniformBufferCreateInfo, NULL, &_uniformDataBuffer));

    VkMemoryAllocateInfo memoryAllocatorInfo {};
    memoryAllocatorInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;

    VkMemoryRequirements memoryRequirements;
    vkGetBufferMemoryRequirements(_deviceHandler, _uniformDataBuffer, &memoryRequirements);

    memoryAllocatorInfo.allocationSize = memoryRequirements.size;

    uint32_t memoryTypeCount = _memoryProperties.memoryTypeCount;
    for(uint32_t i = 0; i < memoryTypeCount; ++i) {
        if((memoryRequirements.memoryTypeBits & 1) == 1) {
            if((_memoryProperties.memoryTypes [i].propertyFlags &
               VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) == VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) {
                memoryAllocatorInfo.memoryTypeIndex = i;
            }
        }
        memoryRequirements.memoryTypeBits >>= 1;
    }

    ErrorCheck(vkAllocateMemory(_deviceHandler, &memoryAllocatorInfo, nullptr, &_uniformBufferMemory));

    uint8_t *pData;
    ErrorCheck(vkMapMemory(_deviceHandler, _uniformBufferMemory, 0, memoryRequirements.size, 0, (void **) &pData));

    memcpy(pData, &mvp2, sizeof(_mvp));
    memcpy(pData + sizeof(_mvp), &_mvp, sizeof(_mvp));

    vkUnmapMemory(_deviceHandler, _uniformBufferMemory);
    ErrorCheck(vkBindBufferMemory(_deviceHandler, _uniformDataBuffer, _uniformBufferMemory, 0));

    _uniformDescriptorInfo.buffer = _uniformDataBuffer;
    _uniformDescriptorInfo.offset = 0;
    _uniformDescriptorInfo.range = VK_WHOLE_SIZE;
}

initDescritorSet() function:

void VulkanRenderer::initDescriptorSet() {
    VkDescriptorSetAllocateInfo descriptorSetAllocateInfo [1];
    descriptorSetAllocateInfo [0].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
    descriptorSetAllocateInfo [0].pNext = NULL;
    descriptorSetAllocateInfo [0].descriptorPool = _descriptorPool;
    descriptorSetAllocateInfo [0].descriptorSetCount = 1;
    descriptorSetAllocateInfo [0].pSetLayouts = _descriptorSetLayout.data();

    _descriptorSets.resize(1);

    ErrorCheck(vkAllocateDescriptorSets(_deviceHandler, descriptorSetAllocateInfo, _descriptorSets.data()));

    VkWriteDescriptorSet writes [2];

    writes [0] = {};
    writes [0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
    writes [0].pNext = NULL;
    writes [0].dstSet = _descriptorSets [0];
    writes [0].descriptorCount = 1;
    writes [0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
    writes [0].pBufferInfo = &_uniformDescriptorInfo;
    writes [0].dstArrayElement = 0;
    writes [0].dstBinding = 0;

    vkUpdateDescriptorSets(_deviceHandler,  1, writes, 0, nullptr);

}
0

There are 0 answers