Commit 211520f0 authored by Laszlo Agocs's avatar Laszlo Agocs
Browse files

vk: minimize BindDescriptorSets

Calling setGraphicsPipeline with the same srb multiple times in a row
in a frame should not lead to queuing BindDescriptorSets every time,
it should rather be optimized out just like the BindPipeline is.
parent 28730ead
...@@ -2847,8 +2847,9 @@ void QRhiVulkan::setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline ...@@ -2847,8 +2847,9 @@ void QRhiVulkan::setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline
if (!srb) if (!srb)
srb = psD->m_shaderResourceBindings; srb = psD->m_shaderResourceBindings;
// do host writes and mark referenced shader resources as in-use
QVkShaderResourceBindings *srbD = QRHI_RES(QVkShaderResourceBindings, srb); QVkShaderResourceBindings *srbD = QRHI_RES(QVkShaderResourceBindings, srb);
bool hasDynamicBufferInSrb = false; bool hasSlottedResourceInSrb = false;
for (const QRhiShaderResourceBinding &b : qAsConst(srbD->m_bindings)) { for (const QRhiShaderResourceBinding &b : qAsConst(srbD->m_bindings)) {
switch (b.type) { switch (b.type) {
case QRhiShaderResourceBinding::UniformBuffer: case QRhiShaderResourceBinding::UniformBuffer:
...@@ -2857,7 +2858,7 @@ void QRhiVulkan::setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline ...@@ -2857,7 +2858,7 @@ void QRhiVulkan::setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline
Q_ASSERT(bufD->m_usage.testFlag(QRhiBuffer::UniformBuffer)); Q_ASSERT(bufD->m_usage.testFlag(QRhiBuffer::UniformBuffer));
bufD->lastActiveFrameSlot = currentFrameSlot; bufD->lastActiveFrameSlot = currentFrameSlot;
if (bufD->m_type == QRhiBuffer::Dynamic) { if (bufD->m_type == QRhiBuffer::Dynamic) {
hasDynamicBufferInSrb = true; hasSlottedResourceInSrb = true;
executeBufferHostWritesForCurrentFrame(bufD); executeBufferHostWritesForCurrentFrame(bufD);
} }
} }
...@@ -2873,7 +2874,7 @@ void QRhiVulkan::setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline ...@@ -2873,7 +2874,7 @@ void QRhiVulkan::setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline
} }
// ensure the descriptor set we are going to bind refers to up-to-date Vk objects // ensure the descriptor set we are going to bind refers to up-to-date Vk objects
const int descSetIdx = hasDynamicBufferInSrb ? currentFrameSlot : 0; const int descSetIdx = hasSlottedResourceInSrb ? currentFrameSlot : 0;
bool srbUpdate = false; bool srbUpdate = false;
for (int i = 0, ie = srbD->m_bindings.count(); i != ie; ++i) { for (int i = 0, ie = srbD->m_bindings.count(); i != ie; ++i) {
const QRhiShaderResourceBinding &b(srbD->m_bindings[i]); const QRhiShaderResourceBinding &b(srbD->m_bindings[i]);
...@@ -2910,11 +2911,16 @@ void QRhiVulkan::setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline ...@@ -2910,11 +2911,16 @@ void QRhiVulkan::setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline
} }
psD->lastActiveFrameSlot = currentFrameSlot; psD->lastActiveFrameSlot = currentFrameSlot;
if (hasDynamicBufferInSrb || srbUpdate || cbD->currentSrb != srb || cbD->currentSrbGeneration != srbD->generation) { // make sure the descriptors for the correct slot will get bound
if (hasSlottedResourceInSrb && cbD->currentDescSetSlot != descSetIdx)
srbUpdate = true;
if (srbUpdate || cbD->currentSrb != srb || cbD->currentSrbGeneration != srbD->generation) {
df->vkCmdBindDescriptorSets(cbD->cb, VK_PIPELINE_BIND_POINT_GRAPHICS, psD->layout, 0, 1, df->vkCmdBindDescriptorSets(cbD->cb, VK_PIPELINE_BIND_POINT_GRAPHICS, psD->layout, 0, 1,
&srbD->descSets[descSetIdx], 0, nullptr); &srbD->descSets[descSetIdx], 0, nullptr);
cbD->currentSrb = srb; cbD->currentSrb = srb;
cbD->currentSrbGeneration = srbD->generation; cbD->currentSrbGeneration = srbD->generation;
cbD->currentDescSetSlot = descSetIdx;
} }
srbD->lastActiveFrameSlot = currentFrameSlot; srbD->lastActiveFrameSlot = currentFrameSlot;
} }
......
...@@ -253,12 +253,14 @@ struct QVkCommandBuffer : public QRhiCommandBuffer ...@@ -253,12 +253,14 @@ struct QVkCommandBuffer : public QRhiCommandBuffer
currentPipelineGeneration = 0; currentPipelineGeneration = 0;
currentSrb = nullptr; currentSrb = nullptr;
currentSrbGeneration = 0; currentSrbGeneration = 0;
currentDescSetSlot = -1;
} }
QRhiRenderTarget *currentTarget; QRhiRenderTarget *currentTarget;
QRhiGraphicsPipeline *currentPipeline; QRhiGraphicsPipeline *currentPipeline;
uint currentPipelineGeneration; uint currentPipelineGeneration;
QRhiShaderResourceBindings *currentSrb; QRhiShaderResourceBindings *currentSrb;
uint currentSrbGeneration; uint currentSrbGeneration;
int currentDescSetSlot;
friend class QRhiVulkan; friend class QRhiVulkan;
}; };
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment