diff --git a/qrenderdoc/Code/QRDUtils.cpp b/qrenderdoc/Code/QRDUtils.cpp index 9b9741473..a0f7e52e3 100644 --- a/qrenderdoc/Code/QRDUtils.cpp +++ b/qrenderdoc/Code/QRDUtils.cpp @@ -1273,6 +1273,21 @@ QString ToQStr(const AddressMode addr, const GraphicsAPI apitype) return lit("Unknown"); } +QString ToQStr(const ShadingRateCombiner addr, const GraphicsAPI apitype) +{ + if(IsD3D(apitype)) + { + switch(addr) + { + case ShadingRateCombiner::Keep: return lit("Passthrough"); + case ShadingRateCombiner::Replace: return lit("Override"); + default: break; + } + } + + return ToQStr(addr); +} + QString TypeString(const SigParameter &sig) { QString ret = ToQStr(sig.varType); diff --git a/qrenderdoc/Code/QRDUtils.h b/qrenderdoc/Code/QRDUtils.h index 0f1010cca..1e5453a94 100644 --- a/qrenderdoc/Code/QRDUtils.h +++ b/qrenderdoc/Code/QRDUtils.h @@ -58,14 +58,11 @@ inline QString ToQStr(const T &el) return QString(ToStr(el)); } -// overload for a couple of things that need to know the pipeline type when converting +// overloads for a couple of things that need to know the pipeline type when converting QString ToQStr(const ResourceUsage usage, const GraphicsAPI apitype); - -// overload for a couple of things that need to know the pipeline type when converting QString ToQStr(const ShaderStage stage, const GraphicsAPI apitype); - -// overload for a couple of things that need to know the pipeline type when converting QString ToQStr(const AddressMode addr, const GraphicsAPI apitype); +QString ToQStr(const ShadingRateCombiner addr, const GraphicsAPI apitype); inline QMetaType::Type GetVariantMetatype(const QVariant &v) { diff --git a/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp index 2db20e5a7..c42dc1550 100644 --- a/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp @@ -915,6 +915,10 @@ void D3D12PipelineStateViewer::clearState() ui->frontCCW->setPixmap(tick); ui->conservativeRaster->setPixmap(cross); + ui->baseShadingRate->setText(lit("1x1")); + ui->shadingRateCombiners->setText(lit("Passthrough, Passthrough")); + ui->shadingRateImage->setText(ToQStr(ResourceId())); + ui->depthBias->setText(lit("0.0")); ui->depthBiasClamp->setText(lit("0.0")); ui->slopeScaledBias->setText(lit("0.0")); @@ -1790,6 +1794,15 @@ void D3D12PipelineStateViewer::setState() state.rasterizer.state.conservativeRasterization != ConservativeRaster::Disabled ? tick : cross); + ui->baseShadingRate->setText(QFormatStr("%1x%2") + .arg(state.rasterizer.state.baseShadingRate.first) + .arg(state.rasterizer.state.baseShadingRate.second)); + ui->shadingRateCombiners->setText( + QFormatStr("%1, %2") + .arg(ToQStr(state.rasterizer.state.shadingRateCombiners.first, GraphicsAPI::D3D12)) + .arg(ToQStr(state.rasterizer.state.shadingRateCombiners.second, GraphicsAPI::D3D12))); + ui->shadingRateImage->setText(ToQStr(state.rasterizer.state.shadingRateImage)); + //////////////////////////////////////////////// // Output Merger diff --git a/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.ui b/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.ui index c056a4a90..998ddf22d 100644 --- a/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.ui +++ b/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.ui @@ -2201,19 +2201,6 @@ 0 - - - - Fill Mode: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - @@ -2232,28 +2219,15 @@ - - - - Cull Mode: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - - - + + 12 - None + 0.00 Qt::AlignCenter @@ -2263,10 +2237,26 @@ - - + + + + Qt::Vertical + + + QSizePolicy::Preferred + + + + 0 + 0 + + + + + + - Front CCW: + Fill Mode: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -2276,19 +2266,29 @@ - - + + - - - - :/cross.png + Depth Bias: - Qt::AlignCenter + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - 4 + + true + + + + + + + Line AA: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true @@ -2305,6 +2305,19 @@ + + + + Forced Sample Count: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + @@ -2321,28 +2334,13 @@ - - + + - Depth Bias: + - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - - - - - - 12 - - - - 0.00 + + :/cross.png Qt::AlignCenter @@ -2352,28 +2350,13 @@ - - + + - Depth Bias Clamp: + - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - - - - - - 12 - - - - 0.00 + + :/cross.png Qt::AlignCenter @@ -2383,16 +2366,19 @@ - - + + - Slope-Scaled Bias: + + + + :/cross.png - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + Qt::AlignCenter - - true + + 4 @@ -2414,66 +2400,6 @@ - - - - Forced Sample Count: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - - - - - - 12 - - - - 0 - - - Qt::AlignCenter - - - 4 - - - - - - - Depth Clip: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - - - - - - - - :/cross.png - - - Qt::AlignCenter - - - 4 - - - @@ -2487,26 +2413,26 @@ - - - - + + + + Qt::Horizontal - - :/cross.png + + QSizePolicy::MinimumExpanding - - Qt::AlignCenter + + + 0 + 0 + - - 4 - - + - - + + - Line AA: + Depth Clip: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -2516,26 +2442,23 @@ - - + + - - - - :/cross.png + Front CCW: - Qt::AlignCenter + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - 4 + + true - - + + - Sample Mask: + Slope-Scaled Bias: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -2563,37 +2486,162 @@ - - - - Qt::Vertical + + + + + 12 + - - QSizePolicy::Preferred + + None - - - 0 - 0 - + + Qt::AlignCenter - + + 4 + + + + + + + + 12 + + + + 0.00 + + + Qt::AlignCenter + + + 4 + + + + + + + Cull Mode: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + + + + + Depth Bias Clamp: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + + + + + + Sample Mask: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + true + + - - - Qt::Horizontal + + + Base Shading Rate: - - QSizePolicy::MinimumExpanding + + + + + + - - - 0 - 0 - + + :/cross.png - + + Qt::AlignCenter + + + 4 + + + + + + + + 12 + + + + 0 + + + Qt::AlignCenter + + + 4 + + + + + + + + 12 + + + + 1x1 + + + + + + + Shading Rate Image: + + + + + + + + + + Shading Rate Combiners: + + + + + + + + 12 + + + + Keep, Keep + + diff --git a/renderdoc/api/replay/d3d12_pipestate.h b/renderdoc/api/replay/d3d12_pipestate.h index 722e9f647..7754b49f5 100644 --- a/renderdoc/api/replay/d3d12_pipestate.h +++ b/renderdoc/api/replay/d3d12_pipestate.h @@ -626,6 +626,34 @@ not force any sample count. uint32_t forcedSampleCount = 0; DOCUMENT("The current :class:`ConservativeRaster` mode."); ConservativeRaster conservativeRasterization = ConservativeRaster::Disabled; + DOCUMENT(R"(The current base variable shading rate. This will always be 1x1 when variable shading +is disabled. + +:type: Tuple[int,int] +)"); + rdcpair baseShadingRate = {1, 1}; + DOCUMENT(R"(The shading rate combiners. + +The combiners are applied as follows, according to the D3D spec: + + ``intermediateRate = combiner[0] ( baseShadingRate, shaderExportedShadingRate )`` + ``finalRate = combiner[1] ( intermediateRate, imageBasedShadingRate )`` + +Where the first input is from :data:`baseShadingRate` and the second is the exported shading rate +from a vertex or geometry shader, which defaults to 1x1 if not exported. + +The intermediate result is then used as the first input to the second combiner, together with the +shading rate sampled from the shading rate image. + +:type: Tuple[ShadingRateCombiner,ShadingRateCombiner] +)"); + rdcpair shadingRateCombiners = { + ShadingRateCombiner::Passthrough, ShadingRateCombiner::Passthrough}; + DOCUMENT(R"(The image bound as a shading rate image. + +:type: ResourceId +)"); + ResourceId shadingRateImage; }; DOCUMENT("Describes the rasterization state of the D3D12 pipeline."); diff --git a/renderdoc/api/replay/renderdoc_tostr.inl b/renderdoc/api/replay/renderdoc_tostr.inl index 5631b67b8..19d524f34 100644 --- a/renderdoc/api/replay/renderdoc_tostr.inl +++ b/renderdoc/api/replay/renderdoc_tostr.inl @@ -323,6 +323,20 @@ rdcstr DoStringise(const ConservativeRaster &el) END_ENUM_STRINGISE(); } +template <> +rdcstr DoStringise(const ShadingRateCombiner &el) +{ + BEGIN_ENUM_STRINGISE(ShadingRateCombiner) + { + STRINGISE_ENUM_CLASS(Keep); + STRINGISE_ENUM_CLASS(Replace); + STRINGISE_ENUM_CLASS(Min); + STRINGISE_ENUM_CLASS(Max); + STRINGISE_ENUM_CLASS(Multiply); + } + END_ENUM_STRINGISE(); +} + template <> rdcstr DoStringise(const LineRaster &el) { diff --git a/renderdoc/api/replay/replay_enums.h b/renderdoc/api/replay/replay_enums.h index dde557b12..c71508423 100644 --- a/renderdoc/api/replay/replay_enums.h +++ b/renderdoc/api/replay/replay_enums.h @@ -2709,6 +2709,50 @@ enum class ConservativeRaster : uint32_t DECLARE_REFLECTION_ENUM(ConservativeRaster); +DOCUMENT(R"(A combiner to apply when determining a pixel shading rate. + +.. data:: Keep + + Keep the first input to the combiner. + +.. data:: Passthrough + + Keep the first input to the combiner. Alias for :data:`Keep`, for D3D terminology. + +.. data:: Replace + + Replace with the second input to the combiner. + +.. data:: Override + + Replace with the second input to the combiner. Alias for :data:`Replace`, for D3D terminology. + +.. data:: Min + + Use the minimum (finest rate) of the two inputs. + +.. data:: Max + + Use the maximum (coarsest rate) of the two inputs. + +.. data:: Multiply + + Multiply the two rates together (e.g. 1x1 and 1x2 = 1x2, 2x2 and 2x2 = 4x4). Note that D3D names + this 'sum' misleadingly. +)"); +enum class ShadingRateCombiner : uint32_t +{ + Keep, + Passthrough = Keep, + Replace, + Override = Replace, + Min, + Max, + Multiply, +}; + +DECLARE_REFLECTION_ENUM(ShadingRateCombiner); + DOCUMENT(R"(The line rasterization mode. .. data:: Default diff --git a/renderdoc/driver/d3d12/d3d12_replay.cpp b/renderdoc/driver/d3d12/d3d12_replay.cpp index 66624aaff..ba04fd7df 100644 --- a/renderdoc/driver/d3d12/d3d12_replay.cpp +++ b/renderdoc/driver/d3d12/d3d12_replay.cpp @@ -1515,6 +1515,41 @@ void D3D12Replay::SavePipelineState(uint32_t eventId) src.ConservativeRaster == D3D12_CONSERVATIVE_RASTERIZATION_MODE_ON ? ConservativeRaster::Overestimate : ConservativeRaster::Disabled; + + switch(rs.shadingRate) + { + default: + case D3D12_SHADING_RATE_1X1: dst.baseShadingRate = {1, 1}; break; + case D3D12_SHADING_RATE_1X2: dst.baseShadingRate = {1, 2}; break; + case D3D12_SHADING_RATE_2X1: dst.baseShadingRate = {2, 1}; break; + case D3D12_SHADING_RATE_2X2: dst.baseShadingRate = {2, 2}; break; + case D3D12_SHADING_RATE_2X4: dst.baseShadingRate = {2, 4}; break; + case D3D12_SHADING_RATE_4X2: dst.baseShadingRate = {4, 2}; break; + case D3D12_SHADING_RATE_4X4: dst.baseShadingRate = {4, 4}; break; + } + + ShadingRateCombiner combiners[2]; + + for(int i = 0; i < 2; i++) + { + switch(rs.shadingRateCombiners[i]) + { + default: + case D3D12_SHADING_RATE_COMBINER_PASSTHROUGH: + combiners[i] = ShadingRateCombiner::Passthrough; + break; + case D3D12_SHADING_RATE_COMBINER_OVERRIDE: + combiners[i] = ShadingRateCombiner::Override; + break; + case D3D12_SHADING_RATE_COMBINER_MIN: combiners[i] = ShadingRateCombiner::Min; break; + case D3D12_SHADING_RATE_COMBINER_MAX: combiners[i] = ShadingRateCombiner::Max; break; + case D3D12_SHADING_RATE_COMBINER_SUM: combiners[i] = ShadingRateCombiner::Multiply; break; + } + } + + dst.shadingRateCombiners = {combiners[0], combiners[1]}; + + dst.shadingRateImage = rm->GetOriginalID(rs.shadingRateImage); } state.rasterizer.scissors.resize(rs.scissors.size()); diff --git a/renderdoc/replay/renderdoc_serialise.inl b/renderdoc/replay/renderdoc_serialise.inl index 52780c3a0..5573af6f4 100644 --- a/renderdoc/replay/renderdoc_serialise.inl +++ b/renderdoc/replay/renderdoc_serialise.inl @@ -1439,8 +1439,11 @@ void DoSerialise(SerialiserType &ser, D3D12Pipe::RasterizerState &el) SERIALISE_MEMBER(antialiasedLines); SERIALISE_MEMBER(forcedSampleCount); SERIALISE_MEMBER(conservativeRasterization); + SERIALISE_MEMBER(baseShadingRate); + SERIALISE_MEMBER(shadingRateCombiners); + SERIALISE_MEMBER(shadingRateImage); - SIZE_CHECK(36); + SIZE_CHECK(64); } template @@ -1451,7 +1454,7 @@ void DoSerialise(SerialiserType &ser, D3D12Pipe::Rasterizer &el) SERIALISE_MEMBER(scissors); SERIALISE_MEMBER(state); - SIZE_CHECK(96); + SIZE_CHECK(120); } template @@ -1539,7 +1542,7 @@ void DoSerialise(SerialiserType &ser, D3D12Pipe::State &el) SERIALISE_MEMBER(resourceStates); - SIZE_CHECK(1408); + SIZE_CHECK(1432); } #pragma endregion D3D12 pipeline state