diff --git a/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp index b374526e6..d2f031d90 100644 --- a/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp @@ -425,9 +425,9 @@ D3D12PipelineStateViewer::D3D12PipelineStateViewer(ICaptureContext &ctx, RDHeaderView *header = new RDHeaderView(Qt::Horizontal, this); ui->stencils->setHeader(header); - ui->stencils->setColumns( - {tr("Face"), tr("Func"), tr("Fail Op"), tr("Depth Fail Op"), tr("Pass Op")}); - header->setColumnStretchHints({1, 2, 2, 2, 2}); + ui->stencils->setColumns({tr("Face"), tr("Func"), tr("Fail Op"), tr("Depth Fail Op"), + tr("Pass Op"), tr("Write Mask"), tr("Comp Mask"), tr("Ref")}); + header->setColumnStretchHints({1, 2, 2, 2, 2, 1, 1, 1}); ui->stencils->setClearSelectionOnFocusLoss(true); ui->stencils->setInstantTooltips(true); @@ -1000,8 +1000,7 @@ void D3D12PipelineStateViewer::clearState() ui->forcedSampleCount->setText(lit("0")); ui->depthClip->setPixmap(tick); - ui->multisample->setPixmap(tick); - ui->lineAA->setPixmap(tick); + ui->lineAA->setText(lit("-")); ui->sampleMask->setText(lit("FFFFFFFF")); ui->independentBlend->setPixmap(cross); @@ -1022,11 +1021,6 @@ void D3D12PipelineStateViewer::clearState() ui->depthBounds->setPixmap(QPixmap()); ui->depthBounds->setText(lit("0.0-1.0")); - ui->stencilEnabled->setPixmap(cross); - ui->stencilReadMask->setText(lit("FF")); - ui->stencilWriteMask->setText(lit("FF")); - ui->stencilRef->setText(lit("FF")); - ui->stencils->clear(); ui->computeDebugSelector->setEnabled(false); @@ -1946,9 +1940,15 @@ void D3D12PipelineStateViewer::setState() ui->cullMode->setText(ToQStr(state.rasterizer.state.cullMode)); ui->frontCCW->setPixmap(state.rasterizer.state.frontCCW ? tick : cross); - ui->lineAA->setPixmap(state.rasterizer.state.antialiasedLines ? tick : cross); + switch(state.rasterizer.state.lineRasterMode) + { + case LineRaster::Default: ui->lineAA->setText(lit("Default")); break; + case LineRaster::Bresenham: ui->lineAA->setText(lit("Aliased")); break; + case LineRaster::RectangularSmooth: ui->lineAA->setText(lit("Alpha antialiased")); break; + case LineRaster::Rectangular: ui->lineAA->setText(lit("Quadrilateral (narrow)")); break; + case LineRaster::RectangularD3D: ui->lineAA->setText(lit("Quadrilateral")); break; + } ui->sampleMask->setText(Formatter::Format(state.rasterizer.sampleMask, true)); - ui->multisample->setPixmap(state.rasterizer.state.multisampleEnable ? tick : cross); ui->depthClip->setPixmap(state.rasterizer.state.depthClip ? tick : cross); ui->depthBias->setText(Formatter::Format(state.rasterizer.state.depthBias)); @@ -2078,26 +2078,47 @@ void D3D12PipelineStateViewer::setState() ui->depthBounds->setPixmap(cross); } - ui->stencilEnabled->setPixmap(state.outputMerger.depthStencilState.stencilEnable ? tick : cross); - m_Common.SetStencilLabelValue( - ui->stencilReadMask, (uint8_t)state.outputMerger.depthStencilState.frontFace.compareMask); - m_Common.SetStencilLabelValue(ui->stencilWriteMask, - (uint8_t)state.outputMerger.depthStencilState.frontFace.writeMask); - m_Common.SetStencilLabelValue(ui->stencilRef, - (uint8_t)state.outputMerger.depthStencilState.frontFace.reference); - ui->stencils->beginUpdate(); ui->stencils->clear(); - ui->stencils->addTopLevelItem(new RDTreeWidgetItem( - {tr("Front"), ToQStr(state.outputMerger.depthStencilState.frontFace.function), - ToQStr(state.outputMerger.depthStencilState.frontFace.failOperation), - ToQStr(state.outputMerger.depthStencilState.frontFace.depthFailOperation), - ToQStr(state.outputMerger.depthStencilState.frontFace.passOperation)})); - ui->stencils->addTopLevelItem(new RDTreeWidgetItem( - {tr("Back"), ToQStr(state.outputMerger.depthStencilState.backFace.function), - ToQStr(state.outputMerger.depthStencilState.backFace.failOperation), - ToQStr(state.outputMerger.depthStencilState.backFace.depthFailOperation), - ToQStr(state.outputMerger.depthStencilState.backFace.passOperation)})); + if(state.outputMerger.depthStencilState.stencilEnable) + { + ui->stencils->addTopLevelItem(new RDTreeWidgetItem({ + tr("Front"), ToQStr(state.outputMerger.depthStencilState.frontFace.function), + ToQStr(state.outputMerger.depthStencilState.frontFace.failOperation), + ToQStr(state.outputMerger.depthStencilState.frontFace.depthFailOperation), + ToQStr(state.outputMerger.depthStencilState.frontFace.passOperation), QVariant(), + QVariant(), QVariant(), + })); + + m_Common.SetStencilTreeItemValue(ui->stencils->topLevelItem(0), 5, + state.outputMerger.depthStencilState.frontFace.writeMask); + m_Common.SetStencilTreeItemValue(ui->stencils->topLevelItem(0), 6, + state.outputMerger.depthStencilState.frontFace.compareMask); + m_Common.SetStencilTreeItemValue(ui->stencils->topLevelItem(0), 7, + state.outputMerger.depthStencilState.frontFace.reference); + + ui->stencils->addTopLevelItem(new RDTreeWidgetItem({ + tr("Back"), ToQStr(state.outputMerger.depthStencilState.backFace.function), + ToQStr(state.outputMerger.depthStencilState.backFace.failOperation), + ToQStr(state.outputMerger.depthStencilState.backFace.depthFailOperation), + ToQStr(state.outputMerger.depthStencilState.backFace.passOperation), QVariant(), QVariant(), + QVariant(), + })); + + m_Common.SetStencilTreeItemValue(ui->stencils->topLevelItem(1), 5, + state.outputMerger.depthStencilState.backFace.writeMask); + m_Common.SetStencilTreeItemValue(ui->stencils->topLevelItem(1), 6, + state.outputMerger.depthStencilState.backFace.compareMask); + m_Common.SetStencilTreeItemValue(ui->stencils->topLevelItem(1), 7, + state.outputMerger.depthStencilState.backFace.reference); + } + else + { + ui->stencils->addTopLevelItem(new RDTreeWidgetItem( + {tr("Front"), lit("-"), lit("-"), lit("-"), lit("-"), lit("-"), lit("-"), lit("-")})); + ui->stencils->addTopLevelItem(new RDTreeWidgetItem( + {tr("Back"), lit("-"), lit("-"), lit("-"), lit("-"), lit("-"), lit("-"), lit("-")})); + } ui->stencils->clearSelection(); ui->stencils->endUpdate(); @@ -3199,10 +3220,9 @@ void D3D12PipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const D3D12Pipe xml.writeEndElement(); m_Common.exportHTMLTable( - xml, {tr("Line AA Enable"), tr("Multisample Enable"), tr("Forced Sample Count"), - tr("Conservative Raster"), tr("Sample Mask")}, - {rs.state.antialiasedLines ? tr("Yes") : tr("No"), - rs.state.multisampleEnable ? tr("Yes") : tr("No"), rs.state.forcedSampleCount, + xml, {tr("Line Rasteriztion"), tr("Forced Sample Count"), tr("Conservative Raster"), + tr("Sample Mask")}, + {ToQStr(rs.state.lineRasterMode), rs.state.forcedSampleCount, rs.state.conservativeRasterization != ConservativeRaster::Disabled ? tr("Yes") : tr("No"), Formatter::Format(rs.sampleMask, true)}); @@ -3340,27 +3360,41 @@ void D3D12PipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const D3D12Pipe xml.writeCharacters(tr("Stencil State")); xml.writeEndElement(); - m_Common.exportHTMLTable( - xml, {tr("Stencil Test Enable"), tr("Stencil Read Mask"), tr("Stencil Write Mask")}, - {om.depthStencilState.stencilEnable ? tr("Yes") : tr("No"), - Formatter::Format(om.depthStencilState.frontFace.compareMask, true), - Formatter::Format(om.depthStencilState.frontFace.writeMask, true)}); + if(om.depthStencilState.stencilEnable) + { + QList rows; - xml.writeStartElement(lit("p")); - xml.writeEndElement(); + rows.push_back({ + tr("Front"), Formatter::Format(om.depthStencilState.frontFace.reference, true), + Formatter::Format(om.depthStencilState.frontFace.compareMask, true), + Formatter::Format(om.depthStencilState.frontFace.writeMask, true), + ToQStr(om.depthStencilState.frontFace.function), + ToQStr(om.depthStencilState.frontFace.passOperation), + ToQStr(om.depthStencilState.frontFace.failOperation), + ToQStr(om.depthStencilState.frontFace.depthFailOperation), + }); - m_Common.exportHTMLTable(xml, {tr("Face"), tr("Function"), tr("Pass Operation"), - tr("Fail Operation"), tr("Depth Fail Operation")}, - { - {tr("Front"), ToQStr(om.depthStencilState.frontFace.function), - ToQStr(om.depthStencilState.frontFace.passOperation), - ToQStr(om.depthStencilState.frontFace.failOperation), - ToQStr(om.depthStencilState.frontFace.depthFailOperation)}, - {tr("Back"), ToQStr(om.depthStencilState.backFace.function), - ToQStr(om.depthStencilState.backFace.passOperation), - ToQStr(om.depthStencilState.backFace.failOperation), - ToQStr(om.depthStencilState.backFace.depthFailOperation)}, - }); + rows.push_back({ + tr("back"), Formatter::Format(om.depthStencilState.backFace.reference, true), + Formatter::Format(om.depthStencilState.backFace.compareMask, true), + Formatter::Format(om.depthStencilState.backFace.writeMask, true), + ToQStr(om.depthStencilState.backFace.function), + ToQStr(om.depthStencilState.backFace.passOperation), + ToQStr(om.depthStencilState.backFace.failOperation), + ToQStr(om.depthStencilState.backFace.depthFailOperation), + }); + + m_Common.exportHTMLTable(xml, + {tr("Face"), tr("Ref"), tr("Compare Mask"), tr("Write Mask"), + tr("Function"), tr("Pass Op"), tr("Fail Op"), tr("Depth Fail Op")}, + rows); + } + else + { + xml.writeStartElement(lit("p")); + xml.writeCharacters(tr("Disabled")); + xml.writeEndElement(); + } } { diff --git a/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.ui b/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.ui index 622a05a7f..d7f974b3a 100644 --- a/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.ui +++ b/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.ui @@ -2521,35 +2521,6 @@ - - - - Multisample: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - - - - - - - - :/cross.png - - - Qt::AlignCenter - - - 4 - - - @@ -2565,11 +2536,13 @@ - - + + + 12 + - - :/cross.png + + Quadrilateral Qt::AlignCenter @@ -3608,7 +3581,10 @@ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - + + + 0 + 2 @@ -3621,143 +3597,7 @@ 2 - - 4 - - - - - - - Enabled: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - :/cross.png - - - Qt::AlignCenter - - - 4 - - - - - - - Write Mask: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - - - - - - 12 - - - - FF - - - Qt::AlignCenter - - - 4 - - - - - - - Read Mask: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - - - - - - 12 - - - - FF - - - Qt::AlignCenter - - - 4 - - - - - - - Ref: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 12 - - - - FF - - - Qt::AlignCenter - - - 4 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - + diff --git a/renderdoc/api/replay/d3d12_pipestate.h b/renderdoc/api/replay/d3d12_pipestate.h index da626a3b6..cf808b7b9 100644 --- a/renderdoc/api/replay/d3d12_pipestate.h +++ b/renderdoc/api/replay/d3d12_pipestate.h @@ -683,7 +683,7 @@ struct RasterizerState )"); bool frontCCW = false; DOCUMENT("The fixed depth bias value to apply to z-values."); - int32_t depthBias = 0; + float depthBias = 0.0f; DOCUMENT(R"(The clamp value for calculated depth bias from :data:`depthBias` and :data:`slopeScaledDepthBias` )"); @@ -692,12 +692,8 @@ struct RasterizerState float slopeScaledDepthBias = 0.0f; DOCUMENT("``True`` if pixels outside of the near and far depth planes should be clipped."); bool depthClip = false; - DOCUMENT("``True`` if the quadrilateral MSAA algorithm should be used on MSAA targets."); - bool multisampleEnable = false; - DOCUMENT( - "``True`` if lines should be anti-aliased. Ignored if :data:`multisampleEnable` is " - "``False``."); - bool antialiasedLines = false; + DOCUMENT("The line rasterization mode."); + LineRaster lineRasterMode = LineRaster::Default; DOCUMENT(R"(A sample count to force rasterization to when UAV rendering or rasterizing, or 0 to not force any sample count. )"); diff --git a/renderdoc/api/replay/renderdoc_tostr.inl b/renderdoc/api/replay/renderdoc_tostr.inl index c34916a16..d99ccf0e1 100644 --- a/renderdoc/api/replay/renderdoc_tostr.inl +++ b/renderdoc/api/replay/renderdoc_tostr.inl @@ -359,6 +359,7 @@ rdcstr DoStringise(const LineRaster &el) STRINGISE_ENUM_CLASS(Rectangular); STRINGISE_ENUM_CLASS(Bresenham); STRINGISE_ENUM_CLASS(RectangularSmooth); + STRINGISE_ENUM_CLASS(RectangularD3D); } END_ENUM_STRINGISE(); } diff --git a/renderdoc/api/replay/replay_enums.h b/renderdoc/api/replay/replay_enums.h index d9752dfd1..a385ab1c8 100644 --- a/renderdoc/api/replay/replay_enums.h +++ b/renderdoc/api/replay/replay_enums.h @@ -2999,7 +2999,13 @@ DOCUMENT(R"(The line rasterization mode. .. data:: RectangularSmooth - Lines are rasterized as rectangles extruded from the line with coverage falloff. + Lines are rasterized as rectangles extruded from the line with coverage falloff being + implementation independent. + +.. data:: RectangularD3D + + Lines are rasterized as rectangles extruded from the line, but with a width of 1.4 according to + legacy D3D behaviour )"); enum class LineRaster : uint32_t { @@ -3007,6 +3013,7 @@ enum class LineRaster : uint32_t Rectangular, Bresenham, RectangularSmooth, + RectangularD3D, }; DECLARE_REFLECTION_ENUM(LineRaster); diff --git a/renderdoc/driver/d3d12/d3d12_command_list8_wrap.cpp b/renderdoc/driver/d3d12/d3d12_command_list8_wrap.cpp index e0ab3f802..8e4a599d4 100644 --- a/renderdoc/driver/d3d12/d3d12_command_list8_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_command_list8_wrap.cpp @@ -24,7 +24,78 @@ #include "d3d12_command_list.h" -void STDMETHODCALLTYPE WrappedID3D12GraphicsCommandList::OMSetFrontAndBackStencilRef( - _In_ UINT FrontStencilRef, _In_ UINT BackStencilRef) +template +bool WrappedID3D12GraphicsCommandList::Serialise_OMSetFrontAndBackStencilRef(SerialiserType &ser, + UINT FrontStencilRef, + UINT BackStencilRef) { + ID3D12GraphicsCommandList8 *pCommandList = this; + SERIALISE_ELEMENT(pCommandList); + SERIALISE_ELEMENT(FrontStencilRef).Important(); + SERIALISE_ELEMENT(BackStencilRef).Important(); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + if(GetWrapped(pCommandList)->GetReal8() == NULL) + { + SET_ERROR_RESULT(m_Cmd->m_FailedReplayResult, ResultCode::APIHardwareUnsupported, + "Capture requires ID3D12GraphicsCommandList8 which isn't available"); + return false; + } + + m_Cmd->m_LastCmdListID = GetResourceManager()->GetOriginalID(GetResID(pCommandList)); + + bool stateUpdate = false; + + if(IsActiveReplaying(m_State)) + { + if(m_Cmd->InRerecordRange(m_Cmd->m_LastCmdListID)) + { + Unwrap8(m_Cmd->RerecordCmdList(m_Cmd->m_LastCmdListID)) + ->OMSetFrontAndBackStencilRef(FrontStencilRef, BackStencilRef); + + stateUpdate = true; + } + else if(!m_Cmd->IsPartialCmdList(m_Cmd->m_LastCmdListID)) + { + stateUpdate = true; + } + } + else + { + Unwrap8(pCommandList)->OMSetFrontAndBackStencilRef(FrontStencilRef, BackStencilRef); + GetCrackedList8()->OMSetFrontAndBackStencilRef(FrontStencilRef, BackStencilRef); + + stateUpdate = true; + } + + if(stateUpdate) + { + D3D12RenderState &rs = m_Cmd->m_BakedCmdListInfo[m_Cmd->m_LastCmdListID].state; + rs.stencilRefFront = FrontStencilRef; + rs.stencilRefBack = BackStencilRef; + } + } + + return true; } + +void STDMETHODCALLTYPE WrappedID3D12GraphicsCommandList::OMSetFrontAndBackStencilRef( + UINT FrontStencilRef, UINT BackStencilRef) +{ + SERIALISE_TIME_CALL(m_pList8->OMSetFrontAndBackStencilRef(FrontStencilRef, BackStencilRef)); + + if(IsCaptureMode(m_State)) + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D12Chunk::List_OMSetFrontAndBackStencilRef); + Serialise_OMSetFrontAndBackStencilRef(ser, FrontStencilRef, BackStencilRef); + + m_ListRecord->AddChunk(scope.Get(m_ListRecord->cmdInfo->alloc)); + } +} + +INSTANTIATE_FUNCTION_SERIALISED(void, WrappedID3D12GraphicsCommandList, OMSetFrontAndBackStencilRef, + UINT FrontStencilRef, UINT BackStencilRef); diff --git a/renderdoc/driver/d3d12/d3d12_command_list9_wrap.cpp b/renderdoc/driver/d3d12/d3d12_command_list9_wrap.cpp index 31449bd51..c4530c352 100644 --- a/renderdoc/driver/d3d12/d3d12_command_list9_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_command_list9_wrap.cpp @@ -24,12 +24,153 @@ #include "d3d12_command_list.h" -void STDMETHODCALLTYPE WrappedID3D12GraphicsCommandList::RSSetDepthBias( - _In_ FLOAT DepthBias, _In_ FLOAT DepthBiasClamp, _In_ FLOAT SlopeScaledDepthBias) +template +bool WrappedID3D12GraphicsCommandList::Serialise_RSSetDepthBias(SerialiserType &ser, FLOAT DepthBias, + FLOAT DepthBiasClamp, + FLOAT SlopeScaledDepthBias) { + ID3D12GraphicsCommandList9 *pCommandList = this; + SERIALISE_ELEMENT(pCommandList); + SERIALISE_ELEMENT(DepthBias).Important(); + SERIALISE_ELEMENT(DepthBiasClamp).Important(); + SERIALISE_ELEMENT(SlopeScaledDepthBias).Important(); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + if(GetWrapped(pCommandList)->GetReal9() == NULL) + { + SET_ERROR_RESULT(m_Cmd->m_FailedReplayResult, ResultCode::APIHardwareUnsupported, + "Capture requires ID3D12GraphicsCommandList9 which isn't available"); + return false; + } + + m_Cmd->m_LastCmdListID = GetResourceManager()->GetOriginalID(GetResID(pCommandList)); + + bool stateUpdate = false; + + if(IsActiveReplaying(m_State)) + { + if(m_Cmd->InRerecordRange(m_Cmd->m_LastCmdListID)) + { + Unwrap9(m_Cmd->RerecordCmdList(m_Cmd->m_LastCmdListID)) + ->RSSetDepthBias(DepthBias, DepthBiasClamp, SlopeScaledDepthBias); + + stateUpdate = true; + } + else if(!m_Cmd->IsPartialCmdList(m_Cmd->m_LastCmdListID)) + { + stateUpdate = true; + } + } + else + { + Unwrap9(pCommandList)->RSSetDepthBias(DepthBias, DepthBiasClamp, SlopeScaledDepthBias); + GetCrackedList9()->RSSetDepthBias(DepthBias, DepthBiasClamp, SlopeScaledDepthBias); + + stateUpdate = true; + } + + if(stateUpdate) + { + D3D12RenderState &rs = m_Cmd->m_BakedCmdListInfo[m_Cmd->m_LastCmdListID].state; + rs.depthBias = DepthBias; + rs.depthBiasClamp = DepthBiasClamp; + rs.slopeScaledDepthBias = SlopeScaledDepthBias; + } + } + + return true; +} + +void STDMETHODCALLTYPE WrappedID3D12GraphicsCommandList::RSSetDepthBias(FLOAT DepthBias, + FLOAT DepthBiasClamp, + FLOAT SlopeScaledDepthBias) +{ + SERIALISE_TIME_CALL(m_pList9->RSSetDepthBias(DepthBias, DepthBiasClamp, SlopeScaledDepthBias)); + + if(IsCaptureMode(m_State)) + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D12Chunk::List_RSSetDepthBias); + Serialise_RSSetDepthBias(ser, DepthBias, DepthBiasClamp, SlopeScaledDepthBias); + + m_ListRecord->AddChunk(scope.Get(m_ListRecord->cmdInfo->alloc)); + } +} + +template +bool WrappedID3D12GraphicsCommandList::Serialise_IASetIndexBufferStripCutValue( + SerialiserType &ser, D3D12_INDEX_BUFFER_STRIP_CUT_VALUE IBStripCutValue) +{ + ID3D12GraphicsCommandList9 *pCommandList = this; + SERIALISE_ELEMENT(pCommandList); + SERIALISE_ELEMENT(IBStripCutValue).Important(); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + if(GetWrapped(pCommandList)->GetReal9() == NULL) + { + SET_ERROR_RESULT(m_Cmd->m_FailedReplayResult, ResultCode::APIHardwareUnsupported, + "Capture requires ID3D12GraphicsCommandList9 which isn't available"); + return false; + } + + m_Cmd->m_LastCmdListID = GetResourceManager()->GetOriginalID(GetResID(pCommandList)); + + bool stateUpdate = false; + + if(IsActiveReplaying(m_State)) + { + if(m_Cmd->InRerecordRange(m_Cmd->m_LastCmdListID)) + { + Unwrap9(m_Cmd->RerecordCmdList(m_Cmd->m_LastCmdListID)) + ->IASetIndexBufferStripCutValue(IBStripCutValue); + + stateUpdate = true; + } + else if(!m_Cmd->IsPartialCmdList(m_Cmd->m_LastCmdListID)) + { + stateUpdate = true; + } + } + else + { + Unwrap9(pCommandList)->IASetIndexBufferStripCutValue(IBStripCutValue); + GetCrackedList9()->IASetIndexBufferStripCutValue(IBStripCutValue); + + stateUpdate = true; + } + + if(stateUpdate) + { + D3D12RenderState &rs = m_Cmd->m_BakedCmdListInfo[m_Cmd->m_LastCmdListID].state; + rs.cutValue = IBStripCutValue; + } + } + + return true; } void STDMETHODCALLTYPE WrappedID3D12GraphicsCommandList::IASetIndexBufferStripCutValue( - _In_ D3D12_INDEX_BUFFER_STRIP_CUT_VALUE IBStripCutValue) + D3D12_INDEX_BUFFER_STRIP_CUT_VALUE IBStripCutValue) { + SERIALISE_TIME_CALL(m_pList9->IASetIndexBufferStripCutValue(IBStripCutValue)); + + if(IsCaptureMode(m_State)) + { + CACHE_THREAD_SERIALISER(); + SCOPED_SERIALISE_CHUNK(D3D12Chunk::List_IASetIndexBufferStripCutValue); + Serialise_IASetIndexBufferStripCutValue(ser, IBStripCutValue); + + m_ListRecord->AddChunk(scope.Get(m_ListRecord->cmdInfo->alloc)); + } } + +INSTANTIATE_FUNCTION_SERIALISED(void, WrappedID3D12GraphicsCommandList, RSSetDepthBias, + FLOAT DepthBias, FLOAT DepthBiasClamp, FLOAT SlopeScaledDepthBias); +INSTANTIATE_FUNCTION_SERIALISED(void, WrappedID3D12GraphicsCommandList, IASetIndexBufferStripCutValue, + D3D12_INDEX_BUFFER_STRIP_CUT_VALUE IBStripCutValue); diff --git a/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp b/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp index 81197c480..37c79f6a2 100644 --- a/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_command_list_wrap.cpp @@ -310,6 +310,18 @@ bool WrappedID3D12GraphicsCommandList::Serialise_Reset(SerialiserType &ser, state.m_DebugManager = m_pDevice->GetDebugManager(); state.pipe = GetResID(pInitialState); + if(state.pipe != ResourceId()) + { + WrappedID3D12PipelineState *pipe = (WrappedID3D12PipelineState *)pInitialState; + if(pipe->IsGraphics()) + { + state.depthBias = pipe->graphics->RasterizerState.DepthBias; + state.depthBiasClamp = pipe->graphics->RasterizerState.DepthBiasClamp; + state.slopeScaledDepthBias = pipe->graphics->RasterizerState.SlopeScaledDepthBias; + state.cutValue = pipe->graphics->IBStripCutValue; + } + } + // whenever a command-building chunk asks for the command list, it // will get our baked version. if(GetResourceManager()->HasReplacement(CommandList)) @@ -406,6 +418,18 @@ bool WrappedID3D12GraphicsCommandList::Serialise_Reset(SerialiserType &ser, state.m_ResourceManager = GetResourceManager(); state.m_DebugManager = m_pDevice->GetDebugManager(); state.pipe = GetResID(pInitialState); + + if(state.pipe != ResourceId()) + { + WrappedID3D12PipelineState *pipe = (WrappedID3D12PipelineState *)pInitialState; + if(pipe->IsGraphics()) + { + state.depthBias = pipe->graphics->RasterizerState.DepthBias; + state.depthBiasClamp = pipe->graphics->RasterizerState.DepthBiasClamp; + state.slopeScaledDepthBias = pipe->graphics->RasterizerState.SlopeScaledDepthBias; + state.cutValue = pipe->graphics->IBStripCutValue; + } + } } } } @@ -676,6 +700,18 @@ bool WrappedID3D12GraphicsCommandList::Serialise_ClearState(SerialiserType &ser, state.m_DebugManager = m_pDevice->GetDebugManager(); state.m_ResourceManager = m_pDevice->GetResourceManager(); state.pipe = GetResID(pPipelineState); + + if(state.pipe != ResourceId()) + { + WrappedID3D12PipelineState *pipe = (WrappedID3D12PipelineState *)pPipelineState; + if(pipe->IsGraphics()) + { + state.depthBias = pipe->graphics->RasterizerState.DepthBias; + state.depthBiasClamp = pipe->graphics->RasterizerState.DepthBiasClamp; + state.slopeScaledDepthBias = pipe->graphics->RasterizerState.SlopeScaledDepthBias; + state.cutValue = pipe->graphics->IBStripCutValue; + } + } } } @@ -991,7 +1027,10 @@ bool WrappedID3D12GraphicsCommandList::Serialise_OMSetStencilRef(SerialiserType } if(stateUpdate) - m_Cmd->m_BakedCmdListInfo[m_Cmd->m_LastCmdListID].state.stencilRef = StencilRef; + { + D3D12RenderState &rs = m_Cmd->m_BakedCmdListInfo[m_Cmd->m_LastCmdListID].state; + rs.stencilRefFront = rs.stencilRefBack = StencilRef; + } } return true; @@ -1371,7 +1410,22 @@ bool WrappedID3D12GraphicsCommandList::Serialise_SetPipelineState(SerialiserType } if(stateUpdate) - m_Cmd->m_BakedCmdListInfo[m_Cmd->m_LastCmdListID].state.pipe = GetResID(pPipelineState); + { + D3D12RenderState &state = m_Cmd->m_BakedCmdListInfo[m_Cmd->m_LastCmdListID].state; + state.pipe = GetResID(pPipelineState); + + if(pPipelineState) + { + WrappedID3D12PipelineState *pipe = (WrappedID3D12PipelineState *)pPipelineState; + if(pipe->IsGraphics()) + { + state.depthBias = pipe->graphics->RasterizerState.DepthBias; + state.depthBiasClamp = pipe->graphics->RasterizerState.DepthBiasClamp; + state.slopeScaledDepthBias = pipe->graphics->RasterizerState.SlopeScaledDepthBias; + state.cutValue = pipe->graphics->IBStripCutValue; + } + } + } } return true; diff --git a/renderdoc/driver/d3d12/d3d12_commands.cpp b/renderdoc/driver/d3d12/d3d12_commands.cpp index fd36f30ac..20bd261d1 100644 --- a/renderdoc/driver/d3d12/d3d12_commands.cpp +++ b/renderdoc/driver/d3d12/d3d12_commands.cpp @@ -891,6 +891,16 @@ bool WrappedID3D12CommandQueue::ProcessChunk(ReadSerialiser &ser, D3D12Chunk chu case D3D12Chunk::List_RSSetShadingRateImage: ret = m_ReplayList->Serialise_RSSetShadingRateImage(ser, NULL); break; + case D3D12Chunk::List_OMSetFrontAndBackStencilRef: + ret = m_ReplayList->Serialise_OMSetFrontAndBackStencilRef(ser, 0, 0); + break; + case D3D12Chunk::List_RSSetDepthBias: + ret = m_ReplayList->Serialise_RSSetDepthBias(ser, 0.0f, 0.0f, 0.0f); + break; + case D3D12Chunk::List_IASetIndexBufferStripCutValue: + ret = m_ReplayList->Serialise_IASetIndexBufferStripCutValue( + ser, D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED); + break; case D3D12Chunk::PushMarker: ret = m_ReplayList->Serialise_BeginEvent(ser, 0, NULL, 0); break; case D3D12Chunk::PopMarker: ret = m_ReplayList->Serialise_EndEvent(ser); break; @@ -952,9 +962,6 @@ bool WrappedID3D12CommandQueue::ProcessChunk(ReadSerialiser &ser, D3D12Chunk chu case D3D12Chunk::Device_CreatePlacedResource2: case D3D12Chunk::Device_CreateReservedResource1: case D3D12Chunk::Device_CreateReservedResource2: - case D3D12Chunk::List_OMSetFrontAndBackStencilRef: - case D3D12Chunk::List_RSSetDepthBias: - case D3D12Chunk::List_IASetIndexBufferStripCutValue: RDCERR("Unexpected chunk while processing frame: %s", ToStr(chunk).c_str()); return false; @@ -1260,6 +1267,10 @@ WrappedID3D12GraphicsCommandList::WrappedID3D12GraphicsCommandList(ID3D12Graphic m_pList->QueryInterface(__uuidof(ID3D12GraphicsCommandList3), (void **)&m_pList3); m_pList->QueryInterface(__uuidof(ID3D12GraphicsCommandList4), (void **)&m_pList4); m_pList->QueryInterface(__uuidof(ID3D12GraphicsCommandList5), (void **)&m_pList5); + m_pList->QueryInterface(__uuidof(ID3D12GraphicsCommandList6), (void **)&m_pList6); + m_pList->QueryInterface(__uuidof(ID3D12GraphicsCommandList7), (void **)&m_pList7); + m_pList->QueryInterface(__uuidof(ID3D12GraphicsCommandList8), (void **)&m_pList8); + m_pList->QueryInterface(__uuidof(ID3D12GraphicsCommandList9), (void **)&m_pList9); } // create a temporary and grab its resource ID @@ -1337,6 +1348,10 @@ WrappedID3D12GraphicsCommandList::~WrappedID3D12GraphicsCommandList() SAFE_RELEASE(m_WrappedDebug.m_pReal1); SAFE_RELEASE(m_WrappedDebug.m_pReal2); SAFE_RELEASE(m_WrappedDebug.m_pReal3); + SAFE_RELEASE(m_pList9); + SAFE_RELEASE(m_pList8); + SAFE_RELEASE(m_pList7); + SAFE_RELEASE(m_pList6); SAFE_RELEASE(m_pList5); SAFE_RELEASE(m_pList4); SAFE_RELEASE(m_pList3); diff --git a/renderdoc/driver/d3d12/d3d12_common.cpp b/renderdoc/driver/d3d12/d3d12_common.cpp index f420ba539..dbc759057 100644 --- a/renderdoc/driver/d3d12/d3d12_common.cpp +++ b/renderdoc/driver/d3d12/d3d12_common.cpp @@ -244,6 +244,10 @@ bool D3D12InitParams::IsSupportedVersion(uint64_t ver) if(ver == 0xE) return true; + // 0xF -> 0x10 - Expanded PSO desc is serialised with new rasterizer/depth-stencil descs + if(ver == 0xF) + return true; + return false; } @@ -882,6 +886,76 @@ rdcstr PIX3DecodeEventString(const UINT64 *pData, UINT64 &color) return formatString; } +D3D12_DEPTH_STENCILOP_DESC1 Upconvert(const D3D12_DEPTH_STENCILOP_DESC &face) +{ + D3D12_DEPTH_STENCILOP_DESC1 ret = {}; + + ret.StencilFunc = face.StencilFunc; + ret.StencilPassOp = face.StencilPassOp; + ret.StencilFailOp = face.StencilFailOp; + ret.StencilDepthFailOp = face.StencilDepthFailOp; + + return ret; +} + +D3D12_DEPTH_STENCILOP_DESC Downconvert(const D3D12_DEPTH_STENCILOP_DESC1 &face) +{ + D3D12_DEPTH_STENCILOP_DESC ret; + + ret.StencilFunc = face.StencilFunc; + ret.StencilPassOp = face.StencilPassOp; + ret.StencilFailOp = face.StencilFailOp; + ret.StencilDepthFailOp = face.StencilDepthFailOp; + + return ret; +} + +D3D12_DEPTH_STENCIL_DESC2 Upconvert(const D3D12_DEPTH_STENCIL_DESC1 &desc) +{ + D3D12_DEPTH_STENCIL_DESC2 DepthStencilState; + + DepthStencilState.DepthBoundsTestEnable = desc.DepthBoundsTestEnable; + DepthStencilState.DepthEnable = desc.DepthEnable; + DepthStencilState.DepthFunc = desc.DepthFunc; + DepthStencilState.DepthWriteMask = desc.DepthWriteMask; + DepthStencilState.StencilEnable = desc.StencilEnable; + DepthStencilState.FrontFace = Upconvert(desc.FrontFace); + DepthStencilState.BackFace = Upconvert(desc.BackFace); + + // duplicate this across both faces when it's not independent + DepthStencilState.FrontFace.StencilReadMask = desc.StencilReadMask; + DepthStencilState.FrontFace.StencilWriteMask = desc.StencilWriteMask; + DepthStencilState.BackFace.StencilReadMask = desc.StencilReadMask; + DepthStencilState.BackFace.StencilWriteMask = desc.StencilWriteMask; + + return DepthStencilState; +} + +D3D12_RASTERIZER_DESC2 Upconvert(const D3D12_RASTERIZER_DESC &desc) +{ + D3D12_RASTERIZER_DESC2 + RasterizerState; + + RasterizerState.FillMode = desc.FillMode; + RasterizerState.CullMode = desc.CullMode; + RasterizerState.FrontCounterClockwise = desc.FrontCounterClockwise; + RasterizerState.DepthBias = FLOAT(desc.DepthBias); + RasterizerState.DepthBiasClamp = desc.DepthBiasClamp; + RasterizerState.SlopeScaledDepthBias = desc.SlopeScaledDepthBias; + RasterizerState.DepthClipEnable = desc.DepthClipEnable; + RasterizerState.ForcedSampleCount = desc.ForcedSampleCount; + RasterizerState.ConservativeRaster = desc.ConservativeRaster; + + if(desc.MultisampleEnable) + RasterizerState.LineRasterizationMode = D3D12_LINE_RASTERIZATION_MODE_QUADRILATERAL_WIDE; + else if(desc.AntialiasedLineEnable) + RasterizerState.LineRasterizationMode = D3D12_LINE_RASTERIZATION_MODE_ALPHA_ANTIALIASED; + else + RasterizerState.LineRasterizationMode = D3D12_LINE_RASTERIZATION_MODE_ALIASED; + + return RasterizerState; +} + D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC::D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC( const D3D12_GRAPHICS_PIPELINE_STATE_DESC &graphics) { @@ -894,16 +968,40 @@ D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC::D3D12_EXPANDED_PIPELINE_STATE_STREAM_ StreamOutput = graphics.StreamOutput; BlendState = graphics.BlendState; SampleMask = graphics.SampleMask; - RasterizerState = graphics.RasterizerState; + + { + RasterizerState.FillMode = graphics.RasterizerState.FillMode; + RasterizerState.CullMode = graphics.RasterizerState.CullMode; + RasterizerState.FrontCounterClockwise = graphics.RasterizerState.FrontCounterClockwise; + RasterizerState.DepthBias = FLOAT(graphics.RasterizerState.DepthBias); + RasterizerState.DepthBiasClamp = graphics.RasterizerState.DepthBiasClamp; + RasterizerState.SlopeScaledDepthBias = graphics.RasterizerState.SlopeScaledDepthBias; + RasterizerState.DepthClipEnable = graphics.RasterizerState.DepthClipEnable; + RasterizerState.ForcedSampleCount = graphics.RasterizerState.ForcedSampleCount; + RasterizerState.ConservativeRaster = graphics.RasterizerState.ConservativeRaster; + + if(graphics.RasterizerState.MultisampleEnable) + RasterizerState.LineRasterizationMode = D3D12_LINE_RASTERIZATION_MODE_QUADRILATERAL_WIDE; + else if(graphics.RasterizerState.AntialiasedLineEnable) + RasterizerState.LineRasterizationMode = D3D12_LINE_RASTERIZATION_MODE_ALPHA_ANTIALIASED; + else + RasterizerState.LineRasterizationMode = D3D12_LINE_RASTERIZATION_MODE_ALIASED; + } + { DepthStencilState.DepthEnable = graphics.DepthStencilState.DepthEnable; DepthStencilState.DepthWriteMask = graphics.DepthStencilState.DepthWriteMask; DepthStencilState.DepthFunc = graphics.DepthStencilState.DepthFunc; DepthStencilState.StencilEnable = graphics.DepthStencilState.StencilEnable; - DepthStencilState.StencilReadMask = graphics.DepthStencilState.StencilReadMask; - DepthStencilState.StencilWriteMask = graphics.DepthStencilState.StencilWriteMask; - DepthStencilState.FrontFace = graphics.DepthStencilState.FrontFace; - DepthStencilState.BackFace = graphics.DepthStencilState.BackFace; + + DepthStencilState.FrontFace = Upconvert(graphics.DepthStencilState.FrontFace); + DepthStencilState.BackFace = Upconvert(graphics.DepthStencilState.BackFace); + + // this is not separate, so duplicate it + DepthStencilState.FrontFace.StencilReadMask = graphics.DepthStencilState.StencilReadMask; + DepthStencilState.FrontFace.StencilWriteMask = graphics.DepthStencilState.StencilWriteMask; + DepthStencilState.BackFace.StencilReadMask = graphics.DepthStencilState.StencilReadMask; + DepthStencilState.BackFace.StencilWriteMask = graphics.DepthStencilState.StencilWriteMask; // DepthBounds defaults to disabled DepthStencilState.DepthBoundsTestEnable = FALSE; @@ -953,8 +1051,11 @@ struct D3D12_U32_PSO_SUBOBJECT UINT NodeMask; D3D12_BLEND_DESC BlendState; D3D12_RASTERIZER_DESC RasterizerState; + D3D12_RASTERIZER_DESC1 RasterizerState1; + D3D12_RASTERIZER_DESC2 RasterizerState2; D3D12_DEPTH_STENCIL_DESC DepthStencilState; D3D12_DEPTH_STENCIL_DESC1 DepthStencilState1; + D3D12_DEPTH_STENCIL_DESC2 DepthStencilState2; D3D12_INDEX_BUFFER_STRIP_CUT_VALUE IBStripCutValue; D3D12_PRIMITIVE_TOPOLOGY_TYPE PrimitiveTopologyType; D3D12_RT_FORMAT_ARRAY RTVFormats; @@ -1016,8 +1117,7 @@ D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC::D3D12_EXPANDED_PIPELINE_STATE_STREAM_ RasterizerState.DepthBiasClamp = 0.0f; RasterizerState.SlopeScaledDepthBias = 0.0f; RasterizerState.DepthClipEnable = TRUE; - RasterizerState.MultisampleEnable = FALSE; - RasterizerState.AntialiasedLineEnable = FALSE; + RasterizerState.LineRasterizationMode = D3D12_LINE_RASTERIZATION_MODE_ALIASED; RasterizerState.ForcedSampleCount = 0; RasterizerState.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF; @@ -1046,16 +1146,14 @@ D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC::D3D12_EXPANDED_PIPELINE_STATE_STREAM_ DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_LESS; DepthStencilState.StencilEnable = FALSE; - DepthStencilState.StencilReadMask = D3D12_DEFAULT_STENCIL_READ_MASK; - DepthStencilState.StencilWriteMask = D3D12_DEFAULT_STENCIL_WRITE_MASK; - DepthStencilState.FrontFace.StencilFunc = DepthStencilState.BackFace.StencilFunc = - D3D12_COMPARISON_FUNC_ALWAYS; - DepthStencilState.FrontFace.StencilDepthFailOp = DepthStencilState.BackFace.StencilDepthFailOp = - D3D12_STENCIL_OP_KEEP; - DepthStencilState.FrontFace.StencilPassOp = DepthStencilState.BackFace.StencilPassOp = - D3D12_STENCIL_OP_KEEP; - DepthStencilState.FrontFace.StencilFailOp = DepthStencilState.BackFace.StencilFailOp = - D3D12_STENCIL_OP_KEEP; + DepthStencilState.FrontFace.StencilReadMask = D3D12_DEFAULT_STENCIL_READ_MASK; + DepthStencilState.FrontFace.StencilWriteMask = D3D12_DEFAULT_STENCIL_WRITE_MASK; + DepthStencilState.FrontFace.StencilFunc = D3D12_COMPARISON_FUNC_ALWAYS; + DepthStencilState.FrontFace.StencilDepthFailOp = D3D12_STENCIL_OP_KEEP; + DepthStencilState.FrontFace.StencilPassOp = D3D12_STENCIL_OP_KEEP; + DepthStencilState.FrontFace.StencilFailOp = D3D12_STENCIL_OP_KEEP; + + DepthStencilState.BackFace = DepthStencilState.FrontFace; // DepthBounds defaults to disabled DepthStencilState.DepthBoundsTestEnable = FALSE; @@ -1152,10 +1250,40 @@ D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC::D3D12_EXPANDED_PIPELINE_STATE_STREAM_ } case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RASTERIZER: { - RasterizerState = u32->data.RasterizerState; + RasterizerState = Upconvert(u32->data.RasterizerState); + ITER_ADV(D3D12_RASTERIZER_DESC); break; } + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RASTERIZER1: + { + RasterizerState.FillMode = u32->data.RasterizerState1.FillMode; + RasterizerState.CullMode = u32->data.RasterizerState1.CullMode; + RasterizerState.FrontCounterClockwise = u32->data.RasterizerState1.FrontCounterClockwise; + RasterizerState.DepthBias = FLOAT(u32->data.RasterizerState1.DepthBias); + RasterizerState.DepthBiasClamp = u32->data.RasterizerState1.DepthBiasClamp; + RasterizerState.SlopeScaledDepthBias = u32->data.RasterizerState1.SlopeScaledDepthBias; + RasterizerState.DepthClipEnable = u32->data.RasterizerState1.DepthClipEnable; + RasterizerState.ForcedSampleCount = u32->data.RasterizerState1.ForcedSampleCount; + RasterizerState.ConservativeRaster = u32->data.RasterizerState1.ConservativeRaster; + + if(u32->data.RasterizerState1.MultisampleEnable) + RasterizerState.LineRasterizationMode = D3D12_LINE_RASTERIZATION_MODE_QUADRILATERAL_WIDE; + else if(u32->data.RasterizerState1.AntialiasedLineEnable) + RasterizerState.LineRasterizationMode = D3D12_LINE_RASTERIZATION_MODE_ALPHA_ANTIALIASED; + else + RasterizerState.LineRasterizationMode = D3D12_LINE_RASTERIZATION_MODE_ALIASED; + + ITER_ADV(D3D12_RASTERIZER_DESC1); + break; + } + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RASTERIZER2: + { + RasterizerState = u32->data.RasterizerState2; + + ITER_ADV(D3D12_RASTERIZER_DESC2); + break; + } case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL: { const D3D12_DEPTH_STENCIL_DESC &dsdesc = u32->data.DepthStencilState; @@ -1163,10 +1291,14 @@ D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC::D3D12_EXPANDED_PIPELINE_STATE_STREAM_ DepthStencilState.DepthWriteMask = dsdesc.DepthWriteMask; DepthStencilState.DepthFunc = dsdesc.DepthFunc; DepthStencilState.StencilEnable = dsdesc.StencilEnable; - DepthStencilState.StencilReadMask = dsdesc.StencilReadMask; - DepthStencilState.StencilWriteMask = dsdesc.StencilWriteMask; - DepthStencilState.FrontFace = dsdesc.FrontFace; - DepthStencilState.BackFace = dsdesc.BackFace; + DepthStencilState.FrontFace = Upconvert(dsdesc.FrontFace); + DepthStencilState.BackFace = Upconvert(dsdesc.BackFace); + + // duplicate this across both faces when it's not independent + DepthStencilState.FrontFace.StencilReadMask = dsdesc.StencilReadMask; + DepthStencilState.FrontFace.StencilWriteMask = dsdesc.StencilWriteMask; + DepthStencilState.BackFace.StencilReadMask = dsdesc.StencilReadMask; + DepthStencilState.BackFace.StencilWriteMask = dsdesc.StencilWriteMask; SeenDSS = true; ITER_ADV(D3D12_DEPTH_STENCIL_DESC); break; @@ -1230,11 +1362,19 @@ D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC::D3D12_EXPANDED_PIPELINE_STATE_STREAM_ } case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL1: { - DepthStencilState = u32->data.DepthStencilState1; + DepthStencilState = Upconvert(u32->data.DepthStencilState1); + SeenDSS = true; ITER_ADV(D3D12_DEPTH_STENCIL_DESC1); break; } + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL2: + { + DepthStencilState = u32->data.DepthStencilState2; + SeenDSS = true; + ITER_ADV(D3D12_DEPTH_STENCIL_DESC2); + break; + } case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_VIEW_INSTANCING: { ViewInstancing = ptr->data.ViewInstancing; @@ -1299,8 +1439,6 @@ D3D12_PACKED_PIPELINE_STATE_STREAM_DESC &D3D12_PACKED_PIPELINE_STATE_STREAM_DESC m_GraphicsStreamData.StreamOutput = expanded.StreamOutput; m_GraphicsStreamData.BlendState = expanded.BlendState; m_GraphicsStreamData.SampleMask = expanded.SampleMask; - m_GraphicsStreamData.RasterizerState = expanded.RasterizerState; - m_GraphicsStreamData.DepthStencilState = expanded.DepthStencilState; m_GraphicsStreamData.InputLayout = expanded.InputLayout; m_GraphicsStreamData.IBStripCutValue = expanded.IBStripCutValue; m_GraphicsStreamData.PrimitiveTopologyType = expanded.PrimitiveTopologyType; @@ -1311,6 +1449,133 @@ D3D12_PACKED_PIPELINE_STATE_STREAM_DESC &D3D12_PACKED_PIPELINE_STATE_STREAM_DESC m_GraphicsStreamData.CachedPSO = expanded.CachedPSO; m_GraphicsStreamData.Flags = expanded.Flags; m_GraphicsStreamData.ViewInstancing = expanded.ViewInstancing; + + byte *ptr = m_GraphicsStreamData.VariableVersionedData; + const byte *start = ptr; + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE type; + +#define WRITE_VERSIONED_SUBOJBECT(subobjType, subobj) \ + type = subobjType; \ + memcpy(ptr, &type, sizeof(type)); \ + ptr += sizeof(type); \ + ptr = AlignUpPtr(ptr, alignof(decltype(subobj))); \ + memcpy(ptr, &subobj, sizeof(subobj)); \ + ptr += sizeof(subobj); \ + ptr = AlignUpPtr(ptr, sizeof(void *)); + + // is the line rasterization mode narrow quadrilateral? if so we need version 2. + if(expanded.RasterizerState.LineRasterizationMode == + D3D12_LINE_RASTERIZATION_MODE_QUADRILATERAL_NARROW) + { + WRITE_VERSIONED_SUBOJBECT(D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RASTERIZER2, + expanded.RasterizerState); + } + // otherwise is the depth bias not an int? then we need version 1 + else if(FLOAT(INT(expanded.RasterizerState.DepthBias)) != expanded.RasterizerState.DepthBias) + { + D3D12_RASTERIZER_DESC1 desc1; + + desc1.FillMode = expanded.RasterizerState.FillMode; + desc1.CullMode = expanded.RasterizerState.CullMode; + desc1.FrontCounterClockwise = expanded.RasterizerState.FrontCounterClockwise; + desc1.DepthBias = expanded.RasterizerState.DepthBias; + desc1.DepthBiasClamp = expanded.RasterizerState.DepthBiasClamp; + desc1.SlopeScaledDepthBias = expanded.RasterizerState.SlopeScaledDepthBias; + desc1.DepthClipEnable = expanded.RasterizerState.DepthClipEnable; + desc1.ForcedSampleCount = expanded.RasterizerState.ForcedSampleCount; + desc1.ConservativeRaster = expanded.RasterizerState.ConservativeRaster; + + switch(expanded.RasterizerState.LineRasterizationMode) + { + case D3D12_LINE_RASTERIZATION_MODE_ALIASED: + desc1.MultisampleEnable = FALSE; + desc1.AntialiasedLineEnable = FALSE; + break; + case D3D12_LINE_RASTERIZATION_MODE_ALPHA_ANTIALIASED: + desc1.MultisampleEnable = FALSE; + desc1.AntialiasedLineEnable = TRUE; + break; + case D3D12_LINE_RASTERIZATION_MODE_QUADRILATERAL_WIDE: + case D3D12_LINE_RASTERIZATION_MODE_QUADRILATERAL_NARROW: + desc1.MultisampleEnable = TRUE; + desc1.AntialiasedLineEnable = FALSE; + break; + default: + desc1.MultisampleEnable = FALSE; + desc1.AntialiasedLineEnable = FALSE; + break; + } + + WRITE_VERSIONED_SUBOJBECT(D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RASTERIZER1, desc1); + } + // if neither of those, we can use the old version + else + { + D3D12_RASTERIZER_DESC desc; + + desc.FillMode = expanded.RasterizerState.FillMode; + desc.CullMode = expanded.RasterizerState.CullMode; + desc.FrontCounterClockwise = expanded.RasterizerState.FrontCounterClockwise; + desc.DepthBias = INT(expanded.RasterizerState.DepthBias); + desc.DepthBiasClamp = expanded.RasterizerState.DepthBiasClamp; + desc.SlopeScaledDepthBias = expanded.RasterizerState.SlopeScaledDepthBias; + desc.DepthClipEnable = expanded.RasterizerState.DepthClipEnable; + desc.ForcedSampleCount = expanded.RasterizerState.ForcedSampleCount; + desc.ConservativeRaster = expanded.RasterizerState.ConservativeRaster; + + switch(expanded.RasterizerState.LineRasterizationMode) + { + case D3D12_LINE_RASTERIZATION_MODE_ALIASED: + desc.MultisampleEnable = FALSE; + desc.AntialiasedLineEnable = FALSE; + break; + case D3D12_LINE_RASTERIZATION_MODE_ALPHA_ANTIALIASED: + desc.MultisampleEnable = FALSE; + desc.AntialiasedLineEnable = TRUE; + break; + case D3D12_LINE_RASTERIZATION_MODE_QUADRILATERAL_WIDE: + case D3D12_LINE_RASTERIZATION_MODE_QUADRILATERAL_NARROW: + desc.MultisampleEnable = TRUE; + desc.AntialiasedLineEnable = FALSE; + break; + default: + desc.MultisampleEnable = FALSE; + desc.AntialiasedLineEnable = FALSE; + break; + } + + WRITE_VERSIONED_SUBOJBECT(D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RASTERIZER, desc); + } + + // do we have separate stencil masks? if so use the new type of D/S desc. Otherwise use the old + // one to ensure we don't fail when the new one isn't supported + if(expanded.DepthStencilState.StencilEnable && + (expanded.DepthStencilState.FrontFace.StencilReadMask != + expanded.DepthStencilState.FrontFace.StencilReadMask || + expanded.DepthStencilState.BackFace.StencilWriteMask != + expanded.DepthStencilState.BackFace.StencilWriteMask)) + { + WRITE_VERSIONED_SUBOJBECT(D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL2, + expanded.DepthStencilState); + } + else + { + D3D12_DEPTH_STENCIL_DESC1 desc1; + + desc1.DepthEnable = expanded.DepthStencilState.DepthEnable; + desc1.DepthFunc = expanded.DepthStencilState.DepthFunc; + desc1.DepthBoundsTestEnable = expanded.DepthStencilState.DepthBoundsTestEnable; + desc1.DepthWriteMask = expanded.DepthStencilState.DepthWriteMask; + desc1.StencilEnable = expanded.DepthStencilState.StencilEnable; + desc1.FrontFace = Downconvert(expanded.DepthStencilState.FrontFace); + desc1.BackFace = Downconvert(expanded.DepthStencilState.BackFace); + desc1.StencilReadMask = expanded.DepthStencilState.FrontFace.StencilReadMask; + desc1.StencilWriteMask = expanded.DepthStencilState.FrontFace.StencilWriteMask; + + WRITE_VERSIONED_SUBOJBECT(D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL1, desc1); + } + + m_VariableVersionedDataLength = ptr - start; } return *this; diff --git a/renderdoc/driver/d3d12/d3d12_common.h b/renderdoc/driver/d3d12/d3d12_common.h index 9ddb7ee98..e0b8dca23 100644 --- a/renderdoc/driver/d3d12/d3d12_common.h +++ b/renderdoc/driver/d3d12/d3d12_common.h @@ -141,6 +141,9 @@ StencilOperation MakeStencilOp(D3D12_STENCIL_OP op); // buffer replay is happening #define VERBOSE_PARTIAL_REPLAY OPTION_OFF +D3D12_DEPTH_STENCIL_DESC2 Upconvert(const D3D12_DEPTH_STENCIL_DESC1 &desc); +D3D12_RASTERIZER_DESC2 Upconvert(const D3D12_RASTERIZER_DESC &desc); + ShaderStageMask ConvertVisibility(D3D12_SHADER_VISIBILITY ShaderVisibility); UINT GetNumSubresources(ID3D12Device *dev, const D3D12_RESOURCE_DESC *desc); @@ -471,8 +474,8 @@ struct D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC D3D12_STREAM_OUTPUT_DESC StreamOutput = {}; D3D12_BLEND_DESC BlendState = {}; UINT SampleMask = 0; - D3D12_RASTERIZER_DESC RasterizerState = {}; - D3D12_DEPTH_STENCIL_DESC1 DepthStencilState = {}; + D3D12_RASTERIZER_DESC2 RasterizerState = {}; + D3D12_DEPTH_STENCIL_DESC2 DepthStencilState = {}; D3D12_INPUT_LAYOUT_DESC InputLayout = {}; D3D12_INDEX_BUFFER_STRIP_CUT_VALUE IBStripCutValue; D3D12_PRIMITIVE_TOPOLOGY_TYPE PrimitiveTopologyType; @@ -525,7 +528,8 @@ public: else { m_StreamDesc.pPipelineStateSubobjectStream = &m_GraphicsStreamData; - m_StreamDesc.SizeInBytes = sizeof(m_GraphicsStreamData); + m_StreamDesc.SizeInBytes = + offsetof(GraphicsStreamData, VariableVersionedData) + m_VariableVersionedDataLength; return &m_StreamDesc; } } @@ -541,7 +545,7 @@ public: } private: - struct + struct GraphicsStreamData { // graphics properties SUBOBJECT_HEADER(ROOT_SIGNATURE); @@ -564,8 +568,6 @@ private: D3D12_CACHED_PIPELINE_STATE CachedPSO = {}; SUBOBJECT_HEADER(VIEW_INSTANCING); D3D12_VIEW_INSTANCING_DESC ViewInstancing = {}; - SUBOBJECT_HEADER(RASTERIZER); - D3D12_RASTERIZER_DESC RasterizerState = {}; SUBOBJECT_HEADER(RENDER_TARGET_FORMATS); D3D12_RT_FORMAT_ARRAY RTVFormats = {}; SUBOBJECT_HEADER(DEPTH_STENCIL_FORMAT); @@ -580,20 +582,27 @@ private: UINT SampleMask = 0; SUBOBJECT_HEADER(FLAGS); D3D12_PIPELINE_STATE_FLAGS Flags = D3D12_PIPELINE_STATE_FLAG_NONE; - SUBOBJECT_HEADER(DEPTH_STENCIL1); - D3D12_DEPTH_STENCIL_DESC1 DepthStencilState = {}; -#if ENABLED(RDOC_X64) - UINT pad0; -#endif SUBOBJECT_HEADER(BLEND); D3D12_BLEND_DESC BlendState = {}; #if ENABLED(RDOC_X64) - UINT pad1; + UINT pad0; #endif SUBOBJECT_HEADER(SAMPLE_DESC); DXGI_SAMPLE_DESC SampleDesc = {}; +#if ENABLED(RDOC_X64) + UINT pad1; +#endif + // since data must be tightly packed, the final structs that are versioned and may not be + // supported are pushed in here + byte alignas(void *) VariableVersionedData[ + // depth-stencil is versioned for separate stencil masks + sizeof(D3D12_DEPTH_STENCIL_DESC2) + sizeof(void *) + + // rasterization is versioned for line raster mode + sizeof(D3D12_RASTERIZER_DESC2) + sizeof(void *)]; } m_GraphicsStreamData; + size_t m_VariableVersionedDataLength; + struct { // compute properties @@ -661,6 +670,7 @@ DECLARE_REFLECTION_ENUM(D3D12_COLOR_WRITE_ENABLE); DECLARE_REFLECTION_ENUM(D3D12_DEPTH_WRITE_MASK); DECLARE_REFLECTION_ENUM(D3D12_VIEW_INSTANCING_FLAGS); DECLARE_REFLECTION_ENUM(D3D12_RESOLVE_MODE); +DECLARE_REFLECTION_ENUM(D3D12_LINE_RASTERIZATION_MODE); DECLARE_REFLECTION_ENUM(D3D12_WRITEBUFFERIMMEDIATE_MODE); DECLARE_REFLECTION_ENUM(D3D12_COMMAND_LIST_FLAGS); DECLARE_REFLECTION_ENUM(D3D12_RENDER_PASS_FLAGS); @@ -686,8 +696,13 @@ DECLARE_REFLECTION_STRUCT(D3D12_SHADER_BYTECODE); DECLARE_REFLECTION_STRUCT(D3D12_SO_DECLARATION_ENTRY); DECLARE_REFLECTION_STRUCT(D3D12_STREAM_OUTPUT_DESC); DECLARE_REFLECTION_STRUCT(D3D12_RASTERIZER_DESC); +DECLARE_REFLECTION_STRUCT(D3D12_RASTERIZER_DESC1); +DECLARE_REFLECTION_STRUCT(D3D12_RASTERIZER_DESC2); DECLARE_REFLECTION_STRUCT(D3D12_DEPTH_STENCILOP_DESC); +DECLARE_REFLECTION_STRUCT(D3D12_DEPTH_STENCILOP_DESC1); DECLARE_REFLECTION_STRUCT(D3D12_DEPTH_STENCIL_DESC); +DECLARE_REFLECTION_STRUCT(D3D12_DEPTH_STENCIL_DESC1); +DECLARE_REFLECTION_STRUCT(D3D12_DEPTH_STENCIL_DESC2); DECLARE_REFLECTION_STRUCT(D3D12_INPUT_ELEMENT_DESC); DECLARE_REFLECTION_STRUCT(D3D12_INPUT_LAYOUT_DESC); DECLARE_REFLECTION_STRUCT(D3D12_RENDER_TARGET_BLEND_DESC); @@ -760,7 +775,6 @@ DECLARE_REFLECTION_STRUCT(D3D12_RECT); DECLARE_REFLECTION_STRUCT(D3D12_BOX); DECLARE_REFLECTION_STRUCT(D3D12_VIEWPORT); DECLARE_REFLECTION_STRUCT(D3D12_RT_FORMAT_ARRAY); -DECLARE_REFLECTION_STRUCT(D3D12_DEPTH_STENCIL_DESC1); DECLARE_REFLECTION_STRUCT(D3D12_VIEW_INSTANCE_LOCATION); DECLARE_REFLECTION_STRUCT(D3D12_VIEW_INSTANCING_DESC); DECLARE_REFLECTION_STRUCT(D3D12_SAMPLE_POSITION); diff --git a/renderdoc/driver/d3d12/d3d12_device.cpp b/renderdoc/driver/d3d12/d3d12_device.cpp index 67f6c61a4..5b5da28d1 100644 --- a/renderdoc/driver/d3d12/d3d12_device.cpp +++ b/renderdoc/driver/d3d12/d3d12_device.cpp @@ -526,6 +526,9 @@ WrappedID3D12Device::WrappedID3D12Device(ID3D12Device *realDevice, D3D12InitPara RDCEraseEl(m_D3D12Opts2); RDCEraseEl(m_D3D12Opts3); RDCEraseEl(m_D3D12Opts6); + RDCEraseEl(m_D3D12Opts14); + RDCEraseEl(m_D3D12Opts15); + RDCEraseEl(m_D3D12Opts16); m_pDevice1 = NULL; m_pDevice2 = NULL; @@ -592,6 +595,18 @@ WrappedID3D12Device::WrappedID3D12Device(ID3D12Device *realDevice, D3D12InitPara sizeof(m_D3D12Opts6)); if(hr != S_OK) RDCEraseEl(m_D3D12Opts6); + hr = m_pDevice->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS14, &m_D3D12Opts14, + sizeof(m_D3D12Opts14)); + if(hr != S_OK) + RDCEraseEl(m_D3D12Opts14); + hr = m_pDevice->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS14, &m_D3D12Opts15, + sizeof(m_D3D12Opts15)); + if(hr != S_OK) + RDCEraseEl(m_D3D12Opts15); + hr = m_pDevice->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS14, &m_D3D12Opts16, + sizeof(m_D3D12Opts16)); + if(hr != S_OK) + RDCEraseEl(m_D3D12Opts16); } // refcounters implicitly construct with one reference, but we don't start with any soft @@ -3077,17 +3092,67 @@ HRESULT WrappedID3D12Device::CreatePipeState(D3D12_EXPANDED_PIPELINE_STATE_STREA graphicsDesc.StreamOutput = desc.StreamOutput; graphicsDesc.BlendState = desc.BlendState; graphicsDesc.SampleMask = desc.SampleMask; - graphicsDesc.RasterizerState = desc.RasterizerState; + + // graphicsDesc.RasterizerState = desc.RasterizerState; + { + graphicsDesc.RasterizerState.FillMode = desc.RasterizerState.FillMode; + graphicsDesc.RasterizerState.CullMode = desc.RasterizerState.CullMode; + graphicsDesc.RasterizerState.FrontCounterClockwise = desc.RasterizerState.FrontCounterClockwise; + graphicsDesc.RasterizerState.DepthBias = INT(desc.RasterizerState.DepthBias); + graphicsDesc.RasterizerState.DepthBiasClamp = desc.RasterizerState.DepthBiasClamp; + graphicsDesc.RasterizerState.SlopeScaledDepthBias = desc.RasterizerState.SlopeScaledDepthBias; + graphicsDesc.RasterizerState.DepthClipEnable = desc.RasterizerState.DepthClipEnable; + graphicsDesc.RasterizerState.ForcedSampleCount = desc.RasterizerState.ForcedSampleCount; + graphicsDesc.RasterizerState.ConservativeRaster = desc.RasterizerState.ConservativeRaster; + + switch(desc.RasterizerState.LineRasterizationMode) + { + case D3D12_LINE_RASTERIZATION_MODE_ALIASED: + graphicsDesc.RasterizerState.MultisampleEnable = FALSE; + graphicsDesc.RasterizerState.AntialiasedLineEnable = FALSE; + break; + case D3D12_LINE_RASTERIZATION_MODE_ALPHA_ANTIALIASED: + graphicsDesc.RasterizerState.MultisampleEnable = FALSE; + graphicsDesc.RasterizerState.AntialiasedLineEnable = TRUE; + break; + case D3D12_LINE_RASTERIZATION_MODE_QUADRILATERAL_WIDE: + case D3D12_LINE_RASTERIZATION_MODE_QUADRILATERAL_NARROW: + graphicsDesc.RasterizerState.MultisampleEnable = TRUE; + graphicsDesc.RasterizerState.AntialiasedLineEnable = FALSE; + break; + default: + graphicsDesc.RasterizerState.MultisampleEnable = FALSE; + graphicsDesc.RasterizerState.AntialiasedLineEnable = FALSE; + break; + } + } + // graphicsDesc.DepthStencilState = desc.DepthStencilState; { graphicsDesc.DepthStencilState.DepthEnable = desc.DepthStencilState.DepthEnable; graphicsDesc.DepthStencilState.DepthWriteMask = desc.DepthStencilState.DepthWriteMask; graphicsDesc.DepthStencilState.DepthFunc = desc.DepthStencilState.DepthFunc; graphicsDesc.DepthStencilState.StencilEnable = desc.DepthStencilState.StencilEnable; - graphicsDesc.DepthStencilState.StencilReadMask = desc.DepthStencilState.StencilReadMask; - graphicsDesc.DepthStencilState.StencilWriteMask = desc.DepthStencilState.StencilWriteMask; - graphicsDesc.DepthStencilState.FrontFace = desc.DepthStencilState.FrontFace; - graphicsDesc.DepthStencilState.BackFace = desc.DepthStencilState.BackFace; + graphicsDesc.DepthStencilState.StencilReadMask = + desc.DepthStencilState.FrontFace.StencilReadMask; + graphicsDesc.DepthStencilState.StencilWriteMask = + desc.DepthStencilState.FrontFace.StencilWriteMask; + graphicsDesc.DepthStencilState.FrontFace.StencilFunc = + desc.DepthStencilState.FrontFace.StencilFunc; + graphicsDesc.DepthStencilState.FrontFace.StencilPassOp = + desc.DepthStencilState.FrontFace.StencilPassOp; + graphicsDesc.DepthStencilState.FrontFace.StencilFailOp = + desc.DepthStencilState.FrontFace.StencilFailOp; + graphicsDesc.DepthStencilState.FrontFace.StencilDepthFailOp = + desc.DepthStencilState.FrontFace.StencilDepthFailOp; + graphicsDesc.DepthStencilState.BackFace.StencilFunc = + desc.DepthStencilState.BackFace.StencilFunc; + graphicsDesc.DepthStencilState.BackFace.StencilPassOp = + desc.DepthStencilState.BackFace.StencilPassOp; + graphicsDesc.DepthStencilState.BackFace.StencilFailOp = + desc.DepthStencilState.BackFace.StencilFailOp; + graphicsDesc.DepthStencilState.BackFace.StencilDepthFailOp = + desc.DepthStencilState.BackFace.StencilDepthFailOp; // no DepthBoundsTestEnable } graphicsDesc.InputLayout = desc.InputLayout; diff --git a/renderdoc/driver/d3d12/d3d12_device.h b/renderdoc/driver/d3d12/d3d12_device.h index b9d298b0f..f0759c071 100644 --- a/renderdoc/driver/d3d12/d3d12_device.h +++ b/renderdoc/driver/d3d12/d3d12_device.h @@ -54,7 +54,7 @@ struct D3D12InitParams UINT SDKVersion = 0; // check if a frame capture section version is supported - static const uint64_t CurrentVersion = 0xF; + static const uint64_t CurrentVersion = 0x10; static bool IsSupportedVersion(uint64_t ver); }; @@ -785,6 +785,9 @@ private: D3D12_FEATURE_DATA_D3D12_OPTIONS2 m_D3D12Opts2; D3D12_FEATURE_DATA_D3D12_OPTIONS3 m_D3D12Opts3; D3D12_FEATURE_DATA_D3D12_OPTIONS6 m_D3D12Opts6; + D3D12_FEATURE_DATA_D3D12_OPTIONS14 m_D3D12Opts14; + D3D12_FEATURE_DATA_D3D12_OPTIONS15 m_D3D12Opts15; + D3D12_FEATURE_DATA_D3D12_OPTIONS16 m_D3D12Opts16; UINT m_DescriptorIncrements[D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES]; template @@ -816,6 +819,9 @@ public: const D3D12_FEATURE_DATA_D3D12_OPTIONS2 &GetOpts2() { return m_D3D12Opts2; } const D3D12_FEATURE_DATA_D3D12_OPTIONS3 &GetOpts3() { return m_D3D12Opts3; } const D3D12_FEATURE_DATA_D3D12_OPTIONS6 &GetOpts6() { return m_D3D12Opts6; } + const D3D12_FEATURE_DATA_D3D12_OPTIONS14 &GetOpts14() { return m_D3D12Opts14; } + const D3D12_FEATURE_DATA_D3D12_OPTIONS15 &GetOpts15() { return m_D3D12Opts15; } + const D3D12_FEATURE_DATA_D3D12_OPTIONS16 &GetOpts16() { return m_D3D12Opts16; } void RemoveQueue(WrappedID3D12CommandQueue *queue); // only valid on replay diff --git a/renderdoc/driver/d3d12/d3d12_overlay.cpp b/renderdoc/driver/d3d12/d3d12_overlay.cpp index 15fca182f..b207c0cca 100644 --- a/renderdoc/driver/d3d12/d3d12_overlay.cpp +++ b/renderdoc/driver/d3d12/d3d12_overlay.cpp @@ -142,7 +142,8 @@ struct D3D12QuadOverdrawCallback : public D3D12ActionCallback pipeDesc.DepthStencilState.BackFace.StencilPassOp = D3D12_STENCIL_OP_KEEP; pipeDesc.DepthStencilState.BackFace.StencilFailOp = D3D12_STENCIL_OP_KEEP; pipeDesc.DepthStencilState.BackFace.StencilDepthFailOp = D3D12_STENCIL_OP_KEEP; - pipeDesc.DepthStencilState.StencilWriteMask = 0; + pipeDesc.DepthStencilState.FrontFace.StencilWriteMask = 0; + pipeDesc.DepthStencilState.BackFace.StencilWriteMask = 0; // disable any multisampling pipeDesc.SampleDesc.Count = 1; @@ -1226,8 +1227,7 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De psoDesc.RasterizerState.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP; psoDesc.RasterizerState.SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; psoDesc.RasterizerState.DepthClipEnable = FALSE; - psoDesc.RasterizerState.MultisampleEnable = FALSE; - psoDesc.RasterizerState.AntialiasedLineEnable = FALSE; + psoDesc.RasterizerState.LineRasterizationMode = D3D12_LINE_RASTERIZATION_MODE_ALIASED; float clearColour[] = {0.0f, 0.0f, 0.0f, 0.5f}; list->ClearRenderTargetView(rtv, clearColour, 0, NULL); @@ -1316,8 +1316,7 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De psoDesc.RasterizerState.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP; psoDesc.RasterizerState.SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; psoDesc.RasterizerState.DepthClipEnable = FALSE; - psoDesc.RasterizerState.MultisampleEnable = FALSE; - psoDesc.RasterizerState.AntialiasedLineEnable = FALSE; + psoDesc.RasterizerState.LineRasterizationMode = D3D12_LINE_RASTERIZATION_MODE_ALIASED; float clearColour[] = {0.0f, 0.0f, 0.0f, 0.0f}; list->ClearRenderTargetView(rtv, clearColour, 0, NULL); @@ -1424,8 +1423,7 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De psoDesc.RasterizerState.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP; psoDesc.RasterizerState.SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; psoDesc.RasterizerState.DepthClipEnable = FALSE; - psoDesc.RasterizerState.MultisampleEnable = FALSE; - psoDesc.RasterizerState.AntialiasedLineEnable = FALSE; + psoDesc.RasterizerState.LineRasterizationMode = D3D12_LINE_RASTERIZATION_MODE_ALIASED; float wireClearCol[4] = {200.0f / 255.0f, 255.0f / 255.0f, 0.0f / 255.0f, 0.0f}; list->ClearRenderTargetView(rtv, wireClearCol, 0, NULL); @@ -1581,8 +1579,7 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De psoDesc.RasterizerState.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP; psoDesc.RasterizerState.SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; psoDesc.RasterizerState.DepthClipEnable = FALSE; - psoDesc.RasterizerState.MultisampleEnable = FALSE; - psoDesc.RasterizerState.AntialiasedLineEnable = FALSE; + psoDesc.RasterizerState.LineRasterizationMode = D3D12_LINE_RASTERIZATION_MODE_ALIASED; psoDesc.PS.pShaderBytecode = red->GetBufferPointer(); psoDesc.PS.BytecodeLength = red->GetBufferSize(); @@ -2163,8 +2160,7 @@ ResourceId D3D12Replay::RenderOverlay(ResourceId texid, FloatVector clearCol, De psoDesc.BlendState.RenderTarget[0].LogicOpEnable = FALSE; psoDesc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID; - psoDesc.RasterizerState.MultisampleEnable = FALSE; - psoDesc.RasterizerState.AntialiasedLineEnable = FALSE; + psoDesc.RasterizerState.LineRasterizationMode = D3D12_LINE_RASTERIZATION_MODE_ALIASED; float clearColour[] = {0.0f, 0.0f, 0.0f, 0.0f}; list->ClearRenderTargetView(rtv, clearColour, 0, NULL); diff --git a/renderdoc/driver/d3d12/d3d12_replay.cpp b/renderdoc/driver/d3d12/d3d12_replay.cpp index bb6311817..38d9d8e7f 100644 --- a/renderdoc/driver/d3d12/d3d12_replay.cpp +++ b/renderdoc/driver/d3d12/d3d12_replay.cpp @@ -1800,9 +1800,24 @@ void D3D12Replay::SavePipelineState(uint32_t eventId) { D3D12Pipe::RasterizerState &dst = state.rasterizer.state; - D3D12_RASTERIZER_DESC &src = pipe->graphics->RasterizerState; + D3D12_RASTERIZER_DESC2 &src = pipe->graphics->RasterizerState; - dst.antialiasedLines = src.AntialiasedLineEnable == TRUE; + switch(src.LineRasterizationMode) + { + case D3D12_LINE_RASTERIZATION_MODE_ALIASED: + dst.lineRasterMode = LineRaster::Bresenham; + break; + case D3D12_LINE_RASTERIZATION_MODE_ALPHA_ANTIALIASED: + dst.lineRasterMode = LineRaster::RectangularSmooth; + break; + case D3D12_LINE_RASTERIZATION_MODE_QUADRILATERAL_WIDE: + dst.lineRasterMode = LineRaster::RectangularD3D; + break; + case D3D12_LINE_RASTERIZATION_MODE_QUADRILATERAL_NARROW: + dst.lineRasterMode = LineRaster::Rectangular; + break; + default: dst.lineRasterMode = LineRaster::Default; break; + } dst.cullMode = CullMode::NoCull; if(src.CullMode == D3D12_CULL_MODE_FRONT) @@ -1818,7 +1833,6 @@ void D3D12Replay::SavePipelineState(uint32_t eventId) dst.depthBiasClamp = src.DepthBiasClamp; dst.depthClip = src.DepthClipEnable == TRUE; dst.frontCCW = src.FrontCounterClockwise == TRUE; - dst.multisampleEnable = src.MultisampleEnable == TRUE; dst.slopeScaledDepthBias = src.SlopeScaledDepthBias; dst.forcedSampleCount = src.ForcedSampleCount; @@ -1940,7 +1954,7 @@ void D3D12Replay::SavePipelineState(uint32_t eventId) } { - D3D12_DEPTH_STENCIL_DESC1 &src = pipe->graphics->DepthStencilState; + D3D12_DEPTH_STENCIL_DESC2 &src = pipe->graphics->DepthStencilState; state.outputMerger.depthStencilState.depthEnable = src.DepthEnable == TRUE; state.outputMerger.depthStencilState.depthFunction = MakeCompareFunc(src.DepthFunc); @@ -1960,6 +1974,9 @@ void D3D12Replay::SavePipelineState(uint32_t eventId) MakeStencilOp(src.FrontFace.StencilPassOp); state.outputMerger.depthStencilState.frontFace.failOperation = MakeStencilOp(src.FrontFace.StencilFailOp); + state.outputMerger.depthStencilState.frontFace.reference = rs.stencilRefFront; + state.outputMerger.depthStencilState.frontFace.compareMask = src.FrontFace.StencilReadMask; + state.outputMerger.depthStencilState.frontFace.writeMask = src.FrontFace.StencilWriteMask; state.outputMerger.depthStencilState.backFace.function = MakeCompareFunc(src.BackFace.StencilFunc); @@ -1969,15 +1986,9 @@ void D3D12Replay::SavePipelineState(uint32_t eventId) MakeStencilOp(src.BackFace.StencilPassOp); state.outputMerger.depthStencilState.backFace.failOperation = MakeStencilOp(src.BackFace.StencilFailOp); - - // due to shared structs, this is slightly duplicated - D3D doesn't have separate states for - // front/back. - state.outputMerger.depthStencilState.frontFace.reference = rs.stencilRef; - state.outputMerger.depthStencilState.frontFace.compareMask = src.StencilReadMask; - state.outputMerger.depthStencilState.frontFace.writeMask = src.StencilWriteMask; - state.outputMerger.depthStencilState.backFace.reference = rs.stencilRef; - state.outputMerger.depthStencilState.backFace.compareMask = src.StencilReadMask; - state.outputMerger.depthStencilState.backFace.writeMask = src.StencilWriteMask; + state.outputMerger.depthStencilState.backFace.reference = rs.stencilRefBack; + state.outputMerger.depthStencilState.backFace.compareMask = src.BackFace.StencilReadMask; + state.outputMerger.depthStencilState.backFace.writeMask = src.BackFace.StencilWriteMask; } } diff --git a/renderdoc/driver/d3d12/d3d12_serialise.cpp b/renderdoc/driver/d3d12/d3d12_serialise.cpp index e73189fb2..628c17723 100644 --- a/renderdoc/driver/d3d12/d3d12_serialise.cpp +++ b/renderdoc/driver/d3d12/d3d12_serialise.cpp @@ -506,8 +506,29 @@ void DoSerialise(SerialiserType &ser, D3D12_EXPANDED_PIPELINE_STATE_STREAM_DESC SERIALISE_MEMBER(StreamOutput); SERIALISE_MEMBER(BlendState); SERIALISE_MEMBER(SampleMask); - SERIALISE_MEMBER(RasterizerState); - SERIALISE_MEMBER(DepthStencilState); + + if(ser.VersionAtLeast(0x10)) + { + SERIALISE_MEMBER(RasterizerState); + } + else + { + D3D12_RASTERIZER_DESC oldState; + ser.Serialise("RasterizerState"_lit, oldState); + el.RasterizerState = Upconvert(oldState); + } + + if(ser.VersionAtLeast(0x10)) + { + SERIALISE_MEMBER(DepthStencilState); + } + else + { + D3D12_DEPTH_STENCIL_DESC1 oldState; + ser.Serialise("DepthStencilState"_lit, oldState); + el.DepthStencilState = Upconvert(oldState); + } + SERIALISE_MEMBER(InputLayout); SERIALISE_MEMBER(IBStripCutValue); SERIALISE_MEMBER(PrimitiveTopologyType); @@ -678,6 +699,37 @@ void DoSerialise(SerialiserType &ser, D3D12_RASTERIZER_DESC &el) SERIALISE_MEMBER(ConservativeRaster); } +template +void DoSerialise(SerialiserType &ser, D3D12_RASTERIZER_DESC1 &el) +{ + SERIALISE_MEMBER(FillMode); + SERIALISE_MEMBER(CullMode); + SERIALISE_MEMBER(FrontCounterClockwise); + SERIALISE_MEMBER(DepthBias); + SERIALISE_MEMBER(DepthBiasClamp); + SERIALISE_MEMBER(SlopeScaledDepthBias); + SERIALISE_MEMBER(DepthClipEnable); + SERIALISE_MEMBER(MultisampleEnable); + SERIALISE_MEMBER(AntialiasedLineEnable); + SERIALISE_MEMBER(ForcedSampleCount); + SERIALISE_MEMBER(ConservativeRaster); +} + +template +void DoSerialise(SerialiserType &ser, D3D12_RASTERIZER_DESC2 &el) +{ + SERIALISE_MEMBER(FillMode); + SERIALISE_MEMBER(CullMode); + SERIALISE_MEMBER(FrontCounterClockwise); + SERIALISE_MEMBER(DepthBias); + SERIALISE_MEMBER(DepthBiasClamp); + SERIALISE_MEMBER(SlopeScaledDepthBias); + SERIALISE_MEMBER(DepthClipEnable); + SERIALISE_MEMBER(LineRasterizationMode); + SERIALISE_MEMBER(ForcedSampleCount); + SERIALISE_MEMBER(ConservativeRaster); +} + template void DoSerialise(SerialiserType &ser, D3D12_DEPTH_STENCILOP_DESC &el) { @@ -692,7 +744,7 @@ void DoSerialise(SerialiserType &ser, D3D12_DEPTH_STENCIL_DESC &el) { SERIALISE_MEMBER(DepthEnable); SERIALISE_MEMBER(DepthWriteMask); - SERIALISE_MEMBER(DepthFunc); + SERIALISE_MEMBER(DepthFunc).Important(); SERIALISE_MEMBER(StencilEnable); SERIALISE_MEMBER(StencilReadMask); SERIALISE_MEMBER(StencilWriteMask); @@ -700,6 +752,43 @@ void DoSerialise(SerialiserType &ser, D3D12_DEPTH_STENCIL_DESC &el) SERIALISE_MEMBER(BackFace); } +template +void DoSerialise(SerialiserType &ser, D3D12_DEPTH_STENCIL_DESC1 &el) +{ + SERIALISE_MEMBER(DepthEnable); + SERIALISE_MEMBER(DepthWriteMask); + SERIALISE_MEMBER(DepthFunc).Important(); + SERIALISE_MEMBER(StencilEnable); + SERIALISE_MEMBER(StencilReadMask); + SERIALISE_MEMBER(StencilWriteMask); + SERIALISE_MEMBER(FrontFace); + SERIALISE_MEMBER(BackFace); + SERIALISE_MEMBER(DepthBoundsTestEnable); +} + +template +void DoSerialise(SerialiserType &ser, D3D12_DEPTH_STENCILOP_DESC1 &el) +{ + SERIALISE_MEMBER(StencilFailOp); + SERIALISE_MEMBER(StencilDepthFailOp); + SERIALISE_MEMBER(StencilPassOp); + SERIALISE_MEMBER(StencilFunc); + SERIALISE_MEMBER(StencilReadMask); + SERIALISE_MEMBER(StencilWriteMask); +} + +template +void DoSerialise(SerialiserType &ser, D3D12_DEPTH_STENCIL_DESC2 &el) +{ + SERIALISE_MEMBER(DepthEnable); + SERIALISE_MEMBER(DepthWriteMask); + SERIALISE_MEMBER(DepthFunc); + SERIALISE_MEMBER(StencilEnable); + SERIALISE_MEMBER(FrontFace); + SERIALISE_MEMBER(BackFace); + SERIALISE_MEMBER(DepthBoundsTestEnable); +} + template void DoSerialise(SerialiserType &ser, D3D12_INPUT_ELEMENT_DESC &el) { @@ -1456,20 +1545,6 @@ void DoSerialise(SerialiserType &ser, D3D12_RT_FORMAT_ARRAY &el) SERIALISE_MEMBER(NumRenderTargets); } -template -void DoSerialise(SerialiserType &ser, D3D12_DEPTH_STENCIL_DESC1 &el) -{ - SERIALISE_MEMBER(DepthEnable); - SERIALISE_MEMBER(DepthWriteMask); - SERIALISE_MEMBER(DepthFunc).Important(); - SERIALISE_MEMBER(StencilEnable); - SERIALISE_MEMBER(StencilReadMask); - SERIALISE_MEMBER(StencilWriteMask); - SERIALISE_MEMBER(FrontFace); - SERIALISE_MEMBER(BackFace); - SERIALISE_MEMBER(DepthBoundsTestEnable); -} - template void DoSerialise(SerialiserType &ser, D3D12_VIEW_INSTANCE_LOCATION &el) { @@ -1686,7 +1761,11 @@ INSTANTIATE_SERIALISE_TYPE(D3D12_BOX); INSTANTIATE_SERIALISE_TYPE(D3D12_VIEWPORT); INSTANTIATE_SERIALISE_TYPE(D3D12_PIPELINE_STATE_STREAM_DESC); INSTANTIATE_SERIALISE_TYPE(D3D12_RT_FORMAT_ARRAY); +INSTANTIATE_SERIALISE_TYPE(D3D12_RASTERIZER_DESC); +INSTANTIATE_SERIALISE_TYPE(D3D12_RASTERIZER_DESC1); +INSTANTIATE_SERIALISE_TYPE(D3D12_RASTERIZER_DESC2); INSTANTIATE_SERIALISE_TYPE(D3D12_DEPTH_STENCIL_DESC1); +INSTANTIATE_SERIALISE_TYPE(D3D12_DEPTH_STENCIL_DESC2); INSTANTIATE_SERIALISE_TYPE(D3D12_VIEW_INSTANCING_DESC); INSTANTIATE_SERIALISE_TYPE(D3D12_SAMPLE_POSITION); INSTANTIATE_SERIALISE_TYPE(D3D12_SUBRESOURCE_RANGE_UINT64); diff --git a/renderdoc/driver/d3d12/d3d12_state.cpp b/renderdoc/driver/d3d12/d3d12_state.cpp index 3abbdaea2..04f114537 100644 --- a/renderdoc/driver/d3d12/d3d12_state.cpp +++ b/renderdoc/driver/d3d12/d3d12_state.cpp @@ -80,7 +80,11 @@ void D3D12RenderState::ApplyState(WrappedID3D12Device *dev, ID3D12GraphicsComman if(topo != D3D_PRIMITIVE_TOPOLOGY_UNDEFINED) cmd->IASetPrimitiveTopology(topo); - cmd->OMSetStencilRef(stencilRef); + if(stencilRefFront != stencilRefBack && GetWrapped(cmd)->GetReal8() && + dev->GetOpts14().IndependentFrontAndBackStencilRefMaskSupported) + cmd->OMSetFrontAndBackStencilRef(stencilRefFront, stencilRefBack); + else + cmd->OMSetStencilRef(stencilRefFront); cmd->OMSetBlendFactor(blendFactor); if(GetWrapped(cmd)->GetReal1()) @@ -114,6 +118,19 @@ void D3D12RenderState::ApplyState(WrappedID3D12Device *dev, ID3D12GraphicsComman } } + if(GetWrapped(cmd)->GetReal9()) + { + if(dev->GetOpts15().DynamicIndexBufferStripCutSupported) + { + cmd->IASetIndexBufferStripCutValue(cutValue); + } + + if(dev->GetOpts16().DynamicDepthBiasSupported) + { + cmd->RSSetDepthBias(depthBias, depthBiasClamp, slopeScaledDepthBias); + } + } + if(ibuffer.buf != ResourceId()) { D3D12_INDEX_BUFFER_VIEW ib; diff --git a/renderdoc/driver/d3d12/d3d12_state.h b/renderdoc/driver/d3d12/d3d12_state.h index 82b31d3a4..aea776478 100644 --- a/renderdoc/driver/d3d12/d3d12_state.h +++ b/renderdoc/driver/d3d12/d3d12_state.h @@ -68,6 +68,9 @@ struct D3D12RenderState rdcarray GetRTVIDs() const; ResourceId GetDSVID() const; + float depthBias = 0.0f, depthBiasClamp = 0.0f, slopeScaledDepthBias = 0.0f; + D3D12_INDEX_BUFFER_STRIP_CUT_VALUE cutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_DISABLED; + ResourceId shadingRateImage; D3D12_SHADING_RATE shadingRate; D3D12_SHADING_RATE_COMBINER shadingRateCombiners[2]; @@ -188,7 +191,7 @@ struct D3D12RenderState } samplePos; D3D12_PRIMITIVE_TOPOLOGY topo = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; - UINT stencilRef = 0; + UINT stencilRefFront = 0, stencilRefBack = 0; float blendFactor[4] = {}; float depthBoundsMin = 0.0f, depthBoundsMax = 1.0f; diff --git a/renderdoc/driver/d3d12/d3d12_stringise.cpp b/renderdoc/driver/d3d12/d3d12_stringise.cpp index 51d7031f1..3287624c3 100644 --- a/renderdoc/driver/d3d12/d3d12_stringise.cpp +++ b/renderdoc/driver/d3d12/d3d12_stringise.cpp @@ -938,6 +938,19 @@ rdcstr DoStringise(const D3D12_DESCRIPTOR_RANGE_TYPE &el) END_ENUM_STRINGISE(); } +template <> +rdcstr DoStringise(const D3D12_LINE_RASTERIZATION_MODE &el) +{ + BEGIN_ENUM_STRINGISE(D3D12_LINE_RASTERIZATION_MODE); + { + STRINGISE_ENUM(D3D12_LINE_RASTERIZATION_MODE_ALIASED) + STRINGISE_ENUM(D3D12_LINE_RASTERIZATION_MODE_ALPHA_ANTIALIASED) + STRINGISE_ENUM(D3D12_LINE_RASTERIZATION_MODE_QUADRILATERAL_WIDE) + STRINGISE_ENUM(D3D12_LINE_RASTERIZATION_MODE_QUADRILATERAL_NARROW) + } + END_ENUM_STRINGISE(); +} + template <> rdcstr DoStringise(const D3D12_CLEAR_FLAGS &el) { diff --git a/renderdoc/replay/renderdoc_serialise.inl b/renderdoc/replay/renderdoc_serialise.inl index 1ba30421c..62e7da180 100644 --- a/renderdoc/replay/renderdoc_serialise.inl +++ b/renderdoc/replay/renderdoc_serialise.inl @@ -1505,8 +1505,7 @@ void DoSerialise(SerialiserType &ser, D3D12Pipe::RasterizerState &el) SERIALISE_MEMBER(depthBiasClamp); SERIALISE_MEMBER(slopeScaledDepthBias); SERIALISE_MEMBER(depthClip); - SERIALISE_MEMBER(multisampleEnable); - SERIALISE_MEMBER(antialiasedLines); + SERIALISE_MEMBER(lineRasterMode); SERIALISE_MEMBER(forcedSampleCount); SERIALISE_MEMBER(conservativeRasterization); SERIALISE_MEMBER(baseShadingRate);