2016-07-09 75 views
4

可以說我有多個要使用不同材質渲染的網格。我知道我可以在這個例子中使用push constants,但這個問題更多的是理解vkDescriptorset是如何工作的。更新渲染通道內的VkDescriptorSet

struct Material { 
    vec4 color; 
    vkDescriptorset descriptorSet; 
    VkDescriptorBufferInfo descriptorBufferInfo; 
}; 

的數據緩衝區被創建後我只能打電話vkUpdateDescriptorSets_descriptorBufferInfo。一切正常。

我測試了另一個解決方案。每種材料沒有一個vkDescriptorset,我只有一個適用於所有材料。在rendepass內部,我爲VkDescriptorBufferInfo中的每一種材料撥打vkUpdateDescriptorSets

vkDescriptorset globalDescriptorSet; 
struct Material { 
    vec4 color; 
    VkDescriptorBufferInfo descriptorBufferInfo; 
}; 

beginCommandBuffer 
beginRenderPass 
for (auto &mesh : meshes) { 
    ... 
    writeDescriptorSets.dstSet = globalDescriptorSet; 
    writeDescriptorSets.pBufferInfo = &mesh.material.descriptorBufferInfo; 
    .... 
    vkUpdateDescriptorSets(device, 1, &writeDescriptorSets, 0, nullptr); 
    renderMesh(mesh); 
} 
endRenderPass 
endCommandBuffer 

但是,當我這樣做,它不起作用。驗證層說你必須在調用第二個網格渲染命令之前調用beginCommandBuffer,然後調用第二個網格的命令vkCmdBindDescriptorSets,vkCmdBindPipeline等。

那麼這裏有什麼問題,我不能在多個VkDescriptorBufferInfo之間共享一個vkDescriptorset,或者我不能在renderPass中更新它嗎?

回答

2

從福爾康規格:

通過調用勢必vkCmdBindDescriptorSets的描述符中設置內容可以在命令的主機執行期間被消耗掉,或者在所得的着色器執行繪製,或之間的任何時間。因此,的內容不得在記錄命令和命令在隊列上執行完成之間發生變化(被更新命令覆蓋或釋放)。

(強調)

據推測,您的通話renderMesh結合的描述符中設置命令緩衝區。從那時起,您不能以任何方式修改該描述符集,直到該命令緩衝區中的命令完成(或CB被銷燬)。

這就是存在動態統一/存儲緩衝區的原因。它們允許您將統一/存儲緩衝區的基址偏移量更改爲而不將視爲實際描述符集的修改。因此,您可以使用不同緩衝區偏移量在多個位置設置相同的描述符。

+0

一如既往的絕佳答案,謝謝 – hidayat