diff --git a/qrenderdoc/Windows/PipelineState/D3D11PipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/D3D11PipelineStateViewer.cpp index af30c9104..84e45cc4e 100644 --- a/qrenderdoc/Windows/PipelineState/D3D11PipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/D3D11PipelineStateViewer.cpp @@ -1532,7 +1532,8 @@ void D3D11PipelineStateViewer::setState() b->setEnabled(stage->reflection != NULL); - m_Common.SetupShaderEditButton(b, ResourceId(), stage->resourceId, stage->reflection); + m_Common.SetupShaderEditButton(b, ResourceId(), stage->resourceId, stage->bindpointMapping, + stage->reflection); } ui->iaBytecodeViewButton->setEnabled(true); diff --git a/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp index d1c64902d..0fb01a11c 100644 --- a/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp @@ -1550,7 +1550,8 @@ void D3D12PipelineStateViewer::setState() b->setEnabled(stage->reflection && state.pipelineResourceId != ResourceId()); - m_Common.SetupShaderEditButton(b, state.pipelineResourceId, stage->resourceId, stage->reflection); + m_Common.SetupShaderEditButton(b, state.pipelineResourceId, stage->resourceId, + stage->bindpointMapping, stage->reflection); } bool streamoutSet = false; diff --git a/qrenderdoc/Windows/PipelineState/GLPipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/GLPipelineStateViewer.cpp index 16e10e1d5..dd13ea25d 100644 --- a/qrenderdoc/Windows/PipelineState/GLPipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/GLPipelineStateViewer.cpp @@ -1486,11 +1486,10 @@ void GLPipelineStateViewer::setState() if(stage == NULL || stage->shaderResourceId == ResourceId()) continue; - ShaderReflection *shaderDetails = stage->reflection; + b->setEnabled(stage->reflection != NULL); - b->setEnabled(shaderDetails != NULL); - - m_Common.SetupShaderEditButton(b, ResourceId(), stage->shaderResourceId, shaderDetails); + m_Common.SetupShaderEditButton(b, ResourceId(), stage->shaderResourceId, + stage->bindpointMapping, stage->reflection); } vs = ui->xfbBuffers->verticalScrollBar()->value(); diff --git a/qrenderdoc/Windows/PipelineState/PipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/PipelineStateViewer.cpp index 6f43efe49..8ba5766fc 100644 --- a/qrenderdoc/Windows/PipelineState/PipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/PipelineStateViewer.cpp @@ -903,7 +903,8 @@ void PipelineStateViewer::MakeShaderVariablesHLSL(bool cbufferContents, } } -QString PipelineStateViewer::GenerateHLSLStub(const ShaderReflection *shaderDetails, +QString PipelineStateViewer::GenerateHLSLStub(const ShaderBindpointMapping &bindpointMapping, + const ShaderReflection *shaderDetails, const QString &entryFunc) { QString hlsl = lit("// HLSL function stub generated\n\n"); @@ -914,22 +915,40 @@ QString PipelineStateViewer::GenerateHLSLStub(const ShaderReflection *shaderDeta lit("Texture2DMSArray"), lit("Texture3D"), lit("TextureCube"), lit("TextureCubeArray"), }; + // use bindpoint mapping + for(const ShaderSampler &samp : shaderDetails->samplers) { - hlsl += lit("//SamplerComparisonState %1 : register(s%2); // can't disambiguate\n" - "SamplerState %1 : register(s%2); // can't disambiguate\n") + uint32_t reg = ~0U; + + if(samp.bindPoint < bindpointMapping.samplers.count()) + reg = bindpointMapping.samplers[samp.bindPoint].bind; + else + hlsl += lit("//"); + + hlsl += lit("SamplerState %1 : register(s%2); // can't disambiguate\n" + "//SamplerComparisonState %1 : register(s%2); // can't disambiguate\n") .arg(samp.name) - .arg(samp.bindPoint); + .arg(reg); } for(int i = 0; i < 2; i++) { + const rdcarray &binds = + (i == 0 ? bindpointMapping.readOnlyResources : bindpointMapping.readWriteResources); const rdcarray &resources = (i == 0 ? shaderDetails->readOnlyResources : shaderDetails->readWriteResources); for(const ShaderResource &res : resources) { char regChar = 't'; + uint32_t reg = ~0U; + + if(res.bindPoint < binds.count()) + reg = binds[res.bindPoint].bind; + else + hlsl += lit("//"); + if(i == 1) { hlsl += lit("RW"); @@ -943,7 +962,7 @@ QString PipelineStateViewer::GenerateHLSLStub(const ShaderReflection *shaderDeta .arg(res.variableType.descriptor.name) .arg(res.name) .arg(QLatin1Char(regChar)) - .arg(res.bindPoint); + .arg(reg); } else { @@ -954,7 +973,7 @@ QString PipelineStateViewer::GenerateHLSLStub(const ShaderReflection *shaderDeta .arg(res.variableType.descriptor.name) .arg(res.name) .arg(QLatin1Char(regChar)) - .arg(res.bindPoint); + .arg(reg); } } } @@ -968,12 +987,22 @@ QString PipelineStateViewer::GenerateHLSLStub(const ShaderReflection *shaderDeta { if(!cbuf.name.isEmpty() && !cbuf.variables.isEmpty()) { + uint32_t reg = ~0U; + + if(cbuf.bindPoint < bindpointMapping.constantBlocks.count()) + reg = bindpointMapping.constantBlocks[cbuf.bindPoint].bind; + else + hlsl += lit("/*\n"); + QString cbufName = cbuf.name; if(cbufName == lit("$Globals")) cbufName = lit("_Globals"); cbuffers += lit("cbuffer %1 : register(b%2) {\n").arg(cbufName).arg(cbuf.bindPoint); MakeShaderVariablesHLSL(true, cbuf.variables, cbuffers, hlsl); cbuffers += lit("};\n\n"); + + if(reg == ~0U) + hlsl += lit("*/\n"); } cbufIdx++; } @@ -984,18 +1013,27 @@ QString PipelineStateViewer::GenerateHLSLStub(const ShaderReflection *shaderDeta hlsl += lit("struct InputStruct {\n"); for(const SigParameter &sig : shaderDetails->inputSignature) - hlsl += lit("\t%1 %2 : %3;\n") - .arg(TypeString(sig)) - .arg(!sig.varName.isEmpty() ? QString(sig.varName) : lit("param%1").arg(sig.regIndex)) - .arg(D3DSemanticString(sig)); + { + QString name = !sig.varName.isEmpty() ? QString(sig.varName) : lit("param%1").arg(sig.regIndex); + + if(sig.varName.isEmpty() && sig.systemValue != ShaderBuiltin::Undefined) + name = D3DSemanticString(sig).replace(lit("SV_"), QString()); + + hlsl += lit("\t%1 %2 : %3;\n").arg(TypeString(sig)).arg(name).arg(D3DSemanticString(sig)); + } hlsl += lit("};\n\n"); hlsl += lit("struct OutputStruct {\n"); for(const SigParameter &sig : shaderDetails->outputSignature) - hlsl += lit("\t%1 %2 : %3;\n") - .arg(TypeString(sig)) - .arg(!sig.varName.isEmpty() ? QString(sig.varName) : lit("param%1").arg(sig.regIndex)) - .arg(D3DSemanticString(sig)); + { + QString name = !sig.varName.isEmpty() ? QString(sig.varName) : lit("param%1").arg(sig.regIndex); + + if(sig.varName.isEmpty() && sig.systemValue != ShaderBuiltin::Undefined) + name = D3DSemanticString(sig).replace(lit("SV_"), QString()); + + hlsl += lit("\t%1 %2 : %3;\n").arg(TypeString(sig)).arg(name).arg(D3DSemanticString(sig)); + } + hlsl += lit("};\n\n"); hlsl += lit("OutputStruct %1(in InputStruct IN)\n" @@ -1131,6 +1169,7 @@ IShaderViewer *PipelineStateViewer::EditDecompiledSource(const ShaderProcessingT void PipelineStateViewer::SetupShaderEditButton(QToolButton *button, ResourceId pipelineId, ResourceId shaderId, + const ShaderBindpointMapping &bindpointMapping, const ShaderReflection *shaderDetails) { if(!shaderDetails || !button->isEnabled() || button->popupMode() != QToolButton::MenuButtonPopup) @@ -1189,7 +1228,8 @@ void PipelineStateViewer::SetupShaderEditButton(QToolButton *button, ResourceId QAction *action = new QAction(label, menu); action->setIcon(Icons::page_white_edit()); - QObject::connect(action, &QAction::triggered, [this, pipelineId, shaderId, shaderDetails]() { + QObject::connect(action, &QAction::triggered, [this, pipelineId, shaderId, bindpointMapping, + shaderDetails]() { QString entry; QString src; @@ -1218,8 +1258,8 @@ void PipelineStateViewer::SetupShaderEditButton(QToolButton *button, ResourceId entry = lit("EditedShader%1S").arg(ToQStr(shaderDetails->stage, GraphicsAPI::D3D11)[0]); rdcstrpairs files; - files.push_back(rdcpair("decompiled_stub.hlsl", - GenerateHLSLStub(shaderDetails, entry))); + files.push_back(rdcpair( + "decompiled_stub.hlsl", GenerateHLSLStub(bindpointMapping, shaderDetails, entry))); EditShader(shaderId, shaderDetails->stage, entry, ShaderCompileFlags(), ShaderEncoding::HLSL, files); diff --git a/qrenderdoc/Windows/PipelineState/PipelineStateViewer.h b/qrenderdoc/Windows/PipelineState/PipelineStateViewer.h index 0864cd143..77ce00a65 100644 --- a/qrenderdoc/Windows/PipelineState/PipelineStateViewer.h +++ b/qrenderdoc/Windows/PipelineState/PipelineStateViewer.h @@ -68,6 +68,7 @@ public: void setPersistData(const QVariant &persistData); void SetupShaderEditButton(QToolButton *button, ResourceId pipelineId, ResourceId shaderId, + const ShaderBindpointMapping &bindpointMapping, const ShaderReflection *shaderDetails); QString GenerateBufferFormatter(const ShaderResource &res, const ResourceFormat &viewFormat, @@ -96,7 +97,8 @@ private: QString declareStruct(QList &declaredStructs, const QString &name, const rdcarray &members, uint32_t requiredByteStride); - QString GenerateHLSLStub(const ShaderReflection *shaderDetails, const QString &entryFunc); + QString GenerateHLSLStub(const ShaderBindpointMapping &bindpointMapping, + const ShaderReflection *shaderDetails, const QString &entryFunc); IShaderViewer *EditShader(ResourceId id, ShaderStage shaderType, const rdcstr &entry, ShaderCompileFlags compileFlags, ShaderEncoding encoding, const rdcstrpairs &files); diff --git a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp index 1a66862f8..281f0dd8d 100644 --- a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp @@ -2046,14 +2046,13 @@ void VulkanPipelineStateViewer::setState() if(stage == NULL || stage->resourceId == ResourceId()) continue; - ShaderReflection *shaderDetails = stage->reflection; - ResourceId pipe = stage->stage == ShaderStage::Compute ? state.compute.pipelineResourceId : state.graphics.pipelineResourceId; - b->setEnabled(shaderDetails && pipe != ResourceId()); + b->setEnabled(stage->reflection && pipe != ResourceId()); - m_Common.SetupShaderEditButton(b, pipe, stage->resourceId, shaderDetails); + m_Common.SetupShaderEditButton(b, pipe, stage->resourceId, stage->bindpointMapping, + stage->reflection); } bool xfbSet = false;