diff --git a/qrenderdoc/Windows/BufferViewer.cpp b/qrenderdoc/Windows/BufferViewer.cpp index 2ba5b33d5..13394e115 100644 --- a/qrenderdoc/Windows/BufferViewer.cpp +++ b/qrenderdoc/Windows/BufferViewer.cpp @@ -2869,9 +2869,12 @@ void BufferViewer::OnEventChanged(uint32_t eventId) bufdata->cb.valid = (reflection != NULL && m_CBufferSlot.slot < reflection->constantBlocks.size()); if(bufdata->cb.valid) - bufdata->cb.bufferBacked = reflection->constantBlocks[m_CBufferSlot.slot].bufferBacked; + { + bufdata->cb.bytesBacked = reflection->constantBlocks[m_CBufferSlot.slot].bufferBacked || + reflection->constantBlocks[m_CBufferSlot.slot].inlineDataBytes; + } - ui->setFormat->setEnabled(bufdata->cb.bufferBacked); + ui->setFormat->setEnabled(bufdata->cb.bytesBacked); if(ui->setFormat->isEnabled()) ui->setFormat->setToolTip(tr("Specify a custom format for this constant buffer")); else @@ -2908,7 +2911,7 @@ void BufferViewer::OnEventChanged(uint32_t eventId) UnrollConstant(parsed.repeating, bufdata->vsinConfig.columns, bufdata->vsinConfig.props); } - if((m_Format.isEmpty() || !bufdata->cb.bufferBacked) && IsCBufferView()) + if((m_Format.isEmpty() || !bufdata->cb.bytesBacked) && IsCBufferView()) { if(bufdata->cb.valid) { @@ -2942,7 +2945,7 @@ void BufferViewer::OnEventChanged(uint32_t eventId) bufdata->vsinConfig.baseVertex = action ? action->baseVertex : 0; - ui->formatSpecifier->setEnabled(!IsCBufferView() || bufdata->cb.bufferBacked); + ui->formatSpecifier->setEnabled(!IsCBufferView() || bufdata->cb.bytesBacked); ui->instance->setEnabled(action && (action->flags & ActionFlags::Instanced)); if(!ui->instance->isEnabled()) @@ -3072,9 +3075,9 @@ void BufferViewer::OnEventChanged(uint32_t eventId) } } - // for cbuffers, if the format is empty or if we're not buffer-backed, we evaluate variables - // here and don't use the format override with a fetched buffer - if((m_Format.isEmpty() || !bufdata->cb.bufferBacked) && IsCBufferView()) + // for cbuffers, if the format is empty or if we're not buffer-backed and don't have inline + // data, we evaluate variables here and don't use the format override with a fetched buffer + if((m_Format.isEmpty() || !bufdata->cb.bytesBacked) && IsCBufferView()) { // only fetch the cbuffer constants if this binding is currently valid if(bufdata->cb.valid) @@ -3216,7 +3219,7 @@ void BufferViewer::OnEventChanged(uint32_t eventId) UI_AddFixedVariables(ui->fixedVars->invisibleRootItem(), 0, bufdata->vsinConfig.fixedVars.type.members, vars); - if(IsCBufferView() && !bufdata->cb.bufferBacked) + if(IsCBufferView() && !bufdata->cb.bytesBacked) UI_RemoveOffsets(ui->fixedVars->invisibleRootItem()); } @@ -3375,7 +3378,7 @@ void BufferViewer::setPersistData(const QVariant &persistData) void BufferViewer::UI_FixedAddMatrixRows(RDTreeWidgetItem *n, const ShaderConstant &c, const ShaderVariable &v) { - const bool showPadding = ui->showPadding->isChecked() && m_CurCBuffer.bufferBacked; + const bool showPadding = ui->showPadding->isChecked() && m_CurCBuffer.bytesBacked; if(v.rows > 1) { @@ -3427,7 +3430,7 @@ void BufferViewer::UI_AddFixedVariables(RDTreeWidgetItem *root, uint32_t baseOff const rdcarray &consts, const rdcarray &vars) { - const bool showPadding = ui->showPadding->isChecked() && m_CurCBuffer.bufferBacked; + const bool showPadding = ui->showPadding->isChecked() && m_CurCBuffer.bytesBacked; if(consts.size() != vars.size()) qCritical() << "Shader variable mismatch"; diff --git a/qrenderdoc/Windows/BufferViewer.h b/qrenderdoc/Windows/BufferViewer.h index 33ece2c13..1d32dad10 100644 --- a/qrenderdoc/Windows/BufferViewer.h +++ b/qrenderdoc/Windows/BufferViewer.h @@ -76,7 +76,7 @@ struct BBoxData struct CBufferData { bool valid = false; - bool bufferBacked = false; + bool bytesBacked = false; ResourceId pipe; ResourceId shader; rdcstr entryPoint; diff --git a/renderdoc/api/replay/shader_types.h b/renderdoc/api/replay/shader_types.h index e323f8ba3..d9994dbc0 100644 --- a/renderdoc/api/replay/shader_types.h +++ b/renderdoc/api/replay/shader_types.h @@ -1109,7 +1109,7 @@ struct ConstantBlock { return name == o.name && variables == o.variables && bindPoint == o.bindPoint && byteSize == o.byteSize && bufferBacked == o.bufferBacked && - compileConstants == o.compileConstants; + inlineDataBytes == o.inlineDataBytes && compileConstants == o.compileConstants; } bool operator<(const ConstantBlock &o) const { @@ -1123,6 +1123,8 @@ struct ConstantBlock return byteSize < o.byteSize; if(!(bufferBacked == o.bufferBacked)) return bufferBacked < o.bufferBacked; + if(!(inlineDataBytes == o.inlineDataBytes)) + return inlineDataBytes < o.inlineDataBytes; if(!(compileConstants == o.compileConstants)) return compileConstants < o.compileConstants; return false; @@ -1145,6 +1147,8 @@ some other API-specific method, such as direct function calls or they may be com specialisation constants. )"); bool bufferBacked = true; + DOCUMENT("``True`` if this is backed by in-line data bytes rather than a specific buffer."); + bool inlineDataBytes = false; DOCUMENT("``True`` if this is a virtual buffer listing compile-time specialisation constants."); bool compileConstants = false; }; diff --git a/renderdoc/driver/shaders/spirv/spirv_reflect.cpp b/renderdoc/driver/shaders/spirv/spirv_reflect.cpp index 39edcde9b..914235da6 100644 --- a/renderdoc/driver/shaders/spirv/spirv_reflect.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_reflect.cpp @@ -1269,6 +1269,7 @@ void Reflector::MakeReflection(const GraphicsAPI sourceAPI, const ShaderStage st if(cblock.name.empty()) cblock.name = StringFormat::Fmt("uniforms%u", global.id.value()); cblock.bufferBacked = !pushConst; + cblock.inlineDataBytes = pushConst; MakeConstantBlockVariables(effectiveStorage, *varType, 0, 0, cblock.variables, pointerTypes, specInfo); @@ -1319,6 +1320,7 @@ void Reflector::MakeReflection(const GraphicsAPI sourceAPI, const ShaderStage st { specblock.name = "Specialization Constants"; specblock.bufferBacked = false; + specblock.inlineDataBytes = true; specblock.compileConstants = true; specblock.byteSize = 0; @@ -1338,6 +1340,7 @@ void Reflector::MakeReflection(const GraphicsAPI sourceAPI, const ShaderStage st { globalsblock.name = "$Globals"; globalsblock.bufferBacked = false; + globalsblock.inlineDataBytes = false; globalsblock.byteSize = (uint32_t)globalsblock.variables.size(); globalsblock.bindPoint = (int)cblocks.size();