diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2020-10-09 20:12:34 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2020-10-11 10:58:50 +0200 |
commit | 8c9dfd7914472585f4fd0519f6f2a278225c3658 (patch) | |
tree | b2f19b304a9e6854e8d7f34ae2a4bc407d3aa0a4 | |
parent | b540c783557808f778f8afd332b33aa81f7e5ec6 (diff) |
rhi: gl: vk: Pre-calculate the flags for dyn.offset
...instead of doing a loop in setShaderResources() just for this.
Change-Id: Iac8d4517783967c6b8bca4926cceca918f7dcdec
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
-rw-r--r-- | src/gui/rhi/qrhigles2.cpp | 64 | ||||
-rw-r--r-- | src/gui/rhi/qrhigles2_p_p.h | 1 | ||||
-rw-r--r-- | src/gui/rhi/qrhivulkan.cpp | 35 | ||||
-rw-r--r-- | src/gui/rhi/qrhivulkan_p_p.h | 2 |
4 files changed, 54 insertions, 48 deletions
diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index 63f419da94..5411d779e1 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -1091,31 +1091,27 @@ void QRhiGles2::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind srb = compPsD->m_shaderResourceBindings; } - QRhiPassResourceTracker &passResTracker(cbD->passResTrackers[cbD->currentPassResTrackerIndex]); QGles2ShaderResourceBindings *srbD = QRHI_RES(QGles2ShaderResourceBindings, srb); - bool hasDynamicOffsetInSrb = false; - for (int i = 0, ie = srbD->m_bindings.count(); i != ie; ++i) { - const QRhiShaderResourceBinding::Data *b = srbD->m_bindings.at(i).data(); - switch (b->type) { - case QRhiShaderResourceBinding::UniformBuffer: - // no BufUniformRead / AccessUniform because no real uniform buffers are used - if (b->u.ubuf.hasDynamicOffset) - hasDynamicOffsetInSrb = true; - break; - case QRhiShaderResourceBinding::SampledTexture: - if (cbD->passNeedsResourceTracking) { + if (cbD->passNeedsResourceTracking) { + QRhiPassResourceTracker &passResTracker(cbD->passResTrackers[cbD->currentPassResTrackerIndex]); + for (int i = 0, ie = srbD->m_bindings.count(); i != ie; ++i) { + const QRhiShaderResourceBinding::Data *b = srbD->m_bindings.at(i).data(); + switch (b->type) { + case QRhiShaderResourceBinding::UniformBuffer: + // no BufUniformRead / AccessUniform because no real uniform buffers are used + break; + case QRhiShaderResourceBinding::SampledTexture: for (int elem = 0; elem < b->u.stex.count; ++elem) { trackedRegisterTexture(&passResTracker, QRHI_RES(QGles2Texture, b->u.stex.texSamplers[elem].tex), QRhiPassResourceTracker::TexSample, QRhiPassResourceTracker::toPassTrackerTextureStage(b->stage)); } - } - break; - case QRhiShaderResourceBinding::ImageLoad: - case QRhiShaderResourceBinding::ImageStore: - case QRhiShaderResourceBinding::ImageLoadStore: - if (cbD->passNeedsResourceTracking) { + break; + case QRhiShaderResourceBinding::ImageLoad: + case QRhiShaderResourceBinding::ImageStore: + case QRhiShaderResourceBinding::ImageLoadStore: + { QGles2Texture *texD = QRHI_RES(QGles2Texture, b->u.simage.tex); QRhiPassResourceTracker::TextureAccess access; if (b->type == QRhiShaderResourceBinding::ImageLoad) @@ -1127,11 +1123,11 @@ void QRhiGles2::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind trackedRegisterTexture(&passResTracker, texD, access, QRhiPassResourceTracker::toPassTrackerTextureStage(b->stage)); } - break; - case QRhiShaderResourceBinding::BufferLoad: - case QRhiShaderResourceBinding::BufferStore: - case QRhiShaderResourceBinding::BufferLoadStore: - if (cbD->passNeedsResourceTracking) { + break; + case QRhiShaderResourceBinding::BufferLoad: + case QRhiShaderResourceBinding::BufferStore: + case QRhiShaderResourceBinding::BufferLoadStore: + { QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, b->u.sbuf.buf); QRhiPassResourceTracker::BufferAccess access; if (b->type == QRhiShaderResourceBinding::BufferLoad) @@ -1143,16 +1139,17 @@ void QRhiGles2::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind trackedRegisterBuffer(&passResTracker, bufD, access, QRhiPassResourceTracker::toPassTrackerBufferStage(b->stage)); } - break; - default: - break; + break; + default: + break; + } } } const bool srbChanged = gfxPsD ? (cbD->currentGraphicsSrb != srb) : (cbD->currentComputeSrb != srb); const bool srbRebuilt = cbD->currentSrbGeneration != srbD->generation; - if (srbChanged || srbRebuilt || hasDynamicOffsetInSrb) { + if (srbChanged || srbRebuilt || srbD->hasDynamicOffset) { if (gfxPsD) { cbD->currentGraphicsSrb = srb; cbD->currentComputeSrb = nullptr; @@ -1168,7 +1165,7 @@ void QRhiGles2::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind cmd.args.bindShaderResources.maybeComputePs = compPsD; cmd.args.bindShaderResources.srb = srb; cmd.args.bindShaderResources.dynamicOffsetCount = 0; - if (hasDynamicOffsetInSrb) { + if (srbD->hasDynamicOffset) { if (dynamicOffsetCount < QGles2CommandBuffer::Command::MAX_DYNAMIC_OFFSET_COUNT) { cmd.args.bindShaderResources.dynamicOffsetCount = dynamicOffsetCount; uint *p = cmd.args.bindShaderResources.dynamicOffsetPairs; @@ -4448,6 +4445,17 @@ bool QGles2ShaderResourceBindings::create() if (!rhiD->sanityCheckShaderResourceBindings(this)) return false; + hasDynamicOffset = false; + for (int i = 0, ie = m_bindings.count(); i != ie; ++i) { + const QRhiShaderResourceBinding::Data *b = m_bindings.at(i).data(); + if (b->type == QRhiShaderResourceBinding::UniformBuffer) { + if (b->u.ubuf.hasDynamicOffset) { + hasDynamicOffset = true; + break; + } + } + } + rhiD->updateLayoutDesc(this); generation += 1; diff --git a/src/gui/rhi/qrhigles2_p_p.h b/src/gui/rhi/qrhigles2_p_p.h index d037bbc4f6..b7577ce51b 100644 --- a/src/gui/rhi/qrhigles2_p_p.h +++ b/src/gui/rhi/qrhigles2_p_p.h @@ -241,6 +241,7 @@ struct QGles2ShaderResourceBindings : public QRhiShaderResourceBindings void destroy() override; bool create() override; + bool hasDynamicOffset = false; uint generation = 0; friend class QRhiGles2; }; diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp index d0e98fb751..ccb2c002b3 100644 --- a/src/gui/rhi/qrhivulkan.cpp +++ b/src/gui/rhi/qrhivulkan.cpp @@ -4283,24 +4283,7 @@ void QRhiVulkan::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBin } QVkShaderResourceBindings *srbD = QRHI_RES(QVkShaderResourceBindings, srb); - bool hasSlottedResourceInSrb = false; - bool hasDynamicOffsetInSrb = false; - - for (const QRhiShaderResourceBinding &binding : qAsConst(srbD->sortedBindings)) { - const QRhiShaderResourceBinding::Data *b = binding.data(); - switch (b->type) { - case QRhiShaderResourceBinding::UniformBuffer: - if (QRHI_RES(QVkBuffer, b->u.ubuf.buf)->m_type == QRhiBuffer::Dynamic) - hasSlottedResourceInSrb = true; - if (b->u.ubuf.hasDynamicOffset) - hasDynamicOffsetInSrb = true; - break; - default: - break; - } - } - - const int descSetIdx = hasSlottedResourceInSrb ? currentFrameSlot : 0; + const int descSetIdx = srbD->hasSlottedResource ? currentFrameSlot : 0; bool rewriteDescSet = false; // Do host writes and mark referenced shader resources as in-use. @@ -4429,13 +4412,13 @@ void QRhiVulkan::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBin // make sure the descriptors for the correct slot will get bound. // also, dynamic offsets always need a bind. - const bool forceRebind = (hasSlottedResourceInSrb && cbD->currentDescSetSlot != descSetIdx) || hasDynamicOffsetInSrb; + const bool forceRebind = (srbD->hasSlottedResource && cbD->currentDescSetSlot != descSetIdx) || srbD->hasDynamicOffset; const bool srbChanged = gfxPsD ? (cbD->currentGraphicsSrb != srb) : (cbD->currentComputeSrb != srb); if (forceRebind || rewriteDescSet || srbChanged || cbD->currentSrbGeneration != srbD->generation) { QVarLengthArray<uint32_t, 4> dynOfs; - if (hasDynamicOffsetInSrb) { + if (srbD->hasDynamicOffset) { // Filling out dynOfs based on the sorted bindings is important // because dynOfs has to be ordered based on the binding numbers, // and neither srb nor dynamicOffsets has any such ordering @@ -6249,6 +6232,18 @@ bool QVkShaderResourceBindings::create() return a.data()->binding < b.data()->binding; }); + hasSlottedResource = false; + hasDynamicOffset = false; + for (const QRhiShaderResourceBinding &binding : qAsConst(sortedBindings)) { + const QRhiShaderResourceBinding::Data *b = binding.data(); + if (b->type == QRhiShaderResourceBinding::UniformBuffer && b->u.ubuf.buf) { + if (QRHI_RES(QVkBuffer, b->u.ubuf.buf)->type() == QRhiBuffer::Dynamic) + hasSlottedResource = true; + if (b->u.ubuf.hasDynamicOffset) + hasDynamicOffset = true; + } + } + QVarLengthArray<VkDescriptorSetLayoutBinding, 4> vkbindings; for (const QRhiShaderResourceBinding &binding : qAsConst(sortedBindings)) { const QRhiShaderResourceBinding::Data *b = binding.data(); diff --git a/src/gui/rhi/qrhivulkan_p_p.h b/src/gui/rhi/qrhivulkan_p_p.h index 5a20e6a757..c16a990894 100644 --- a/src/gui/rhi/qrhivulkan_p_p.h +++ b/src/gui/rhi/qrhivulkan_p_p.h @@ -249,6 +249,8 @@ struct QVkShaderResourceBindings : public QRhiShaderResourceBindings bool create() override; QVarLengthArray<QRhiShaderResourceBinding, 8> sortedBindings; + bool hasSlottedResource = false; + bool hasDynamicOffset = false; int poolIndex = -1; VkDescriptorSetLayout layout = VK_NULL_HANDLE; VkDescriptorSet descSets[QVK_FRAMES_IN_FLIGHT]; // multiple sets to support dynamic buffers |