2017-11-07 3 views
0

Vulkanでインスタンス化されたメッシュレンダリングを実装しようとしています。Vulkan vkCmdDrawIndexedは最初に使用されました。VertexBufferの値

私の問題は、VulkanはバインドされたVertexBufferの最初の頂点だけを使用し、すべてのインデックスの値を複製することです。 出力RenderDoc:

RenderDoc output Duplicated Vertex Input

これらが正しい値{{<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を複数回チェックし、それしました正しい値が含まれています。

 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); 

私の最初の仮定は、私のバインディングの記述が間違っているということでした。ここで

を作成する私のCommandBufferから切り取られます。しかし、私はエラーを見ることができません:

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

なぜ最初の値が使われているのですか?

EDIT:

InstanceData:

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(); 

EDIT 2

#define VERTEX_BIND_ID 0 
#define INSTANCING_BIND_ID 1 

編集3: 私はVulkanMemoryAllocatorを使用しています。

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); 
} 

I:これは私がステージングから私のバッファをtransfair方法です

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; 
} 

memcpy(mappedStaging, vertices, vertexBufferSize); 

バッファの作成: は

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; 
} 

コピー頂点バッファをステージングの作成しますデータがステージングバッファにあるかどうか、およびverticesBufferでもcreateBuffer Prozessを変更した後で何度もチェックされます。それらは正しく格納されます。

+0

あなたの全体の 'VkPipelineVertexInputStateCreateInfo'を見せてください。また、バッファデータの設定/転送方法についても説明します。また、頂点シェーダのインターフェイスブロックがうまくいくでしょう。 – krOoze

+0

PS:最新の検証レイヤを有効にしてテストしましたか? – krOoze

+0

VkPipelineVertexInputStateCreateInfo全体を自分の投稿に追加しました。 私はVK_LAYER_LUNARG_standard_validationエクステンションを利用しています。 –

答えて

0

私は間違いを発見しました。 間違いはここにあった:

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

結合が行われた時点で、models.agent.bindingDescriptionは、まだ初期化されていませんでした。その結果、VkVertexInputBindingDescriptionに障害がありました。 models.agent。bindingDescriptionはVkVertexInputBindingDescriptionの標準値で埋められました:

binding = 0 
stroke = 0 
inputRate = VK_VERTEX_INPUT_RATE_VERTEX 
+0

ハァッ。私は0ストライドが合法であることを期待していませんでした... – krOoze

+0

私はそれも考えませんでした。今それは動作します。ご協力いただきありがとうございます。 –

関連する問題