繁体   English   中英

Vulkan vkCmdDrawIndexed仅使用VertexBuffer中的第一个值

[英]Vulkan vkCmdDrawIndexed used only first Value from VertexBuffer

我正在尝试在Vulkan中实现实例化网格渲染。

我的问题是Vulkan仅使用绑定的VertexBuffer中的第一个顶点,并为所有索引复制值。 输出RenderDoc:

RenderDoc输出重复的顶点输入

这些应该是正确的值{{ <inPosition> },{ <inColor> },{ <inTexCoord> }}:

const vkf::Vertex vertices[] = {
    { { -0.2f, -0.5f, 0.0f },{ 1.0f, 0.0f, 0.0f },{ 1.0f, 0.0f } },
    { { 0.5f, -0.5f, 0.0f },{ 0.0f, 1.0f, 0.0f },{ 0.0f, 0.0f } },
    { { 0.5f, 0.5f, 0.0f },{ 0.0f, 0.0f, 1.0f },{ 0.0f, 1.0f } },
    { { -0.5f, 0.5f, 0.0f },{ 1.0f, 1.0f, 1.0f },{ 1.0f, 1.0f } }
};

我已经多次检查了VertexBuffer,它包含正确的值。

这是我的CommandBuffer创建的片段:

        vkCmdBindPipeline(m_commandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.agents);

        VkBuffer vertexBuffers[] = { models.agent.verticesBuffer };
        VkBuffer instanceBuffers[] = { m_instanceBuffer.buffer };

        VkDeviceSize offsets[] = { 0 };
        vkCmdBindVertexBuffers(m_commandBuffers[i], 0, 1, vertexBuffers, offsets);
        vkCmdBindVertexBuffers(m_commandBuffers[i], 1, 1, instanceBuffers, offsets);

        vkCmdBindIndexBuffer(m_commandBuffers[i], models.agent.indexBuffer, 0, VK_INDEX_TYPE_UINT16);

        vkCmdBindDescriptorSets(m_commandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayouts.pipelineLayoutAgent, 0, 1, &descriptorSets.agent, 0, nullptr);
        vkCmdDrawIndexed(m_commandBuffers[i], static_cast<uint32_t> (models.agent.indexCount), 5, 0, 0, 0); 

我的第一个假设是我的约束性描述是错误的。 但是我看不到错误:

bindingDescription = {};
bindingDescription.binding = 0;
bindingDescription.stride = sizeof(Vertex);
bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;

为什么只使用缓冲区中的第一个值?

编辑:

实例数据:

struct InstanceData
{
    glm::vec3 pos;
    glm::vec3 rot;
    float scale;


    static VkVertexInputBindingDescription getBindingDescription()
    {
        VkVertexInputBindingDescription bindingDescription = {};
        bindingDescription.binding = INSTANCING_BIND_ID;
        bindingDescription.stride = sizeof(InstanceData);
        bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_INSTANCE;

        return bindingDescription;
    }

};

整个VkPipelineVertexInputStateCreateInfo:

std::vector<VkVertexInputBindingDescription> bindingDesciption = {};
std::vector<VkVertexInputAttributeDescription> attributeDescriptions = {};

bindingDesciption = { 
    models.agent.bindingDescription,    
    InstanceData::getBindingDescription() 
};
attributeDescriptions =
{
    vertexInputAttributeDescription(VERTEX_BIND_ID, 0, VK_FORMAT_R32G32B32_SFLOAT, offsetof(vkf::Vertex, pos)),
    vertexInputAttributeDescription(VERTEX_BIND_ID, 1, VK_FORMAT_R32G32B32_SFLOAT, offsetof(vkf::Vertex, color)),
    vertexInputAttributeDescription(INSTANCING_BIND_ID, 2, VK_FORMAT_R32G32B32_SFLOAT, offsetof(InstanceData, pos)),
    vertexInputAttributeDescription(VERTEX_BIND_ID, 3, VK_FORMAT_R32G32_SFLOAT, offsetof(vkf::Vertex, texCoord))
};

VkPipelineVertexInputStateCreateInfo vertexInputInfo = {};

vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
vertexInputInfo.vertexBindingDescriptionCount = static_cast<uint32_t>(bindingDesciption.size());
vertexInputInfo.vertexAttributeDescriptionCount = static_cast<uint32_t>(attributeDescriptions.size());
vertexInputInfo.pVertexBindingDescriptions = bindingDesciption.data();
vertexInputInfo.pVertexAttributeDescriptions = attributeDescriptions.data();

编辑2

#define VERTEX_BIND_ID 0
#define INSTANCING_BIND_ID 1

编辑3:我正在使用VulkanMemoryAllocator。 创建登台缓冲区

size_t vertexBufferSize = sizeof(vkf::Vertex) *_countof(vertices);

createStagingBuffer(vertexBufferSize );

VkBuffer createStagingBuffer(VkDeviceSize size)
{
    VkBuffer buffer;
    VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
    bufferInfo.size = size;
    bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
    bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;

    VmaAllocationCreateInfo allocCreateInfo = {};
    allocCreateInfo.usage = VMA_MEMORY_USAGE_CPU_TO_GPU;
    allocCreateInfo.flags = VMA_ALLOCATION_CREATE_PERSISTENT_MAP_BIT;

    VmaAllocationInfo allocInfo = {};
    if (vmaCreateBuffer(m_allocator, &bufferInfo, &allocCreateInfo, &buffer, &m_allocation, &allocInfo) != VK_SUCCESS)
    {
        throw std::runtime_error("failed to create Buffer!");
    }
    return buffer;
}

复制顶点:

memcpy(mappedStaging, vertices, vertexBufferSize);

创建缓冲区:

createBuffer(vertexBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VMA_MEMORY_USAGE_GPU_ONLY);

VkBuffer createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VmaMemoryUsage vmaUsage)
{
    VkBuffer buffer;   

    VkBufferCreateInfo bufferInfo = { VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
    bufferInfo.size = size;
    bufferInfo.usage = usage;
    bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;

    VmaAllocationCreateInfo allocCreateInfo = {};
    allocCreateInfo.usage = vmaUsage;
    allocCreateInfo.flags = 0;

    VmaAllocationInfo allocInfo;
    if (vmaCreateBuffer(m_allocator, &bufferInfo, &allocCreateInfo, &buffer, &m_allocation, &allocInfo) != VK_SUCCESS)
    {
        throw std::runtime_error("failed to create Buffer!");
    }    
    return buffer;
}

这是我如何过渡暂存器的缓冲区:

copyBuffer(stagingVertexBuffer, verticesBuffer, vertexBufferSize);

void Base::copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size)
{
    VkCommandBuffer commandBuffer = beginSingleTimeCommands();

    VkBufferCopy copyRegion = {};
    copyRegion.dstOffset = 0;
    copyRegion.srcOffset = 0;
    copyRegion.size = size;
    vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, 1, &copyRegion);

    endSingleTimeCommands(commandBuffer);
}

我检查了几次数据是否在临时缓冲区中,并且在修改createBuffer Prozess之后也在verticesBuffer中进行了检查。 它们正确存储在此处。

我发现了错误。 错误在这里:

bindingDesciption = { 
    models.agent.bindingDescription,    
    InstanceData::getBindingDescription() 
};

到绑定发生时,models.agent.bindingDescription尚未初始化。 结果,VkVertexInputBindingDescription错误。 models.agent.bindingDescription填充了VkVertexInputBindingDescription的标准值:

binding = 0
stroke = 0
inputRate = VK_VERTEX_INPUT_RATE_VERTEX

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM