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>
This commit is contained in:
parent
b540c78355
commit
8c9dfd7914
@ -1091,31 +1091,27 @@ void QRhiGles2::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
|
|||||||
srb = compPsD->m_shaderResourceBindings;
|
srb = compPsD->m_shaderResourceBindings;
|
||||||
}
|
}
|
||||||
|
|
||||||
QRhiPassResourceTracker &passResTracker(cbD->passResTrackers[cbD->currentPassResTrackerIndex]);
|
|
||||||
QGles2ShaderResourceBindings *srbD = QRHI_RES(QGles2ShaderResourceBindings, srb);
|
QGles2ShaderResourceBindings *srbD = QRHI_RES(QGles2ShaderResourceBindings, srb);
|
||||||
bool hasDynamicOffsetInSrb = false;
|
if (cbD->passNeedsResourceTracking) {
|
||||||
for (int i = 0, ie = srbD->m_bindings.count(); i != ie; ++i) {
|
QRhiPassResourceTracker &passResTracker(cbD->passResTrackers[cbD->currentPassResTrackerIndex]);
|
||||||
const QRhiShaderResourceBinding::Data *b = srbD->m_bindings.at(i).data();
|
for (int i = 0, ie = srbD->m_bindings.count(); i != ie; ++i) {
|
||||||
switch (b->type) {
|
const QRhiShaderResourceBinding::Data *b = srbD->m_bindings.at(i).data();
|
||||||
case QRhiShaderResourceBinding::UniformBuffer:
|
switch (b->type) {
|
||||||
// no BufUniformRead / AccessUniform because no real uniform buffers are used
|
case QRhiShaderResourceBinding::UniformBuffer:
|
||||||
if (b->u.ubuf.hasDynamicOffset)
|
// no BufUniformRead / AccessUniform because no real uniform buffers are used
|
||||||
hasDynamicOffsetInSrb = true;
|
break;
|
||||||
break;
|
case QRhiShaderResourceBinding::SampledTexture:
|
||||||
case QRhiShaderResourceBinding::SampledTexture:
|
|
||||||
if (cbD->passNeedsResourceTracking) {
|
|
||||||
for (int elem = 0; elem < b->u.stex.count; ++elem) {
|
for (int elem = 0; elem < b->u.stex.count; ++elem) {
|
||||||
trackedRegisterTexture(&passResTracker,
|
trackedRegisterTexture(&passResTracker,
|
||||||
QRHI_RES(QGles2Texture, b->u.stex.texSamplers[elem].tex),
|
QRHI_RES(QGles2Texture, b->u.stex.texSamplers[elem].tex),
|
||||||
QRhiPassResourceTracker::TexSample,
|
QRhiPassResourceTracker::TexSample,
|
||||||
QRhiPassResourceTracker::toPassTrackerTextureStage(b->stage));
|
QRhiPassResourceTracker::toPassTrackerTextureStage(b->stage));
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
break;
|
case QRhiShaderResourceBinding::ImageLoad:
|
||||||
case QRhiShaderResourceBinding::ImageLoad:
|
case QRhiShaderResourceBinding::ImageStore:
|
||||||
case QRhiShaderResourceBinding::ImageStore:
|
case QRhiShaderResourceBinding::ImageLoadStore:
|
||||||
case QRhiShaderResourceBinding::ImageLoadStore:
|
{
|
||||||
if (cbD->passNeedsResourceTracking) {
|
|
||||||
QGles2Texture *texD = QRHI_RES(QGles2Texture, b->u.simage.tex);
|
QGles2Texture *texD = QRHI_RES(QGles2Texture, b->u.simage.tex);
|
||||||
QRhiPassResourceTracker::TextureAccess access;
|
QRhiPassResourceTracker::TextureAccess access;
|
||||||
if (b->type == QRhiShaderResourceBinding::ImageLoad)
|
if (b->type == QRhiShaderResourceBinding::ImageLoad)
|
||||||
@ -1127,11 +1123,11 @@ void QRhiGles2::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
|
|||||||
trackedRegisterTexture(&passResTracker, texD, access,
|
trackedRegisterTexture(&passResTracker, texD, access,
|
||||||
QRhiPassResourceTracker::toPassTrackerTextureStage(b->stage));
|
QRhiPassResourceTracker::toPassTrackerTextureStage(b->stage));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case QRhiShaderResourceBinding::BufferLoad:
|
case QRhiShaderResourceBinding::BufferLoad:
|
||||||
case QRhiShaderResourceBinding::BufferStore:
|
case QRhiShaderResourceBinding::BufferStore:
|
||||||
case QRhiShaderResourceBinding::BufferLoadStore:
|
case QRhiShaderResourceBinding::BufferLoadStore:
|
||||||
if (cbD->passNeedsResourceTracking) {
|
{
|
||||||
QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, b->u.sbuf.buf);
|
QGles2Buffer *bufD = QRHI_RES(QGles2Buffer, b->u.sbuf.buf);
|
||||||
QRhiPassResourceTracker::BufferAccess access;
|
QRhiPassResourceTracker::BufferAccess access;
|
||||||
if (b->type == QRhiShaderResourceBinding::BufferLoad)
|
if (b->type == QRhiShaderResourceBinding::BufferLoad)
|
||||||
@ -1143,16 +1139,17 @@ void QRhiGles2::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
|
|||||||
trackedRegisterBuffer(&passResTracker, bufD, access,
|
trackedRegisterBuffer(&passResTracker, bufD, access,
|
||||||
QRhiPassResourceTracker::toPassTrackerBufferStage(b->stage));
|
QRhiPassResourceTracker::toPassTrackerBufferStage(b->stage));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool srbChanged = gfxPsD ? (cbD->currentGraphicsSrb != srb) : (cbD->currentComputeSrb != srb);
|
const bool srbChanged = gfxPsD ? (cbD->currentGraphicsSrb != srb) : (cbD->currentComputeSrb != srb);
|
||||||
const bool srbRebuilt = cbD->currentSrbGeneration != srbD->generation;
|
const bool srbRebuilt = cbD->currentSrbGeneration != srbD->generation;
|
||||||
|
|
||||||
if (srbChanged || srbRebuilt || hasDynamicOffsetInSrb) {
|
if (srbChanged || srbRebuilt || srbD->hasDynamicOffset) {
|
||||||
if (gfxPsD) {
|
if (gfxPsD) {
|
||||||
cbD->currentGraphicsSrb = srb;
|
cbD->currentGraphicsSrb = srb;
|
||||||
cbD->currentComputeSrb = nullptr;
|
cbD->currentComputeSrb = nullptr;
|
||||||
@ -1168,7 +1165,7 @@ void QRhiGles2::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBind
|
|||||||
cmd.args.bindShaderResources.maybeComputePs = compPsD;
|
cmd.args.bindShaderResources.maybeComputePs = compPsD;
|
||||||
cmd.args.bindShaderResources.srb = srb;
|
cmd.args.bindShaderResources.srb = srb;
|
||||||
cmd.args.bindShaderResources.dynamicOffsetCount = 0;
|
cmd.args.bindShaderResources.dynamicOffsetCount = 0;
|
||||||
if (hasDynamicOffsetInSrb) {
|
if (srbD->hasDynamicOffset) {
|
||||||
if (dynamicOffsetCount < QGles2CommandBuffer::Command::MAX_DYNAMIC_OFFSET_COUNT) {
|
if (dynamicOffsetCount < QGles2CommandBuffer::Command::MAX_DYNAMIC_OFFSET_COUNT) {
|
||||||
cmd.args.bindShaderResources.dynamicOffsetCount = dynamicOffsetCount;
|
cmd.args.bindShaderResources.dynamicOffsetCount = dynamicOffsetCount;
|
||||||
uint *p = cmd.args.bindShaderResources.dynamicOffsetPairs;
|
uint *p = cmd.args.bindShaderResources.dynamicOffsetPairs;
|
||||||
@ -4448,6 +4445,17 @@ bool QGles2ShaderResourceBindings::create()
|
|||||||
if (!rhiD->sanityCheckShaderResourceBindings(this))
|
if (!rhiD->sanityCheckShaderResourceBindings(this))
|
||||||
return false;
|
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);
|
rhiD->updateLayoutDesc(this);
|
||||||
|
|
||||||
generation += 1;
|
generation += 1;
|
||||||
|
@ -241,6 +241,7 @@ struct QGles2ShaderResourceBindings : public QRhiShaderResourceBindings
|
|||||||
void destroy() override;
|
void destroy() override;
|
||||||
bool create() override;
|
bool create() override;
|
||||||
|
|
||||||
|
bool hasDynamicOffset = false;
|
||||||
uint generation = 0;
|
uint generation = 0;
|
||||||
friend class QRhiGles2;
|
friend class QRhiGles2;
|
||||||
};
|
};
|
||||||
|
@ -4283,24 +4283,7 @@ void QRhiVulkan::setShaderResources(QRhiCommandBuffer *cb, QRhiShaderResourceBin
|
|||||||
}
|
}
|
||||||
|
|
||||||
QVkShaderResourceBindings *srbD = QRHI_RES(QVkShaderResourceBindings, srb);
|
QVkShaderResourceBindings *srbD = QRHI_RES(QVkShaderResourceBindings, srb);
|
||||||
bool hasSlottedResourceInSrb = false;
|
const int descSetIdx = srbD->hasSlottedResource ? currentFrameSlot : 0;
|
||||||
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;
|
|
||||||
bool rewriteDescSet = false;
|
bool rewriteDescSet = false;
|
||||||
|
|
||||||
// Do host writes and mark referenced shader resources as in-use.
|
// 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.
|
// make sure the descriptors for the correct slot will get bound.
|
||||||
// also, dynamic offsets always need a bind.
|
// 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);
|
const bool srbChanged = gfxPsD ? (cbD->currentGraphicsSrb != srb) : (cbD->currentComputeSrb != srb);
|
||||||
|
|
||||||
if (forceRebind || rewriteDescSet || srbChanged || cbD->currentSrbGeneration != srbD->generation) {
|
if (forceRebind || rewriteDescSet || srbChanged || cbD->currentSrbGeneration != srbD->generation) {
|
||||||
QVarLengthArray<uint32_t, 4> dynOfs;
|
QVarLengthArray<uint32_t, 4> dynOfs;
|
||||||
if (hasDynamicOffsetInSrb) {
|
if (srbD->hasDynamicOffset) {
|
||||||
// Filling out dynOfs based on the sorted bindings is important
|
// Filling out dynOfs based on the sorted bindings is important
|
||||||
// because dynOfs has to be ordered based on the binding numbers,
|
// because dynOfs has to be ordered based on the binding numbers,
|
||||||
// and neither srb nor dynamicOffsets has any such ordering
|
// and neither srb nor dynamicOffsets has any such ordering
|
||||||
@ -6249,6 +6232,18 @@ bool QVkShaderResourceBindings::create()
|
|||||||
return a.data()->binding < b.data()->binding;
|
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;
|
QVarLengthArray<VkDescriptorSetLayoutBinding, 4> vkbindings;
|
||||||
for (const QRhiShaderResourceBinding &binding : qAsConst(sortedBindings)) {
|
for (const QRhiShaderResourceBinding &binding : qAsConst(sortedBindings)) {
|
||||||
const QRhiShaderResourceBinding::Data *b = binding.data();
|
const QRhiShaderResourceBinding::Data *b = binding.data();
|
||||||
|
@ -249,6 +249,8 @@ struct QVkShaderResourceBindings : public QRhiShaderResourceBindings
|
|||||||
bool create() override;
|
bool create() override;
|
||||||
|
|
||||||
QVarLengthArray<QRhiShaderResourceBinding, 8> sortedBindings;
|
QVarLengthArray<QRhiShaderResourceBinding, 8> sortedBindings;
|
||||||
|
bool hasSlottedResource = false;
|
||||||
|
bool hasDynamicOffset = false;
|
||||||
int poolIndex = -1;
|
int poolIndex = -1;
|
||||||
VkDescriptorSetLayout layout = VK_NULL_HANDLE;
|
VkDescriptorSetLayout layout = VK_NULL_HANDLE;
|
||||||
VkDescriptorSet descSets[QVK_FRAMES_IN_FLIGHT]; // multiple sets to support dynamic buffers
|
VkDescriptorSet descSets[QVK_FRAMES_IN_FLIGHT]; // multiple sets to support dynamic buffers
|
||||||
|
Loading…
x
Reference in New Issue
Block a user