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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -241,6 +241,7 @@ struct QGles2ShaderResourceBindings : public QRhiShaderResourceBindings
|
||||
void destroy() override;
|
||||
bool create() override;
|
||||
|
||||
bool hasDynamicOffset = false;
|
||||
uint generation = 0;
|
||||
friend class QRhiGles2;
|
||||
};
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user