From fe0a8c55e6aa83c72453a17d5013773cc6f00ae5 Mon Sep 17 00:00:00 2001 From: baldurk Date: Fri, 8 May 2026 14:07:59 +0100 Subject: [PATCH] Add some extra accessors of state to common pipeline state abstraction --- .../python_api/renderdoc/pipelines/common.rst | 10 +- renderdoc/api/replay/common_pipestate.h | 68 +++++++++ renderdoc/api/replay/pipestate.h | 32 +++++ renderdoc/api/replay/pipestate.inl | 129 ++++++++++++++++++ 4 files changed, 237 insertions(+), 2 deletions(-) diff --git a/docs/python_api/renderdoc/pipelines/common.rst b/docs/python_api/renderdoc/pipelines/common.rst index 03475a8dd..c3a502e59 100644 --- a/docs/python_api/renderdoc/pipelines/common.rst +++ b/docs/python_api/renderdoc/pipelines/common.rst @@ -101,9 +101,15 @@ Rasterizer .. autoclass:: renderdoc.ShadingRateCombiner :members: +.. autoclass:: renderdoc.RasterState + :members: -Stencil -------- + +Depth and Stencil +----------------- + +.. autoclass:: renderdoc.DepthTestState + :members: .. autoclass:: renderdoc.StencilFace :members: diff --git a/renderdoc/api/replay/common_pipestate.h b/renderdoc/api/replay/common_pipestate.h index 8f6a4afbf..4a095e73b 100644 --- a/renderdoc/api/replay/common_pipestate.h +++ b/renderdoc/api/replay/common_pipestate.h @@ -270,6 +270,74 @@ struct ColorBlend DECLARE_REFLECTION_STRUCT(ColorBlend); +DOCUMENT("Describes a common subset of rasterizing state."); +struct RasterState +{ + DOCUMENT(""); + RasterState() = default; + RasterState(const RasterState &) = default; + RasterState &operator=(const RasterState &) = default; + + DOCUMENT(R"(``True`` if counter-clockwise polygons are front-facing. +``False`` if clockwise polygons are front-facing. + +:type: bool +)"); + bool frontCCW = false; + + DOCUMENT(R"(The polygon :class:`FillMode`. + +:type: FillMode +)"); + FillMode fillMode = FillMode::Solid; + + DOCUMENT(R"(The polygon :class:`CullMode`. + +:type: CullMode +)"); + CullMode cullMode = CullMode::NoCull; +}; + +DOCUMENT("Describes a common subset of depth testing state."); +struct DepthTestState +{ + DOCUMENT(""); + DepthTestState() = default; + DepthTestState(const DepthTestState &) = default; + DepthTestState &operator=(const DepthTestState &) = default; + + DOCUMENT(R"(``True`` if depth testing should be performed. + +:type: bool +)"); + bool depthEnable = false; + DOCUMENT(R"(The :class:`CompareFunction` to use for testing depth values. + +:type: CompareFunction +)"); + CompareFunction depthFunction = CompareFunction::AlwaysTrue; + DOCUMENT(R"(``True`` if depth values should be written to the depth target. + +:type: bool +)"); + bool depthWrites = false; + DOCUMENT(R"(``True`` if depth bounds tests should be applied. + +:type: bool +)"); + bool depthBounds = false; + DOCUMENT(R"(The near plane bounding value. + +:type: float +)"); + double minDepthBounds = 0.0; + DOCUMENT(R"(The far plane bounding value. + +:type: float +)"); + double maxDepthBounds = 0.0; +}; + DOCUMENT("Describes the details of a stencil operation."); struct StencilFace { diff --git a/renderdoc/api/replay/pipestate.h b/renderdoc/api/replay/pipestate.h index 6e3165178..61a7d7159 100644 --- a/renderdoc/api/replay/pipestate.h +++ b/renderdoc/api/replay/pipestate.h @@ -432,6 +432,20 @@ convenience of access. )"); rdcarray GetColorBlends() const; + DOCUMENT(R"(Retrieves the current fixed blend factor. + +:return: The currently fixed blend factor. +:rtype: Tuple[float,float,float,float] +)"); + rdcfixedarray GetBlendFactor() const; + + DOCUMENT(R"(Checks whether stencil operations are enabled or not. + +:return: The currently stencil states. Front facing first, back facing second. +:rtype: Tuple[StencilFace, StencilFace] +)"); + bool IsStencilTestEnabled() const; + DOCUMENT(R"(Retrieves the current stencil states. :return: The currently stencil states. Front facing first, back facing second. @@ -439,6 +453,24 @@ convenience of access. )"); rdcpair GetStencilFaces() const; + DOCUMENT(R"(Retrieves some of the depth testing state. + +This doesn't contain all properties from all APIs but a common subset. + +:return: The currently depth testing state. +:rtype: DepthTestState +)"); + DepthTestState GetDepthTestState() const; + + DOCUMENT(R"(Retrieves some of the rasterizer state. + +This doesn't contain all properties from all APIs but a common subset. + +:return: The currently depth testing state. +:rtype: RasterState +)"); + RasterState GetRasterState() const; + DOCUMENT(R"(Determines whether or not independent blending is enabled. :return: A boolean indicating if independent blending is enabled. diff --git a/renderdoc/api/replay/pipestate.inl b/renderdoc/api/replay/pipestate.inl index 93403add5..d8d91b874 100644 --- a/renderdoc/api/replay/pipestate.inl +++ b/renderdoc/api/replay/pipestate.inl @@ -1194,6 +1194,110 @@ rdcarray PipeState::GetOutputTargets() const return ret; } +rdcfixedarray PipeState::GetBlendFactor() const +{ + if(IsCaptureLoaded()) + { + if(IsCaptureD3D11()) + { + return m_D3D11->outputMerger.blendState.blendFactor; + } + else if(IsCaptureD3D12()) + { + return m_D3D12->outputMerger.blendState.blendFactor; + } + else if(IsCaptureGL()) + { + return m_GL->framebuffer.blendState.blendFactor; + } + else if(IsCaptureVK()) + { + return m_Vulkan->colorBlend.blendFactor; + } + } + + return {}; +} + +DepthTestState PipeState::GetDepthTestState() const +{ + DepthTestState ret = {}; + + if(IsCaptureLoaded()) + { + if(IsCaptureD3D11()) + { + ret.depthEnable = m_D3D11->outputMerger.depthStencilState.depthEnable; + ret.depthWrites = m_D3D11->outputMerger.depthStencilState.depthWrites; + ret.depthFunction = m_D3D11->outputMerger.depthStencilState.depthFunction; + } + else if(IsCaptureD3D12()) + { + ret.depthEnable = m_D3D12->outputMerger.depthStencilState.depthEnable; + ret.depthWrites = m_D3D12->outputMerger.depthStencilState.depthWrites; + ret.depthFunction = m_D3D12->outputMerger.depthStencilState.depthFunction; + ret.depthBounds = m_D3D12->outputMerger.depthStencilState.depthBoundsEnable; + ret.minDepthBounds = m_D3D12->outputMerger.depthStencilState.minDepthBounds; + ret.maxDepthBounds = m_D3D12->outputMerger.depthStencilState.maxDepthBounds; + } + else if(IsCaptureGL()) + { + ret.depthEnable = m_GL->depthState.depthEnable; + ret.depthWrites = m_GL->depthState.depthWrites; + ret.depthFunction = m_GL->depthState.depthFunction; + ret.depthBounds = m_GL->depthState.depthBounds; + ret.minDepthBounds = m_GL->depthState.nearBound; + ret.maxDepthBounds = m_GL->depthState.farBound; + } + else if(IsCaptureVK()) + { + ret.depthEnable = m_Vulkan->depthStencil.depthTestEnable; + ret.depthWrites = m_Vulkan->depthStencil.depthWriteEnable; + ret.depthFunction = m_Vulkan->depthStencil.depthFunction; + ret.depthBounds = m_Vulkan->depthStencil.depthBoundsEnable; + ret.minDepthBounds = m_Vulkan->depthStencil.minDepthBounds; + ret.maxDepthBounds = m_Vulkan->depthStencil.maxDepthBounds; + } + } + + return ret; +} + +RasterState PipeState::GetRasterState() const +{ + RasterState ret = {}; + + if(IsCaptureLoaded()) + { + if(IsCaptureD3D11()) + { + ret.cullMode = m_D3D11->rasterizer.state.cullMode; + ret.fillMode = m_D3D11->rasterizer.state.fillMode; + ret.frontCCW = m_D3D11->rasterizer.state.frontCCW; + } + else if(IsCaptureD3D12()) + { + ret.cullMode = m_D3D12->rasterizer.state.cullMode; + ret.fillMode = m_D3D12->rasterizer.state.fillMode; + ret.frontCCW = m_D3D12->rasterizer.state.frontCCW; + } + else if(IsCaptureGL()) + { + ret.cullMode = m_GL->rasterizer.state.cullMode; + ret.fillMode = m_GL->rasterizer.state.fillMode; + ret.frontCCW = m_GL->rasterizer.state.frontCCW; + } + else if(IsCaptureVK()) + { + ret.cullMode = m_Vulkan->rasterizer.cullMode; + ret.fillMode = m_Vulkan->rasterizer.fillMode; + ret.frontCCW = m_Vulkan->rasterizer.frontCCW; + } + } + + return ret; +} + rdcarray PipeState::GetColorBlends() const { if(IsCaptureLoaded()) @@ -1231,6 +1335,31 @@ rdcarray PipeState::GetColorBlends() const return {}; } +bool PipeState::IsStencilTestEnabled() const +{ + if(IsCaptureLoaded()) + { + if(IsCaptureD3D11()) + { + return m_D3D11->outputMerger.depthStencilState.stencilEnable; + } + else if(IsCaptureD3D12()) + { + return m_D3D12->outputMerger.depthStencilState.stencilEnable; + } + else if(IsCaptureGL()) + { + return m_GL->stencilState.stencilEnable; + } + else if(IsCaptureVK()) + { + return m_Vulkan->depthStencil.stencilTestEnable; + } + } + + return false; +} + rdcpair PipeState::GetStencilFaces() const { if(IsCaptureLoaded())