From 7bb5c135dfd03f5af3691293ad05fcb7da28d213 Mon Sep 17 00:00:00 2001 From: baldurk Date: Fri, 29 May 2026 14:03:45 +0100 Subject: [PATCH] Display relevant slot when independent blend is off on D3D. Closes #3842 * On D3D11 the runtime handled this for us via query of the DESC struct, but on D3D12 we'd get whatever the user provided. To make things more clear we display only the active blend state slot and label it 'all' instead of 0 on both D3D11 and D3D12. --- .../D3D11PipelineStateViewer.cpp | 22 ++++++++++++++----- .../D3D12PipelineStateViewer.cpp | 22 ++++++++++++++----- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/qrenderdoc/Windows/PipelineState/D3D11PipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/D3D11PipelineStateViewer.cpp index 346845acb..ea8530a02 100644 --- a/qrenderdoc/Windows/PipelineState/D3D11PipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/D3D11PipelineStateViewer.cpp @@ -1962,18 +1962,26 @@ void D3D11PipelineStateViewer::setState() ui->blends->beginUpdate(); ui->blends->clear(); { + bool independent = state.outputMerger.blendState.independentBlend; int i = 0; for(const ColorBlend &blend : state.outputMerger.blendState.blends) { - bool filledSlot = (blend.enabled || targets[i]); + bool filledSlot = true; bool usedSlot = (targets[i]); + if(!independent) + usedSlot = i == 0; + if(showNode(usedSlot, filledSlot)) { RDTreeWidgetItem *node = NULL; + QString slotName = QString::number(i); + if(!independent) + slotName = i == 0 ? tr("All") : lit("-"); + node = new RDTreeWidgetItem( - {i, blend.enabled ? tr("True") : tr("False"), + {slotName, blend.enabled ? tr("True") : tr("False"), ToQStr(blend.colorBlend.source), ToQStr(blend.colorBlend.destination), ToQStr(blend.colorBlend.operation), @@ -1989,9 +1997,6 @@ void D3D11PipelineStateViewer::setState() .arg((blend.writeMask & 0x4) == 0 ? lit("_") : lit("B")) .arg((blend.writeMask & 0x8) == 0 ? lit("_") : lit("A"))}); - if(!filledSlot) - setEmptyRow(node); - if(!usedSlot) setInactiveRow(node); @@ -3153,6 +3158,7 @@ void D3D11PipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const D3D11Pipe QList rows; + bool independent = om.blendState.independentBlend; int i = 0; for(const ColorBlend &b : om.blendState.blends) { @@ -3165,7 +3171,11 @@ void D3D11PipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const D3D11Pipe .arg((b.writeMask & 0x4) == 0 ? lit("_") : lit("B")) .arg((b.writeMask & 0x8) == 0 ? lit("_") : lit("A")); - rows.push_back({i, b.enabled ? tr("Yes") : tr("No"), + QString slotName = QString::number(i); + if(!independent) + slotName = i == 0 ? tr("All") : lit("-"); + + rows.push_back({slotName, b.enabled ? tr("Yes") : tr("No"), b.logicOperationEnabled ? tr("Yes") : tr("No"), ToQStr(b.colorBlend.source), ToQStr(b.colorBlend.destination), ToQStr(b.colorBlend.operation), ToQStr(b.alphaBlend.source), ToQStr(b.alphaBlend.destination), diff --git a/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp index a84678ce5..5e1d1e27b 100644 --- a/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp @@ -2137,18 +2137,26 @@ void D3D12PipelineStateViewer::setState() ui->blends->beginUpdate(); ui->blends->clear(); { + bool independent = state.outputMerger.blendState.independentBlend; int i = 0; for(const ColorBlend &blend : state.outputMerger.blendState.blends) { - bool filledSlot = (blend.enabled || targets[i]); + bool filledSlot = true; bool usedSlot = (targets[i]); + if(!independent) + usedSlot = i == 0; + if(showNode(usedSlot, filledSlot)) { RDTreeWidgetItem *node = NULL; + QString slotName = QString::number(i); + if(!independent) + slotName = i == 0 ? tr("All") : lit("-"); + node = new RDTreeWidgetItem( - {i, blend.enabled ? tr("True") : tr("False"), + {slotName, blend.enabled ? tr("True") : tr("False"), ToQStr(blend.colorBlend.source), ToQStr(blend.colorBlend.destination), ToQStr(blend.colorBlend.operation), @@ -2164,9 +2172,6 @@ void D3D12PipelineStateViewer::setState() .arg((blend.writeMask & 0x4) == 0 ? lit("_") : lit("B")) .arg((blend.writeMask & 0x8) == 0 ? lit("_") : lit("A"))}); - if(!filledSlot) - setEmptyRow(node); - if(!usedSlot) setInactiveRow(node); @@ -3400,6 +3405,7 @@ void D3D12PipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const D3D12Pipe QList rows; + bool independent = om.blendState.independentBlend; int i = 0; for(const ColorBlend &b : om.blendState.blends) { @@ -3412,7 +3418,11 @@ void D3D12PipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const D3D12Pipe .arg((b.writeMask & 0x4) == 0 ? lit("_") : lit("B")) .arg((b.writeMask & 0x8) == 0 ? lit("_") : lit("A")); - rows.push_back({i, b.enabled ? tr("Yes") : tr("No"), + QString slotName = QString::number(i); + if(!independent) + slotName = i == 0 ? tr("All") : lit("-"); + + rows.push_back({slotName, b.enabled ? tr("Yes") : tr("No"), b.logicOperationEnabled ? tr("Yes") : tr("No"), ToQStr(b.colorBlend.source), ToQStr(b.colorBlend.destination), ToQStr(b.colorBlend.operation), ToQStr(b.alphaBlend.source), ToQStr(b.alphaBlend.destination),