Warm tip: This article is reproduced from stackoverflow.com, please click
3d graphics vulkan

Vulkan: Vertex Buffer doesn't get sent to vertex shader

发布于 2020-05-03 08:29:09

I am learning Vulkan and started having a problem where no vertices would get displayed. After analyzing my program with RenderDoc (https://renderdoc.org/builds), I realized that the buffer containing the vertex and index information contained the rights values. enter image description here

At the end of the same buffer, the indices data: enter image description here

The problem is that when I check the data that is transmitted to the vertex shader, it is empty: enter image description here

Here is the command buffer section where it is supposed to send the data to the shader:

VkDeviceSize indicesOffset = sizeof(Vertex) * this->nbVertices;
VkDeviceSize offsets[] = {0};

vkCmdBindVertexBuffers(commandBuffers[i], 0, 1, &this->vertexBuffer, offsets);
vkCmdBindIndexBuffer(commandBuffers[i], this->vertexBuffer, indicesOffset, VK_INDEX_TYPE_UINT32);

for(size_t j = 0 ; j < this->models.size() ; j++){
    Model *model = this->models[j];
    uint32_t modelDynamicOffset = j * static_cast<uint32_t>(this->uniformDynamicAlignment);

    VkDescriptorSet* modelDescriptorSet =  model->getDescriptorSet(i);
    vkCmdBindDescriptorSets(this->commandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, modelDescriptorSet, 1, &modelDynamicOffset);

    vkCmdDrawIndexed(commandBuffers[i], this->nbIndices, 1, 0, indicesOffset, 0);
}

Also, here is how I create the vertex buffer:

void Application::createVertexBuffers() {
for(Model *model : this->models){
    for(Vertex vertex : model->getVertices()){
        vertices.push_back(vertex);
    }
    for(uint32_t index : model->getIndices()){
        indices.push_back(index);
    }
}

VkDeviceSize vertexBufferSize = sizeof(vertices[0]) * vertices.size();
VkDeviceSize indexBufferSize = sizeof(uint32_t) * indices.size();

this->nbVertices = vertices.size();
this->nbIndices = indices.size();

VkBuffer stagingBuffer;
VkDeviceMemory stagingBufferMemory;


//To CPU
this->createBuffer(vertexBufferSize + indexBufferSize,
                          VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
                          VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
                          stagingBuffer,
                          stagingBufferMemory);
void *data;
vkMapMemory(device, stagingBufferMemory, 0, vertexBufferSize, 0, &data);
memcpy(data, vertices.data(), (size_t)vertexBufferSize);
vkUnmapMemory(device, stagingBufferMemory);

//Add the index data after vertex data
vkMapMemory(device, stagingBufferMemory, vertexBufferSize, indexBufferSize, 0, &data);
memcpy(data, indices.data(), (size_t)indexBufferSize);
vkUnmapMemory(device, stagingBufferMemory);

//To GPU
this->createBuffer(vertexBufferSize + indexBufferSize,
                          VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
                          VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
                          this->vertexBuffer,
                          this->vertexBufferMemory);

this->copyBuffer(stagingBuffer, this->vertexBuffer, vertexBufferSize + indexBufferSize);

vkDestroyBuffer(device, stagingBuffer, nullptr);
vkFreeMemory(device, stagingBufferMemory, nullptr);
}

If you need more information to help me solve my problem, please tell me. Thank you.

Questioner
Clément Bisaillon
Viewed
26
ratchet freak 2020-02-14 23:33

The indices that renderdoc reports for the render are a bit high.

You pass indicesOffset as vertexOffset in your draw command. Which is:

vertexOffset is the value added to the vertex index before indexing into the vertex buffer.

So replace that with 0 and you should get your proper vertices again.