diff --git a/docs/python_api/examples/renderdoc/decode_mesh.py b/docs/python_api/examples/renderdoc/decode_mesh.py index 574b67015..c214eda9b 100644 --- a/docs/python_api/examples/renderdoc/decode_mesh.py +++ b/docs/python_api/examples/renderdoc/decode_mesh.py @@ -64,14 +64,12 @@ def unpackData(fmt, data): # Get a list of MeshData objects describing the vertex inputs at this draw def getMeshInputs(controller, draw): - # This work is API-specific, but the APIs have a lot of similarities. - # Here we implement support for D3D11 since it's relatively simple - state = controller.GetD3D11PipelineState() + state = controller.GetPipelineState() # Get the index & vertex buffers, and fixed vertex inputs - ib = state.inputAssembly.indexBuffer - vbs = state.inputAssembly.vertexBuffers - attrs = state.inputAssembly.layouts + ib = state.GetIBuffer() + vbs = state.GetVBuffers() + attrs = state.GetVertexInputs() meshInputs = [] @@ -94,13 +92,11 @@ def getMeshInputs(controller, draw): meshInput.indexResourceId = rd.ResourceId.Null() # The total offset is the attribute offset from the base of the vertex - meshInput.vertexByteOffset = attr.byteOffset + vbs[attr.inputSlot].byteOffset + meshInput.vertexByteOffset = attr.byteOffset + vbs[attr.vertexBuffer].byteOffset meshInput.format = attr.format - meshInput.vertexResourceId = vbs[attr.inputSlot].resourceId - meshInput.vertexByteStride = vbs[attr.inputSlot].byteStride - - # We don't go into the details of semantic matching here, just use both as the name - meshInput.name = '%s%d' % (attr.semanticName, attr.semanticIndex) + meshInput.vertexResourceId = vbs[attr.vertexBuffer].resourceId + meshInput.vertexByteStride = vbs[attr.vertexBuffer].byteStride + meshInput.name = attr.name meshInputs.append(meshInput) @@ -111,8 +107,7 @@ def getMeshOutputs(controller, postvs): meshOutputs = [] posidx = 0 - state = controller.GetD3D11PipelineState() - vs = state.vertexShader.reflection + vs = controller.GetPipelineState().GetShaderReflection(rd.ShaderStage.Vertex) # Repeat the process, but this time sourcing the data from postvs. # Since these are outputs, we iterate over the list of outputs from the diff --git a/docs/python_api/examples/renderdoc/decode_mesh.rst b/docs/python_api/examples/renderdoc/decode_mesh.rst index 715697df7..45803aca7 100644 --- a/docs/python_api/examples/renderdoc/decode_mesh.rst +++ b/docs/python_api/examples/renderdoc/decode_mesh.rst @@ -3,19 +3,17 @@ Decoding Mesh Data In this example we will fetch the geometry inputs to and outputs from a vertex shader. While this sample does not handle all possible edge cases, it is more complex than most others. -First we gather the API state that describes the vertex input data. In this example we will use the D3D11 pipeline state, but the same can be done for other APIs: +First we gather the API state that describes the vertex input data. In this example we will use the API abstraction :py:class:`~renderdoc.PipeState` so that this code works on a capture from any API: .. highlight:: python .. code:: python - # This work is API-specific, but the APIs have a lot of similarities. - # Here we implement support for D3D11 since it's relatively simple - state = controller.GetD3D11PipelineState() + state = controller.GetPipelineState() # Get the index & vertex buffers, and fixed vertex inputs - ib = state.inputAssembly.indexBuffer - vbs = state.inputAssembly.vertexBuffers - attrs = state.inputAssembly.layouts + ib = state.GetIBuffer() + vbs = state.GetVBuffers() + attrs = state.GetVertexInputs() We iterate over every attribute defined, and create an object that describes where to source it from, based on :py:class:`~renderdoc.MeshFormat` - since that is the format returned by :py:meth:`~renderdoc.ReplayController.GetPostVSData` this allows us to re-use code. @@ -42,13 +40,11 @@ In the object we pass both the indices (which does not vary per attribute in our meshInput.indexResourceId = rd.ResourceId.Null() # The total offset is the attribute offset from the base of the vertex - meshInput.vertexByteOffset = attr.byteOffset + vbs[attr.inputSlot].byteOffset + meshInput.vertexByteOffset = attr.byteOffset + vbs[attr.vertexBuffer].byteOffset meshInput.format = attr.format - meshInput.vertexResourceId = vbs[attr.inputSlot].resourceId - meshInput.vertexByteStride = vbs[attr.inputSlot].byteStride - - # We don't go into the details of semantic matching here, just use both as the name - meshInput.name = '%s%d' % (attr.semanticName, attr.semanticIndex) + meshInput.vertexResourceId = vbs[attr.vertexBuffer].resourceId + meshInput.vertexByteStride = vbs[attr.vertexBuffer].byteStride + meshInput.name = attr.name meshInputs.append(meshInput) @@ -174,8 +170,7 @@ The position output is also treated specially - it always appears first, regardl posidx = 0 - state = controller.GetD3D11PipelineState() - vs = state.vertexShader.reflection + vs = controller.GetPipelineState().GetShaderReflection(rd.ShaderStage.Vertex) # Repeat the process, but this time sourcing the data from postvs. # Since these are outputs, we iterate over the list of outputs from the diff --git a/docs/python_api/examples/renderdoc/fetch_shader.py b/docs/python_api/examples/renderdoc/fetch_shader.py index f99c3c39a..2d5a537c1 100644 --- a/docs/python_api/examples/renderdoc/fetch_shader.py +++ b/docs/python_api/examples/renderdoc/fetch_shader.py @@ -29,17 +29,21 @@ def sampleCode(controller): target = targets[0] + state = controller.GetPipelineState() + # For some APIs, it might be relevant to set the PSO id or entry point name - pipe = rd.ResourceId.Null() - entry = "main" + pipe = state.GetGraphicsPipelineObject() + entry = state.GetShaderEntryPoint(rd.ShaderStage.Pixel) # Get the pixel shader's reflection object - ps = controller.GetD3D11PipelineState().pixelShader + ps = state.GetShaderReflection(rd.ShaderStage.Pixel) + + cb = state.GetConstantBuffer(rd.ShaderStage.Pixel, 0, 0) print("Pixel shader:") - print(controller.DisassembleShader(pipe, ps.reflection, target)) + print(controller.DisassembleShader(pipe, ps, target)) - cbufferVars = controller.GetCBufferVariableContents(ps.resourceId, entry, 0, ps.constantBuffers[0].resourceId, 0) + cbufferVars = controller.GetCBufferVariableContents(ps.resourceId, entry, 0, cb.resourceId, 0) for v in cbufferVars: printVar(v) diff --git a/docs/python_api/examples/renderdoc/fetch_shader.rst b/docs/python_api/examples/renderdoc/fetch_shader.rst index 28472ef66..2dbf9ae0f 100644 --- a/docs/python_api/examples/renderdoc/fetch_shader.rst +++ b/docs/python_api/examples/renderdoc/fetch_shader.rst @@ -19,17 +19,21 @@ When disassembling a shader there may be more than one possible representation a Next we fetch any ancillary data that might be needed to disassemble - this varies by API depending on whether it supports multiple entry points per shader, or has a concept of pipeline state objects that are used together with a shader to disassemble. -For the purposes of this example we use D3D11 which does not require either, so we set some default values and fetch the shader from the pipeline state. Finally we fetch the disassembled shader string with :py:meth:`~renderdoc.ReplayController.DisassembleShader` and print it: +For the purposes of this example we use the API abstraction :py:class:`~renderdoc.PipeState` so that this code works on a capture from any API, so we fetch the state bindings that we need. Finally we fetch the disassembled shader string with :py:meth:`~renderdoc.ReplayController.DisassembleShader` and print it: .. highlight:: python .. code:: python - # For some APIs, it might be relevant to set the PSO id or entry point name - pipe = rd.ResourceId.Null() - entry = "main" + state = controller.GetPipelineState() - # Get the pixel shader's reflection object - ps = controller.GetD3D11PipelineState().pixelShader + # For some APIs, it might be relevant to set the PSO id or entry point name + pipe = state.GetGraphicsPipelineObject() + entry = state.GetShaderEntryPoint(rd.ShaderStage.Pixel) + + # Get the pixel shader's reflection object + ps = state.GetShaderReflection(rd.ShaderStage.Pixel) + + cb = state.GetConstantBuffer(rd.ShaderStage.Pixel, 0, 0) print("Pixel shader:") print(controller.DisassembleShader(pipe, ps.reflection, target)) @@ -39,7 +43,7 @@ Now we want to display the constants bound to this shader. Shader bindings is an .. highlight:: python .. code:: python - cbufferVars = controller.GetCBufferVariableContents(ps.resourceId, entry, 0, ps.constantBuffers[0].resourceId, 0) + cbufferVars = controller.GetCBufferVariableContents(ps.resourceId, entry, 0, cb.resourceId, 0) Since constants can contain structs of other constants, we want to define a recursive function that will iterate over a constant and print it along with its value. We want to handle both vectors and matrices so we need to iterate over both rows and columns for each variable. @@ -188,16 +192,16 @@ Sample output: range: 3.000 gLightPosV: - -2.022 0.200 6.306 -107374176.000 + -2.022 0.200 6.306 -107374176.000 gLigthDirES: - -0.298 -0.596 -0.745 + -0.298 -0.596 -0.745 gWorldViewProj: - 1.567 0.000 0.000 0.000 - 0.000 2.414 0.000 0.000 - 0.000 0.000 1.002 1.000 - -3.169 0.483 5.896 6.306 + 1.567 0.000 0.000 0.000 + 0.000 2.414 0.000 0.000 + 0.000 0.000 1.002 1.000 + -3.169 0.483 5.896 6.306 gWorldView: - 1.000 0.000 0.000 0.000 - 0.000 1.000 0.000 0.000 - 0.000 0.000 1.000 0.000 - -2.022 0.200 6.306 1.000 + 1.000 0.000 0.000 0.000 + 0.000 1.000 0.000 0.000 + 0.000 0.000 1.000 0.000 + -2.022 0.200 6.306 1.000 diff --git a/docs/python_api/qrenderdoc/index.rst b/docs/python_api/qrenderdoc/index.rst index f34a757ad..a165a146b 100644 --- a/docs/python_api/qrenderdoc/index.rst +++ b/docs/python_api/qrenderdoc/index.rst @@ -7,9 +7,7 @@ qrenderdoc API Reference main windows config - pipeline * :doc:`main` * :doc:`windows` -* :doc:`config` -* :doc:`pipeline` \ No newline at end of file +* :doc:`config` \ No newline at end of file diff --git a/docs/python_api/qrenderdoc/pipeline.rst b/docs/python_api/qrenderdoc/pipeline.rst deleted file mode 100644 index b287acd8e..000000000 --- a/docs/python_api/qrenderdoc/pipeline.rst +++ /dev/null @@ -1,37 +0,0 @@ -Pipeline Abstraction -==================== - -.. contents:: - -.. currentmodule:: qrenderdoc - -Pipeline --------- - -.. autoclass:: qrenderdoc.CommonPipelineState - :members: - :undoc-members: - -Bindings --------- - -.. autoclass:: qrenderdoc.BoundResource - :members: - :undoc-members: - -.. autoclass:: qrenderdoc.BoundResourceArray - :members: - :undoc-members: - -.. autoclass:: qrenderdoc.BoundVBuffer - :members: - :undoc-members: - -.. autoclass:: qrenderdoc.BoundCBuffer - :members: - :undoc-members: - -.. autoclass:: qrenderdoc.VertexInputAttribute - :members: - :undoc-members: - diff --git a/docs/python_api/renderdoc/enums_data.rst b/docs/python_api/renderdoc/enums_data.rst index 2483880ad..44a7b6554 100644 --- a/docs/python_api/renderdoc/enums_data.rst +++ b/docs/python_api/renderdoc/enums_data.rst @@ -5,4 +5,4 @@ Enums and Data Structures :members: :undoc-members: :imported-members: - :exclude-members: free_functions__, enum_constants__, name_match__startswith__D3D11, name_match__startswith__D3D12, name_match__startswith__VK, name_match__startswith__GL, name_match__startswith__rdcarray_of, rdcstr, bytebuf, ReplayController, ReplayOutput, TargetControl, RemoteServer, CaptureFile + :exclude-members: free_functions__, enum_constants__, name_match__startswith__D3D11, name_match__startswith__D3D12, name_match__startswith__VK, name_match__startswith__GL, name_match__startswith__rdcarray_of, rdcstr, bytebuf, ReplayController, ReplayOutput, TargetControl, RemoteServer, CaptureFile, Viewport, Scissor, BlendEquation, ColorBlend, StencilFace, BoundResource, BoundResourceArray, BoundVBuffer, BoundCBuffer, VertexInputAttribute, PipeState diff --git a/docs/python_api/renderdoc/pipelines/common.rst b/docs/python_api/renderdoc/pipelines/common.rst new file mode 100644 index 000000000..2c5829111 --- /dev/null +++ b/docs/python_api/renderdoc/pipelines/common.rst @@ -0,0 +1,79 @@ +Common Pipeline State Abstraction +================================= + +.. currentmodule:: renderdoc + +.. autoclass:: PipeState + :members: + :undoc-members: + +Viewport +-------- + +.. autoclass:: renderdoc.Viewport + :members: + :undoc-members: + +Scissor +------- + +.. autoclass:: renderdoc.Scissor + :members: + :undoc-members: + +BlendEquation +------------- + +.. autoclass:: renderdoc.BlendEquation + :members: + :undoc-members: + +ColorBlend +---------- + +.. autoclass:: renderdoc.ColorBlend + :members: + :undoc-members: + +StencilFace +----------- + +.. autoclass:: renderdoc.StencilFace + :members: + :undoc-members: + +BoundResource +------------- + +.. autoclass:: renderdoc.BoundResource + :members: + :undoc-members: + +BoundResourceArray +------------------ + +.. autoclass:: renderdoc.BoundResourceArray + :members: + :undoc-members: + +BoundVBuffer +------------ + +.. autoclass:: renderdoc.BoundVBuffer + :members: + :undoc-members: + +BoundCBuffer +------------ + +.. autoclass:: renderdoc.BoundCBuffer + :members: + :undoc-members: + +VertexInputAttribute +-------------------- + +.. autoclass:: renderdoc.VertexInputAttribute + :members: + :undoc-members: + \ No newline at end of file diff --git a/docs/python_api/renderdoc/pipelines/index.rst b/docs/python_api/renderdoc/pipelines/index.rst index 8cb3d0ed9..859da7c20 100644 --- a/docs/python_api/renderdoc/pipelines/index.rst +++ b/docs/python_api/renderdoc/pipelines/index.rst @@ -2,7 +2,10 @@ Pipeline State Objects ====================== .. toctree:: + :maxdepth: 1 + d3d11 d3d12 gl vulkan + common diff --git a/qrenderdoc/Code/CaptureContext.cpp b/qrenderdoc/Code/CaptureContext.cpp index b7dbdefa0..2653f68a8 100644 --- a/qrenderdoc/Code/CaptureContext.cpp +++ b/qrenderdoc/Code/CaptureContext.cpp @@ -55,9 +55,11 @@ #include "QRDUtils.h" #include "RGPInterop.h" +#include "pipestate.inl" + CaptureContext::CaptureContext(QString paramFilename, QString remoteHost, uint32_t remoteIdent, bool temp, PersistantConfig &cfg) - : m_Config(cfg), m_CurPipelineState(*this) + : m_Config(cfg) { m_CaptureLoaded = false; m_LoadInProgress = false; @@ -66,10 +68,11 @@ CaptureContext::CaptureContext(QString paramFilename, QString remoteHost, uint32 memset(&m_APIProps, 0, sizeof(m_APIProps)); - m_CurD3D11PipelineState = &m_DummyD3D11; - m_CurD3D12PipelineState = &m_DummyD3D12; - m_CurGLPipelineState = &m_DummyGL; - m_CurVulkanPipelineState = &m_DummyVK; + m_CurD3D11PipelineState = NULL; + m_CurD3D12PipelineState = NULL; + m_CurGLPipelineState = NULL; + m_CurVulkanPipelineState = NULL; + m_CurPipelineState = &m_DummyPipelineState; m_StructuredFile = &m_DummySDFile; @@ -325,12 +328,11 @@ void CaptureContext::LoadCaptureThreaded(const QString &captureFile, const QStri m_PostloadProgress = 0.9f; - m_CurD3D11PipelineState = &r->GetD3D11PipelineState(); - m_CurD3D12PipelineState = &r->GetD3D12PipelineState(); - m_CurGLPipelineState = &r->GetGLPipelineState(); - m_CurVulkanPipelineState = &r->GetVulkanPipelineState(); - m_CurPipelineState.SetStates(m_APIProps, m_CurD3D11PipelineState, m_CurD3D12PipelineState, - m_CurGLPipelineState, m_CurVulkanPipelineState); + m_CurD3D11PipelineState = r->GetD3D11PipelineState(); + m_CurD3D12PipelineState = r->GetD3D12PipelineState(); + m_CurGLPipelineState = r->GetGLPipelineState(); + m_CurVulkanPipelineState = r->GetVulkanPipelineState(); + m_CurPipelineState = &r->GetPipelineState(); m_UnreadMessageCount = 0; AddMessages(m_FrameInfo.debugMessages); @@ -858,11 +860,11 @@ void CaptureContext::CloseCapture() m_Drawcalls.clear(); m_FirstDrawcall = m_LastDrawcall = NULL; - m_CurD3D11PipelineState = &m_DummyD3D11; - m_CurD3D12PipelineState = &m_DummyD3D12; - m_CurGLPipelineState = &m_DummyGL; - m_CurVulkanPipelineState = &m_DummyVK; - m_CurPipelineState.SetStates(m_APIProps, NULL, NULL, NULL, NULL); + m_CurD3D11PipelineState = NULL; + m_CurD3D12PipelineState = NULL; + m_CurGLPipelineState = NULL; + m_CurVulkanPipelineState = NULL; + m_CurPipelineState = &m_DummyPipelineState; m_StructuredFile = &m_DummySDFile; @@ -1025,12 +1027,11 @@ void CaptureContext::SetEventID(const rdcarray &exclude, uint3 m_Renderer.BlockInvoke([this, eventId, force](IReplayController *r) { r->SetFrameEvent(eventId, force); - m_CurD3D11PipelineState = &r->GetD3D11PipelineState(); - m_CurD3D12PipelineState = &r->GetD3D12PipelineState(); - m_CurGLPipelineState = &r->GetGLPipelineState(); - m_CurVulkanPipelineState = &r->GetVulkanPipelineState(); - m_CurPipelineState.SetStates(m_APIProps, m_CurD3D11PipelineState, m_CurD3D12PipelineState, - m_CurGLPipelineState, m_CurVulkanPipelineState); + m_CurD3D11PipelineState = r->GetD3D11PipelineState(); + m_CurD3D12PipelineState = r->GetD3D12PipelineState(); + m_CurGLPipelineState = r->GetGLPipelineState(); + m_CurVulkanPipelineState = r->GetVulkanPipelineState(); + m_CurPipelineState = &r->GetPipelineState(); }); bool updateSelectedEvent = force || prevSelectedEventID != selectedEventID; diff --git a/qrenderdoc/Code/CaptureContext.h b/qrenderdoc/Code/CaptureContext.h index 935d1c2f1..44ab4f85a 100644 --- a/qrenderdoc/Code/CaptureContext.h +++ b/qrenderdoc/Code/CaptureContext.h @@ -218,11 +218,11 @@ public: void AddDockWindow(QWidget *newWindow, DockReference ref, QWidget *refWindow, float percentage = 0.5f) override; - const D3D11Pipe::State &CurD3D11PipelineState() override { return *m_CurD3D11PipelineState; } - const D3D12Pipe::State &CurD3D12PipelineState() override { return *m_CurD3D12PipelineState; } - const GLPipe::State &CurGLPipelineState() override { return *m_CurGLPipelineState; } - const VKPipe::State &CurVulkanPipelineState() override { return *m_CurVulkanPipelineState; } - CommonPipelineState &CurPipelineState() override { return m_CurPipelineState; } + const D3D11Pipe::State *CurD3D11PipelineState() override { return m_CurD3D11PipelineState; } + const D3D12Pipe::State *CurD3D12PipelineState() override { return m_CurD3D12PipelineState; } + const GLPipe::State *CurGLPipelineState() override { return m_CurGLPipelineState; } + const VKPipe::State *CurVulkanPipelineState() override { return m_CurVulkanPipelineState; } + const PipeState &CurPipelineState() override { return *m_CurPipelineState; } PersistantConfig &Config() override { return m_Config; } private: ReplayManager m_Renderer; @@ -231,12 +231,8 @@ private: const D3D12Pipe::State *m_CurD3D12PipelineState; const GLPipe::State *m_CurGLPipelineState; const VKPipe::State *m_CurVulkanPipelineState; - CommonPipelineState m_CurPipelineState; - - D3D11Pipe::State m_DummyD3D11; - D3D12Pipe::State m_DummyD3D12; - GLPipe::State m_DummyGL; - VKPipe::State m_DummyVK; + const PipeState *m_CurPipelineState; + PipeState m_DummyPipelineState; PersistantConfig &m_Config; diff --git a/qrenderdoc/Code/Interface/CommonPipelineState.h b/qrenderdoc/Code/Interface/CommonPipelineState.h deleted file mode 100644 index 9e21589ba..000000000 --- a/qrenderdoc/Code/Interface/CommonPipelineState.h +++ /dev/null @@ -1,534 +0,0 @@ -/****************************************************************************** - * The MIT License (MIT) - * - * Copyright (c) 2016-2018 Baldur Karlsson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - ******************************************************************************/ - -#pragma once - -// do not include any headers here, they must all be in QRDInterface.h -#include "QRDInterface.h" - -struct ICaptureContext; - -DOCUMENT("Information about a single resource bound to a slot in an API-specific way."); -struct BoundResource -{ - DOCUMENT(""); - BoundResource() - { - resourceId = ResourceId(); - firstMip = -1; - firstSlice = -1; - typeHint = CompType::Typeless; - } - BoundResource(ResourceId id) - { - resourceId = id; - firstMip = -1; - firstSlice = -1; - typeHint = CompType::Typeless; - } - - bool operator==(const BoundResource &o) const - { - return resourceId == o.resourceId && firstMip == o.firstMip && firstSlice == o.firstSlice && - typeHint == o.typeHint; - } - bool operator<(const BoundResource &o) const - { - if(resourceId != o.resourceId) - return resourceId < o.resourceId; - if(firstMip != o.firstMip) - return firstMip < o.firstMip; - if(firstSlice != o.firstSlice) - return firstSlice < o.firstSlice; - if(typeHint != o.typeHint) - return typeHint < o.typeHint; - return false; - } - DOCUMENT("A :class:`~renderdoc.ResourceId` identifying the bound resource."); - ResourceId resourceId; - DOCUMENT("For textures, the highest mip level available on this binding, or -1 for all mips"); - int firstMip; - DOCUMENT("For textures, the first array slice available on this binding. or -1 for all slices."); - int firstSlice; - DOCUMENT( - "For textures, a :class:`~renderdoc.CompType` hint for how to interpret typeless textures."); - CompType typeHint; -}; - -DECLARE_REFLECTION_STRUCT(BoundResource); - -// TODO this should be replaced with an rdcmap -DOCUMENT(R"(Contains all of the bound resources at a particular bindpoint. In APIs that don't -support resource arrays, there will only be one bound resource. -)"); -struct BoundResourceArray -{ - DOCUMENT(""); - BoundResourceArray() = default; - BoundResourceArray(Bindpoint b) : bindPoint(b) {} - BoundResourceArray(Bindpoint b, const rdcarray &r) : bindPoint(b), resources(r) {} - // for convenience for searching the array, we compare only using the BindPoint - bool operator==(const BoundResourceArray &o) const { return bindPoint == o.bindPoint; } - bool operator!=(const BoundResourceArray &o) const { return !(bindPoint == o.bindPoint); } - bool operator<(const BoundResourceArray &o) const { return bindPoint < o.bindPoint; } - DOCUMENT("The bind point for this array of bound resources."); - Bindpoint bindPoint; - - DOCUMENT("The resources at this bind point"); - rdcarray resources; -}; - -DECLARE_REFLECTION_STRUCT(BoundResourceArray); - -DOCUMENT("Information about a single vertex or index buffer binding."); -struct BoundVBuffer -{ - DOCUMENT(""); - bool operator==(const BoundVBuffer &o) const - { - return resourceId == o.resourceId && byteOffset == o.byteOffset && byteStride == o.byteStride; - } - bool operator<(const BoundVBuffer &o) const - { - if(resourceId != o.resourceId) - return resourceId < o.resourceId; - if(byteOffset != o.byteOffset) - return byteOffset < o.byteOffset; - if(byteStride != o.byteStride) - return byteStride < o.byteStride; - return false; - } - DOCUMENT("A :class:`~renderdoc.ResourceId` identifying the buffer."); - ResourceId resourceId; - DOCUMENT("The offset in bytes from the start of the buffer to the data."); - uint64_t byteOffset = 0; - DOCUMENT("The stride in bytes between the start of one element and the start of the next."); - uint32_t byteStride = 0; -}; - -DECLARE_REFLECTION_STRUCT(BoundVBuffer); - -DOCUMENT("Information about a single constant buffer binding."); -struct BoundCBuffer -{ - DOCUMENT("A :class:`~renderdoc.ResourceId` identifying the buffer."); - ResourceId resourceId; - DOCUMENT("The offset in bytes from the start of the buffer to the constant data."); - uint64_t byteOffset = 0; - DOCUMENT("The size in bytes for the constant buffer. Access outside this size returns 0."); - uint32_t byteSize = 0; -}; - -DECLARE_REFLECTION_STRUCT(BoundCBuffer); - -DOCUMENT("Information about a vertex input attribute feeding the vertex shader."); -struct VertexInputAttribute -{ - DOCUMENT(""); - bool operator==(const VertexInputAttribute &o) const - { - return name == o.name && vertexBuffer == o.vertexBuffer && byteOffset == o.byteOffset && - perInstance == o.perInstance && instanceRate == o.instanceRate && format == o.format && - !memcmp(&genericValue, &o.genericValue, sizeof(genericValue)) && - genericEnabled == o.genericEnabled && used == o.used; - } - bool operator<(const VertexInputAttribute &o) const - { - if(name != o.name) - return name < o.name; - if(vertexBuffer != o.vertexBuffer) - return vertexBuffer < o.vertexBuffer; - if(byteOffset != o.byteOffset) - return byteOffset < o.byteOffset; - if(perInstance != o.perInstance) - return perInstance < o.perInstance; - if(instanceRate != o.instanceRate) - return instanceRate < o.instanceRate; - if(format != o.format) - return format < o.format; - if(memcmp(&genericValue, &o.genericValue, sizeof(genericValue)) < 0) - return true; - if(genericEnabled != o.genericEnabled) - return genericEnabled < o.genericEnabled; - if(used != o.used) - return used < o.used; - return false; - } - - DOCUMENT("The name of this input. This may be a variable name or a semantic name."); - rdcstr name; - DOCUMENT("The index of the vertex buffer used to provide this attribute."); - int vertexBuffer; - DOCUMENT("The byte offset from the start of the vertex data for this VB to this attribute."); - uint32_t byteOffset; - DOCUMENT("``True`` if this attribute runs at instance rate."); - bool perInstance; - DOCUMENT(R"(If :data:`perInstance` is ``True``, the number of instances that source the same value -from the vertex buffer before advancing to the next value. -)"); - int instanceRate; - DOCUMENT("A :class:`~renderdoc.ResourceFormat` with the interpreted format of this attribute."); - ResourceFormat format; - DOCUMENT(R"(A :class:`~renderdoc.PixelValue` with the generic value for this attribute if it has -no VB bound. -)"); - PixelValue genericValue; - DOCUMENT("``True`` if this attribute is using :data:`genericValue` for its data."); - bool genericEnabled; - DOCUMENT("``True`` if this attribute is enabled and used by the vertex shader."); - bool used; -}; - -DECLARE_REFLECTION_STRUCT(VertexInputAttribute); - -DOCUMENT(R"(An API-agnostic view of the common aspects of the pipeline state. This allows simple -access to e.g. find out the bound resources or vertex buffers, or certain pipeline state which is -available on all APIs. - -For more detailed or precise information without abstraction, access the specific pipeline state -for the capture that's open. -)"); -class CommonPipelineState -{ -public: - CommonPipelineState(ICaptureContext &ctx) : m_Ctx(ctx) {} - DOCUMENT(R"(Set the source API-specific states to read data from. - -:param ~renderdoc.APIProperties props: The properties of the current capture. -:param ~renderdoc.D3D11State d3d11: The D3D11 state. -:param ~renderdoc.D3D12State d3d12: The D3D11 state. -:param ~renderdoc.GLState gl: The OpenGL state. -:param ~renderdoc.VKState vk: The Vulkan state. -)"); - void SetStates(APIProperties props, const D3D11Pipe::State *d3d11, const D3D12Pipe::State *d3d12, - const GLPipe::State *gl, const VKPipe::State *vk) - { - m_APIProps = props; - m_D3D11 = d3d11; - m_D3D12 = d3d12; - m_GL = gl; - m_Vulkan = vk; - } - - DOCUMENT( - "The default :class:`~renderdoc.GraphicsAPI` to pretend to contain, if no capture is " - "loaded."); - GraphicsAPI defaultType = GraphicsAPI::D3D11; - - DOCUMENT(R"(Determines whether or not a capture is currently loaded. - -:return: A boolean indicating if a capture is currently loaded. -:rtype: ``bool`` -)"); - bool IsCaptureLoaded() - { - return m_D3D11 != NULL || m_D3D12 != NULL || m_GL != NULL || m_Vulkan != NULL; - } - - DOCUMENT(R"(Determines whether or not a D3D11 capture is currently loaded. - -:return: A boolean indicating if a D3D11 capture is currently loaded. -:rtype: ``bool`` -)"); - bool IsCaptureD3D11() - { - return IsCaptureLoaded() && m_APIProps.pipelineType == GraphicsAPI::D3D11 && m_D3D11 != NULL; - } - - DOCUMENT(R"(Determines whether or not a D3D12 capture is currently loaded. - -:return: A boolean indicating if a D3D12 capture is currently loaded. -:rtype: ``bool`` -)"); - bool IsCaptureD3D12() - { - return IsCaptureLoaded() && m_APIProps.pipelineType == GraphicsAPI::D3D12 && m_D3D12 != NULL; - } - - DOCUMENT(R"(Determines whether or not an OpenGL capture is currently loaded. - -:return: A boolean indicating if an OpenGL capture is currently loaded. -:rtype: ``bool`` -)"); - bool IsCaptureGL() - { - return IsCaptureLoaded() && m_APIProps.pipelineType == GraphicsAPI::OpenGL && m_GL != NULL; - } - - DOCUMENT(R"(Determines whether or not a Vulkan capture is currently loaded. - -:return: A boolean indicating if a Vulkan capture is currently loaded. -:rtype: ``bool`` -)"); - bool IsCaptureVK() - { - return IsCaptureLoaded() && m_APIProps.pipelineType == GraphicsAPI::Vulkan && m_Vulkan != NULL; - } - - // add a bunch of generic properties that people can check to save having to see which pipeline - // state is valid and look at the appropriate part of it - DOCUMENT(R"(Determines whether or not tessellation is currently enabled. - -:return: A boolean indicating if tessellation is currently enabled. -:rtype: ``bool`` -)"); - bool IsTessellationEnabled() - { - if(IsCaptureLoaded()) - { - if(IsCaptureD3D11()) - return m_D3D11 != NULL && m_D3D11->hullShader.resourceId != ResourceId(); - - if(IsCaptureD3D12()) - return m_D3D12 != NULL && m_D3D12->hullShader.resourceId != ResourceId(); - - if(IsCaptureGL()) - return m_GL != NULL && m_GL->tessEvalShader.shaderResourceId != ResourceId(); - - if(IsCaptureVK()) - return m_Vulkan != NULL && m_Vulkan->tessEvalShader.resourceId != ResourceId(); - } - - return false; - } - - DOCUMENT(R"(Determines whether or not the current capture supports binding arrays of resources. - -:return: A boolean indicating if binding arrays of resources is supported. -:rtype: ``bool`` -)"); - bool SupportsResourceArrays() { return IsCaptureLoaded() && IsCaptureVK(); } - DOCUMENT(R"(Determines whether or not the current capture uses explicit barriers. - -:return: A boolean indicating if explicit barriers are used. -:rtype: ``bool`` -)"); - bool SupportsBarriers() { return IsCaptureLoaded() && (IsCaptureVK() || IsCaptureD3D12()); } - DOCUMENT(R"(Determines whether or not the PostVS data is aligned in the typical fashion (ie. -vectors not crossing ``float4`` boundaries). APIs that use stream-out or transform feedback have -tightly packed data, but APIs that rewrite shaders to dump data might have these alignment -requirements. - -:return: A boolean indicating if post-VS data is aligned. -:rtype: ``bool`` -)"); - bool HasAlignedPostVSData() { return IsCaptureLoaded() && IsCaptureVK(); } - DOCUMENT(R"(For APIs that have explicit barriers, retrieves the current layout of a resource. - -:return: The name of the current resource layout. -:rtype: ``str`` -)"); - rdcstr GetResourceLayout(ResourceId id); - - DOCUMENT(R"(Retrieves a suitable two or three letter abbreviation of the given shader stage. - -:param ~renderdoc.ShaderStage stage: The shader stage to abbreviate. -:return: The abbreviation of the stage. -:rtype: ``str`` -)"); - rdcstr Abbrev(ShaderStage stage); - DOCUMENT(R"(Retrieves a suitable two or three letter abbreviation of the output stage. Typically -'OM' or 'FBO'. - -:return: The abbreviation of the output stage. -:rtype: ``str`` -)"); - rdcstr OutputAbbrev(); - - DOCUMENT(R"(Retrieves the viewport for a given index. - -:param int index: The index to retrieve. -:return: The viewport for the given index. -:rtype: ~renderdoc.Viewport -)"); - Viewport GetViewport(int index); - - DOCUMENT(R"(Retrieves the scissor region for a given index. - -:param int index: The index to retrieve. -:return: The scissor region for the given index. -:rtype: ~renderdoc.Scissor -)"); - Scissor GetScissor(int index); - - DOCUMENT(R"(Retrieves the current bindpoint mapping for a shader stage. - -This returns an empty bindpoint mapping if no shader is bound. - -:param ~renderdoc.ShaderStage stage: The shader stage to fetch. -:return: The bindpoint mapping for the given shader. -:rtype: ~renderdoc.ShaderBindpointMapping -)"); - const ShaderBindpointMapping &GetBindpointMapping(ShaderStage stage); - - DOCUMENT(R"(Retrieves the shader reflection information for a shader stage. - -This returns ``None`` if no shader is bound. - -:param ~renderdoc.ShaderStage stage: The shader stage to fetch. -:return: The reflection data for the given shader. -:rtype: :class:`~renderdoc.ShaderBindpointMapping` or ``None`` -)"); - const ShaderReflection *GetShaderReflection(ShaderStage stage); - - DOCUMENT(R"(Retrieves the the compute pipeline state object, if applicable. - -:return: The object ID for the given pipeline object. -:rtype: ~renderdoc.ResourceId -)"); - ResourceId GetComputePipelineObject(); - - DOCUMENT(R"(Retrieves the the graphics pipeline state object, if applicable. - -:return: The object ID for the given pipeline object. -:rtype: ~renderdoc.ResourceId -)"); - ResourceId GetGraphicsPipelineObject(); - - DOCUMENT(R"(Retrieves the name of the entry point function for a shader stage. - -For some APIs that don't distinguish by entry point, this may be empty. - -:param ~renderdoc.ShaderStage stage: The shader stage to fetch. -:return: The entry point name for the given shader. -:rtype: ``str`` -)"); - rdcstr GetShaderEntryPoint(ShaderStage stage); - - DOCUMENT(R"(Retrieves the object ID of the shader bound at a shader stage. - -:param ~renderdoc.ShaderStage stage: The shader stage to fetch. -:return: The object ID for the given shader. -:rtype: ~renderdoc.ResourceId -)"); - ResourceId GetShader(ShaderStage stage); - - DOCUMENT(R"(Retrieves the name of the shader object at a shader stage. - -:param ~renderdoc.ShaderStage stage: The shader stage to fetch. -:return: The object name for the given shader. -:rtype: ``str`` -)"); - rdcstr GetShaderName(ShaderStage stage); - - DOCUMENT(R"(Retrieves the common file extension for high level shaders in the current API. - -Typically this is ``glsl`` or ``hlsl``. - -:return: The file extension with no ``.``. -:rtype: ``str`` -)"); - rdcstr GetShaderExtension(); - - DOCUMENT(R"(Retrieves the current index buffer binding. - -:return: A :class:`BoundVBuffer` with the index buffer details. The stride is always 0. -:rtype: ``BoundVBuffer`` -)"); - BoundVBuffer GetIBuffer(); - - DOCUMENT(R"(Determines whether or not primitive restart is enabled. - -:return: A boolean indicating if primitive restart is enabled. -:rtype: ``bool`` -)"); - bool IsStripRestartEnabled(); - - DOCUMENT(R"(Retrieves the primitive restart index. - -:param int indexByteWidth: The width in bytes of the indices. -:return: The index value that represents a strip restart not a real index. -:rtype: ``int`` -)"); - uint32_t GetStripRestartIndex(); - - DOCUMENT(R"(Retrieves the currently bound vertex buffers. - -:return: The list of bound vertex buffers. -:rtype: ``list`` of :class:`BoundVBuffer`. -)"); - rdcarray GetVBuffers(); - - DOCUMENT(R"(Retrieves the currently specified vertex attributes. - -:return: The list of current vertex attributes. -:rtype: ``list`` of :class:`VertexInputAttribute`. -)"); - rdcarray GetVertexInputs(); - - DOCUMENT(R"(Retrieves the constant buffer at a given binding. - -:param ~renderdoc.ShaderStage stage: The shader stage to fetch from. -:param int BufIdx: The index in the shader's ConstantBlocks array to look up. -:param int ArrayIdx: For APIs that support arrays of constant buffers in a single binding, the index - in that array to look up. -:return: The constant buffer at the specified binding. -:rtype: BoundCBuffer -)"); - BoundCBuffer GetConstantBuffer(ShaderStage stage, uint32_t BufIdx, uint32_t ArrayIdx); - - DOCUMENT(R"(Retrieves the read-only resources bound to a particular shader stage. - -:param ~renderdoc.ShaderStage stage: The shader stage to fetch from. -:return: The currently bound read-only resoruces. -:rtype: ``list`` of :class:`BoundResourceArray` entries -)"); - rdcarray GetReadOnlyResources(ShaderStage stage); - - DOCUMENT(R"(Retrieves the read/write resources bound to a particular shader stage. - -:param ~renderdoc.ShaderStage stage: The shader stage to fetch from. -:return: The currently bound read/write resoruces. -:rtype: ``list`` of :class:`BoundResourceArray` entries -)"); - rdcarray GetReadWriteResources(ShaderStage stage); - - DOCUMENT(R"(Retrieves the read/write resources bound to the depth-stencil output. - -:return: The currently bound depth-stencil resource. -:rtype: BoundResource -)"); - BoundResource GetDepthTarget(); - - DOCUMENT(R"(Retrieves the resources bound to the color outputs. - -:return: The currently bound output targets. -:rtype: ``list`` of :class:`BoundResource`. -)"); - rdcarray GetOutputTargets(); - -private: - const D3D11Pipe::State *m_D3D11 = NULL; - const D3D12Pipe::State *m_D3D12 = NULL; - const GLPipe::State *m_GL = NULL; - const VKPipe::State *m_Vulkan = NULL; - APIProperties m_APIProps; - - ICaptureContext &m_Ctx; - - const D3D11Pipe::Shader &GetD3D11Stage(ShaderStage stage); - const D3D12Pipe::Shader &GetD3D12Stage(ShaderStage stage); - const GLPipe::Shader &GetGLStage(ShaderStage stage); - const VKPipe::Shader &GetVulkanStage(ShaderStage stage); -}; \ No newline at end of file diff --git a/qrenderdoc/Code/Interface/QRDInterface.h b/qrenderdoc/Code/Interface/QRDInterface.h index 0cfb5cc3c..793886184 100644 --- a/qrenderdoc/Code/Interface/QRDInterface.h +++ b/qrenderdoc/Code/Interface/QRDInterface.h @@ -61,7 +61,6 @@ class QWidget; #include "renderdoc_replay.h" #include "Analytics.h" -#include "CommonPipelineState.h" #include "PersistantConfig.h" #include "RemoteHost.h" @@ -1843,38 +1842,53 @@ currently docked. DOCUMENT(R"(Retrieve the current :class:`~renderdoc.D3D11State` pipeline state. +The return value will be ``None`` if the capture is not using the D3D11 API. +You should determine the API of the capture first before fetching it. + :return: The current D3D11 pipeline state. :rtype: ~renderdoc.D3D11State )"); - virtual const D3D11Pipe::State &CurD3D11PipelineState() = 0; + virtual const D3D11Pipe::State *CurD3D11PipelineState() = 0; DOCUMENT(R"(Retrieve the current :class:`~renderdoc.D3D12State` pipeline state. +The return value will be ``None`` if the capture is not using the D3D12 API. +You should determine the API of the capture first before fetching it. + :return: The current D3D12 pipeline state. :rtype: ~renderdoc.D3D12State )"); - virtual const D3D12Pipe::State &CurD3D12PipelineState() = 0; + virtual const D3D12Pipe::State *CurD3D12PipelineState() = 0; DOCUMENT(R"(Retrieve the current :class:`~renderdoc.GLState` pipeline state. +The return value will be ``None`` if the capture is not using the OpenGL API. +You should determine the API of the capture first before fetching it. + :return: The current OpenGL pipeline state. :rtype: ~renderdoc.GLState )"); - virtual const GLPipe::State &CurGLPipelineState() = 0; + virtual const GLPipe::State *CurGLPipelineState() = 0; DOCUMENT(R"(Retrieve the current :class:`~renderdoc.VKState` pipeline state. +The return value will be ``None`` if the capture is not using the Vulkan API. +You should determine the API of the capture first before fetching it. + :return: The current Vulkan pipeline state. :rtype: ~renderdoc.VKState )"); - virtual const VKPipe::State &CurVulkanPipelineState() = 0; + virtual const VKPipe::State *CurVulkanPipelineState() = 0; - DOCUMENT(R"(Retrieve the current :class:`CommonPipelineState` abstracted pipeline state. + DOCUMENT(R"(Retrieve the current :class:`~renderdoc.PipeState` abstracted pipeline state. + +This pipeline state will always be valid, and allows queries that will work regardless of the +capture's API. :return: The current API-agnostic abstracted pipeline state. -:rtype: CommonPipelineState +:rtype: ~renderdoc.PipeState )"); - virtual CommonPipelineState &CurPipelineState() = 0; + virtual const PipeState &CurPipelineState() = 0; DOCUMENT(R"(Retrieve the current persistant config. diff --git a/qrenderdoc/Code/pyrenderdoc/pyrenderdoc_stub.cpp b/qrenderdoc/Code/pyrenderdoc/pyrenderdoc_stub.cpp index 6b0bc27d9..326c05d13 100644 --- a/qrenderdoc/Code/pyrenderdoc/pyrenderdoc_stub.cpp +++ b/qrenderdoc/Code/pyrenderdoc/pyrenderdoc_stub.cpp @@ -24,6 +24,7 @@ #include #include +#include #include "renderdoc_replay.h" @@ -38,6 +39,8 @@ std::string DoStringise(const uint32_t &el) #include "renderdoc_tostr.inl" +#include "pipestate.inl" + extern "C" PyThreadState *GetExecutingThreadState(PyObject *global_handle) { return NULL; diff --git a/qrenderdoc/Code/pyrenderdoc/qrenderdoc.i b/qrenderdoc/Code/pyrenderdoc/qrenderdoc.i index 7f3849766..4aa9cffce 100644 --- a/qrenderdoc/Code/pyrenderdoc/qrenderdoc.i +++ b/qrenderdoc/Code/pyrenderdoc/qrenderdoc.i @@ -74,7 +74,6 @@ TEMPLATE_ARRAY_DECLARE(rdcarray); %include %include "Code/Interface/QRDInterface.h" -%include "Code/Interface/CommonPipelineState.h" %include "Code/Interface/PersistantConfig.h" %include "Code/Interface/RemoteHost.h" @@ -82,10 +81,6 @@ DOCUMENT(""); TEMPLATE_ARRAY_INSTANTIATE(rdcarray, EventBookmark) TEMPLATE_ARRAY_INSTANTIATE(rdcarray, SPIRVDisassembler) -TEMPLATE_ARRAY_INSTANTIATE(rdcarray, BoundVBuffer) -TEMPLATE_ARRAY_INSTANTIATE(rdcarray, VertexInputAttribute) -TEMPLATE_ARRAY_INSTANTIATE(rdcarray, BoundResource) -TEMPLATE_ARRAY_INSTANTIATE(rdcarray, BoundResourceArray) TEMPLATE_ARRAY_INSTANTIATE(rdcarray, rdcstrpair) TEMPLATE_ARRAY_INSTANTIATE(rdcarray, BugReport) TEMPLATE_ARRAY_INSTANTIATE_PTR(rdcarray, ICaptureViewer) diff --git a/qrenderdoc/Code/pyrenderdoc/qrenderdoc_stub.cpp b/qrenderdoc/Code/pyrenderdoc/qrenderdoc_stub.cpp index b35ef5281..5cb5d206d 100644 --- a/qrenderdoc/Code/pyrenderdoc/qrenderdoc_stub.cpp +++ b/qrenderdoc/Code/pyrenderdoc/qrenderdoc_stub.cpp @@ -160,148 +160,3 @@ void RemoteHost::CheckStatus() void RemoteHost::Launch() { } - -//////////////////////////////////////////////////////////////////////////////// -// CommonPipelineState.cpp stubs -//////////////////////////////////////////////////////////////////////////////// - -rdcstr CommonPipelineState::GetResourceLayout(ResourceId id) -{ - return ""; -} - -rdcstr CommonPipelineState::Abbrev(ShaderStage stage) -{ - return ""; -} - -rdcstr CommonPipelineState::OutputAbbrev() -{ - return ""; -} - -const D3D11Pipe::Shader &CommonPipelineState::GetD3D11Stage(ShaderStage stage) -{ - static D3D11Pipe::Shader dummy; - return dummy; -} - -const D3D12Pipe::Shader &CommonPipelineState::GetD3D12Stage(ShaderStage stage) -{ - static D3D12Pipe::Shader dummy; - return dummy; -} - -const GLPipe::Shader &CommonPipelineState::GetGLStage(ShaderStage stage) -{ - static GLPipe::Shader dummy; - return dummy; -} - -const VKPipe::Shader &CommonPipelineState::GetVulkanStage(ShaderStage stage) -{ - static VKPipe::Shader dummy; - return dummy; -} - -rdcstr CommonPipelineState::GetShaderExtension() -{ - return ""; -} - -Viewport CommonPipelineState::GetViewport(int index) -{ - return Viewport(); -} - -Scissor CommonPipelineState::GetScissor(int index) -{ - return Scissor(); -} - -const ShaderBindpointMapping &CommonPipelineState::GetBindpointMapping(ShaderStage stage) -{ - static ShaderBindpointMapping dummy; - return dummy; -} - -const ShaderReflection *CommonPipelineState::GetShaderReflection(ShaderStage stage) -{ - return NULL; -} - -ResourceId CommonPipelineState::GetComputePipelineObject() -{ - return ResourceId(); -} - -ResourceId CommonPipelineState::GetGraphicsPipelineObject() -{ - return ResourceId(); -} - -rdcstr CommonPipelineState::GetShaderEntryPoint(ShaderStage stage) -{ - return ""; -} - -ResourceId CommonPipelineState::GetShader(ShaderStage stage) -{ - return ResourceId(); -} - -rdcstr CommonPipelineState::GetShaderName(ShaderStage stage) -{ - return ""; -} - -BoundVBuffer CommonPipelineState::GetIBuffer() -{ - return BoundVBuffer(); -} - -bool CommonPipelineState::IsStripRestartEnabled() -{ - return false; -} - -uint32_t CommonPipelineState::GetStripRestartIndex() -{ - return UINT32_MAX; -} - -rdcarray CommonPipelineState::GetVBuffers() -{ - return rdcarray(); -} - -rdcarray CommonPipelineState::GetVertexInputs() -{ - return rdcarray(); -} - -BoundCBuffer CommonPipelineState::GetConstantBuffer(ShaderStage stage, uint32_t BufIdx, - uint32_t ArrayIdx) -{ - return BoundCBuffer(); -} - -rdcarray CommonPipelineState::GetReadOnlyResources(ShaderStage stage) -{ - return rdcarray(); -} - -rdcarray CommonPipelineState::GetReadWriteResources(ShaderStage stage) -{ - return rdcarray(); -} - -BoundResource CommonPipelineState::GetDepthTarget() -{ - return BoundResource(); -} - -rdcarray CommonPipelineState::GetOutputTargets() -{ - return rdcarray(); -} diff --git a/qrenderdoc/Code/pyrenderdoc/renderdoc.i b/qrenderdoc/Code/pyrenderdoc/renderdoc.i index 758427c5d..bbc68a76e 100644 --- a/qrenderdoc/Code/pyrenderdoc/renderdoc.i +++ b/qrenderdoc/Code/pyrenderdoc/renderdoc.i @@ -192,6 +192,7 @@ TEMPLATE_ARRAY_DECLARE(rdcarray); %include "replay_enums.h" %include "shader_types.h" %include "vk_pipestate.h" +%include "pipestate.h" %feature("docstring") ""; @@ -269,6 +270,10 @@ TEMPLATE_ARRAY_INSTANTIATE(rdcarray, ShaderEntryPoint) TEMPLATE_ARRAY_INSTANTIATE(rdcarray, Viewport) TEMPLATE_ARRAY_INSTANTIATE(rdcarray, Scissor) TEMPLATE_ARRAY_INSTANTIATE(rdcarray, ColorBlend) +TEMPLATE_ARRAY_INSTANTIATE(rdcarray, BoundVBuffer) +TEMPLATE_ARRAY_INSTANTIATE(rdcarray, VertexInputAttribute) +TEMPLATE_ARRAY_INSTANTIATE(rdcarray, BoundResource) +TEMPLATE_ARRAY_INSTANTIATE(rdcarray, BoundResourceArray) TEMPLATE_NAMESPACE_ARRAY_INSTANTIATE(rdcarray, VKPipe, Attachment) TEMPLATE_NAMESPACE_ARRAY_INSTANTIATE(rdcarray, VKPipe, BindingElement) TEMPLATE_NAMESPACE_ARRAY_INSTANTIATE(rdcarray, VKPipe, DescriptorBinding) diff --git a/qrenderdoc/Windows/PipelineState/D3D11PipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/D3D11PipelineStateViewer.cpp index 739eb0bae..e0b586ba8 100644 --- a/qrenderdoc/Windows/PipelineState/D3D11PipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/D3D11PipelineStateViewer.cpp @@ -508,9 +508,9 @@ void D3D11PipelineStateViewer::setViewDetails(RDTreeWidgetItem *node, const D3D1 if(view.type == D3D11ViewTag::OMDepth) { - if(m_Ctx.CurD3D11PipelineState().outputMerger.depthReadOnly) + if(m_Ctx.CurD3D11PipelineState()->outputMerger.depthReadOnly) text += tr("Depth component is read-only\n"); - if(m_Ctx.CurD3D11PipelineState().outputMerger.stencilReadOnly) + if(m_Ctx.CurD3D11PipelineState()->outputMerger.stencilReadOnly) text += tr("Stencil component is read-only\n"); } @@ -594,8 +594,8 @@ void D3D11PipelineStateViewer::addResourceRow(const D3D11ViewTag &view, bool viewDetails = false; if(view.type == D3D11ViewTag::OMDepth) - viewDetails = m_Ctx.CurD3D11PipelineState().outputMerger.depthReadOnly || - m_Ctx.CurD3D11PipelineState().outputMerger.stencilReadOnly; + viewDetails = m_Ctx.CurD3D11PipelineState()->outputMerger.depthReadOnly || + m_Ctx.CurD3D11PipelineState()->outputMerger.stencilReadOnly; bool filledSlot = (r.resourceResourceId != ResourceId()); bool usedSlot = (map && map->used); @@ -751,23 +751,23 @@ const D3D11Pipe::Shader *D3D11PipelineStateViewer::stageForSender(QWidget *widge while(widget) { if(widget == ui->stagesTabs->widget(0)) - return &m_Ctx.CurD3D11PipelineState().vertexShader; + return &m_Ctx.CurD3D11PipelineState()->vertexShader; if(widget == ui->stagesTabs->widget(1)) - return &m_Ctx.CurD3D11PipelineState().vertexShader; + return &m_Ctx.CurD3D11PipelineState()->vertexShader; if(widget == ui->stagesTabs->widget(2)) - return &m_Ctx.CurD3D11PipelineState().hullShader; + return &m_Ctx.CurD3D11PipelineState()->hullShader; if(widget == ui->stagesTabs->widget(3)) - return &m_Ctx.CurD3D11PipelineState().domainShader; + return &m_Ctx.CurD3D11PipelineState()->domainShader; if(widget == ui->stagesTabs->widget(4)) - return &m_Ctx.CurD3D11PipelineState().geometryShader; + return &m_Ctx.CurD3D11PipelineState()->geometryShader; if(widget == ui->stagesTabs->widget(5)) - return &m_Ctx.CurD3D11PipelineState().pixelShader; + return &m_Ctx.CurD3D11PipelineState()->pixelShader; if(widget == ui->stagesTabs->widget(6)) - return &m_Ctx.CurD3D11PipelineState().pixelShader; + return &m_Ctx.CurD3D11PipelineState()->pixelShader; if(widget == ui->stagesTabs->widget(7)) - return &m_Ctx.CurD3D11PipelineState().pixelShader; + return &m_Ctx.CurD3D11PipelineState()->pixelShader; if(widget == ui->stagesTabs->widget(8)) - return &m_Ctx.CurD3D11PipelineState().computeShader; + return &m_Ctx.CurD3D11PipelineState()->computeShader; widget = widget->parentWidget(); } @@ -1107,7 +1107,7 @@ void D3D11PipelineStateViewer::setState() return; } - const D3D11Pipe::State &state = m_Ctx.CurD3D11PipelineState(); + const D3D11Pipe::State &state = *m_Ctx.CurD3D11PipelineState(); const DrawcallDescription *draw = m_Ctx.CurDrawcall(); const QPixmap &tick = Pixmaps::tick(this); @@ -1879,12 +1879,12 @@ void D3D11PipelineStateViewer::resource_itemActivated(RDTreeWidgetItem *item, in if(stage->stage == ShaderStage::Geometry) { - for(int i = 0; i < m_Ctx.CurD3D11PipelineState().streamOut.outputs.count(); i++) + for(int i = 0; i < m_Ctx.CurD3D11PipelineState()->streamOut.outputs.count(); i++) { - if(buf->resourceId == m_Ctx.CurD3D11PipelineState().streamOut.outputs[i].resourceId) + if(buf->resourceId == m_Ctx.CurD3D11PipelineState()->streamOut.outputs[i].resourceId) { - size -= m_Ctx.CurD3D11PipelineState().streamOut.outputs[i].byteOffset; - offs += m_Ctx.CurD3D11PipelineState().streamOut.outputs[i].byteOffset; + size -= m_Ctx.CurD3D11PipelineState()->streamOut.outputs[i].byteOffset; + offs += m_Ctx.CurD3D11PipelineState()->streamOut.outputs[i].byteOffset; break; } } @@ -1906,7 +1906,7 @@ void D3D11PipelineStateViewer::resource_itemActivated(RDTreeWidgetItem *item, in // bound in the PS but only in an earlier stage. if(view.type == D3D11ViewTag::UAV && stage->stage != ShaderStage::Compute) { - const D3D11Pipe::State &state = m_Ctx.CurD3D11PipelineState(); + const D3D11Pipe::State &state = *m_Ctx.CurD3D11PipelineState(); const D3D11Pipe::Shader *nonCS[] = {&state.vertexShader, &state.domainShader, &state.hullShader, &state.geometryShader, &state.pixelShader}; @@ -2127,7 +2127,7 @@ void D3D11PipelineStateViewer::highlightIABind(int slot) { int idx = ((slot + 1) * 21) % 32; // space neighbouring colours reasonably distinctly - const D3D11Pipe::InputAssembly &IA = m_Ctx.CurD3D11PipelineState().inputAssembly; + const D3D11Pipe::InputAssembly &IA = m_Ctx.CurD3D11PipelineState()->inputAssembly; QColor col = QColor::fromHslF(float(idx) / 32.0f, 1.0f, qBound(0.05, palette().color(QPalette::Base).lightnessF(), 0.95)); @@ -2172,7 +2172,7 @@ void D3D11PipelineStateViewer::on_iaLayouts_mouseMove(QMouseEvent *e) vertex_leave(NULL); - const D3D11Pipe::InputAssembly &IA = m_Ctx.CurD3D11PipelineState().inputAssembly; + const D3D11Pipe::InputAssembly &IA = m_Ctx.CurD3D11PipelineState()->inputAssembly; if(idx.isValid()) { @@ -2246,7 +2246,7 @@ void D3D11PipelineStateViewer::shaderView_clicked() QWidget *sender = qobject_cast(QObject::sender()); if(sender == ui->iaBytecode || sender == ui->iaBytecodeViewButton) { - shaderDetails = m_Ctx.CurD3D11PipelineState().inputAssembly.bytecode; + shaderDetails = m_Ctx.CurD3D11PipelineState()->inputAssembly.bytecode; } else { @@ -2988,7 +2988,7 @@ void D3D11PipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const D3D11Pipe continue; rows.push_back(exportViewHTML(om.uavs[i - om.uavStartSlot], i, - m_Ctx.CurD3D11PipelineState().pixelShader.reflection, QString())); + m_Ctx.CurD3D11PipelineState()->pixelShader.reflection, QString())); } m_Common.exportHTMLTable(xml, @@ -3057,18 +3057,18 @@ void D3D11PipelineStateViewer::on_exportHTML_clicked() switch(stage) { - case 0: exportHTML(xml, m_Ctx.CurD3D11PipelineState().inputAssembly); break; - case 1: exportHTML(xml, m_Ctx.CurD3D11PipelineState().vertexShader); break; - case 2: exportHTML(xml, m_Ctx.CurD3D11PipelineState().hullShader); break; - case 3: exportHTML(xml, m_Ctx.CurD3D11PipelineState().domainShader); break; + case 0: exportHTML(xml, m_Ctx.CurD3D11PipelineState()->inputAssembly); break; + case 1: exportHTML(xml, m_Ctx.CurD3D11PipelineState()->vertexShader); break; + case 2: exportHTML(xml, m_Ctx.CurD3D11PipelineState()->hullShader); break; + case 3: exportHTML(xml, m_Ctx.CurD3D11PipelineState()->domainShader); break; case 4: - exportHTML(xml, m_Ctx.CurD3D11PipelineState().geometryShader); - exportHTML(xml, m_Ctx.CurD3D11PipelineState().streamOut); + exportHTML(xml, m_Ctx.CurD3D11PipelineState()->geometryShader); + exportHTML(xml, m_Ctx.CurD3D11PipelineState()->streamOut); break; - case 5: exportHTML(xml, m_Ctx.CurD3D11PipelineState().rasterizer); break; - case 6: exportHTML(xml, m_Ctx.CurD3D11PipelineState().pixelShader); break; - case 7: exportHTML(xml, m_Ctx.CurD3D11PipelineState().outputMerger); break; - case 8: exportHTML(xml, m_Ctx.CurD3D11PipelineState().computeShader); break; + case 5: exportHTML(xml, m_Ctx.CurD3D11PipelineState()->rasterizer); break; + case 6: exportHTML(xml, m_Ctx.CurD3D11PipelineState()->pixelShader); break; + case 7: exportHTML(xml, m_Ctx.CurD3D11PipelineState()->outputMerger); break; + case 8: exportHTML(xml, m_Ctx.CurD3D11PipelineState()->computeShader); break; } xml.writeEndElement(); @@ -3097,7 +3097,7 @@ void D3D11PipelineStateViewer::on_debugThread_clicked() if(!draw) return; - ShaderReflection *shaderDetails = m_Ctx.CurD3D11PipelineState().computeShader.reflection; + ShaderReflection *shaderDetails = m_Ctx.CurD3D11PipelineState()->computeShader.reflection; if(!shaderDetails) return; diff --git a/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp index 406e2d143..d5bfb9d69 100644 --- a/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/D3D12PipelineStateViewer.cpp @@ -529,7 +529,7 @@ void D3D12PipelineStateViewer::setViewDetails(RDTreeWidgetItem *node, const D3D1 bool viewdetails = false; - for(const D3D12Pipe::ResourceData &im : m_Ctx.CurD3D12PipelineState().resourceStates) + for(const D3D12Pipe::ResourceData &im : m_Ctx.CurD3D12PipelineState()->resourceStates) { if(im.resourceId == tex->resourceId) { @@ -549,9 +549,9 @@ void D3D12PipelineStateViewer::setViewDetails(RDTreeWidgetItem *node, const D3D1 if(view.space == D3D12ViewTag::OMDepth) { - if(m_Ctx.CurD3D12PipelineState().outputMerger.depthReadOnly) + if(m_Ctx.CurD3D12PipelineState()->outputMerger.depthReadOnly) text += tr("Depth component is read-only\n"); - if(m_Ctx.CurD3D12PipelineState().outputMerger.stencilReadOnly) + if(m_Ctx.CurD3D12PipelineState()->outputMerger.stencilReadOnly) text += tr("Stencil component is read-only\n"); } @@ -605,7 +605,7 @@ void D3D12PipelineStateViewer::setViewDetails(RDTreeWidgetItem *node, const D3D1 const D3D12Pipe::View &res = view.res; - for(const D3D12Pipe::ResourceData &im : m_Ctx.CurD3D12PipelineState().resourceStates) + for(const D3D12Pipe::ResourceData &im : m_Ctx.CurD3D12PipelineState()->resourceStates) { if(im.resourceId == buf->resourceId) { @@ -683,8 +683,8 @@ void D3D12PipelineStateViewer::addResourceRow(const D3D12ViewTag &view, bool viewDetails = false; if(view.type == D3D12ViewTag::OMDepth) - viewDetails = m_Ctx.CurD3D12PipelineState().outputMerger.depthReadOnly || - m_Ctx.CurD3D12PipelineState().outputMerger.stencilReadOnly; + viewDetails = m_Ctx.CurD3D12PipelineState()->outputMerger.depthReadOnly || + m_Ctx.CurD3D12PipelineState()->outputMerger.stencilReadOnly; QString rootel = r.immediate ? tr("#%1 Direct").arg(r.rootElement) : tr("#%1 Table[%2]").arg(r.rootElement).arg(r.tableIndex); @@ -842,23 +842,23 @@ const D3D12Pipe::Shader *D3D12PipelineStateViewer::stageForSender(QWidget *widge while(widget) { if(widget == ui->stagesTabs->widget(0)) - return &m_Ctx.CurD3D12PipelineState().vertexShader; + return &m_Ctx.CurD3D12PipelineState()->vertexShader; if(widget == ui->stagesTabs->widget(1)) - return &m_Ctx.CurD3D12PipelineState().vertexShader; + return &m_Ctx.CurD3D12PipelineState()->vertexShader; if(widget == ui->stagesTabs->widget(2)) - return &m_Ctx.CurD3D12PipelineState().hullShader; + return &m_Ctx.CurD3D12PipelineState()->hullShader; if(widget == ui->stagesTabs->widget(3)) - return &m_Ctx.CurD3D12PipelineState().domainShader; + return &m_Ctx.CurD3D12PipelineState()->domainShader; if(widget == ui->stagesTabs->widget(4)) - return &m_Ctx.CurD3D12PipelineState().geometryShader; + return &m_Ctx.CurD3D12PipelineState()->geometryShader; if(widget == ui->stagesTabs->widget(5)) - return &m_Ctx.CurD3D12PipelineState().pixelShader; + return &m_Ctx.CurD3D12PipelineState()->pixelShader; if(widget == ui->stagesTabs->widget(6)) - return &m_Ctx.CurD3D12PipelineState().pixelShader; + return &m_Ctx.CurD3D12PipelineState()->pixelShader; if(widget == ui->stagesTabs->widget(7)) - return &m_Ctx.CurD3D12PipelineState().pixelShader; + return &m_Ctx.CurD3D12PipelineState()->pixelShader; if(widget == ui->stagesTabs->widget(8)) - return &m_Ctx.CurD3D12PipelineState().computeShader; + return &m_Ctx.CurD3D12PipelineState()->computeShader; widget = widget->parentWidget(); } @@ -952,7 +952,7 @@ void D3D12PipelineStateViewer::setShaderState(const D3D12Pipe::Shader &stage, RD RDTreeWidget *uavs) { ShaderReflection *shaderDetails = stage.reflection; - const D3D12Pipe::State &state = m_Ctx.CurD3D12PipelineState(); + const D3D12Pipe::State &state = *m_Ctx.CurD3D12PipelineState(); rootSig->setText(ToQStr(state.rootSignatureResourceId)); @@ -1239,7 +1239,7 @@ void D3D12PipelineStateViewer::setState() return; } - const D3D12Pipe::State &state = m_Ctx.CurD3D12PipelineState(); + const D3D12Pipe::State &state = *m_Ctx.CurD3D12PipelineState(); const DrawcallDescription *draw = m_Ctx.CurDrawcall(); const QPixmap &tick = Pixmaps::tick(this); @@ -1777,14 +1777,14 @@ void D3D12PipelineStateViewer::resource_itemActivated(RDTreeWidgetItem *item, in { // last thing, see if it's a streamout buffer - if(stage == &m_Ctx.CurD3D12PipelineState().geometryShader) + if(stage == &m_Ctx.CurD3D12PipelineState()->geometryShader) { - for(int i = 0; i < m_Ctx.CurD3D12PipelineState().streamOut.outputs.count(); i++) + for(int i = 0; i < m_Ctx.CurD3D12PipelineState()->streamOut.outputs.count(); i++) { - if(buf->resourceId == m_Ctx.CurD3D12PipelineState().streamOut.outputs[i].resourceId) + if(buf->resourceId == m_Ctx.CurD3D12PipelineState()->streamOut.outputs[i].resourceId) { - size -= m_Ctx.CurD3D12PipelineState().streamOut.outputs[i].byteOffset; - offs += m_Ctx.CurD3D12PipelineState().streamOut.outputs[i].byteOffset; + size -= m_Ctx.CurD3D12PipelineState()->streamOut.outputs[i].byteOffset; + offs += m_Ctx.CurD3D12PipelineState()->streamOut.outputs[i].byteOffset; break; } } @@ -1979,7 +1979,7 @@ void D3D12PipelineStateViewer::highlightIABind(int slot) { int idx = ((slot + 1) * 21) % 32; // space neighbouring colours reasonably distinctly - const D3D12Pipe::InputAssembly &IA = m_Ctx.CurD3D12PipelineState().inputAssembly; + const D3D12Pipe::InputAssembly &IA = m_Ctx.CurD3D12PipelineState()->inputAssembly; QColor col = QColor::fromHslF(float(idx) / 32.0f, 1.0f, qBound(0.05, palette().color(QPalette::Base).lightnessF(), 0.95)); @@ -2022,7 +2022,7 @@ void D3D12PipelineStateViewer::on_iaLayouts_mouseMove(QMouseEvent *e) vertex_leave(NULL); - const D3D12Pipe::InputAssembly &IA = m_Ctx.CurD3D12PipelineState().inputAssembly; + const D3D12Pipe::InputAssembly &IA = m_Ctx.CurD3D12PipelineState()->inputAssembly; if(idx.isValid()) { @@ -2098,7 +2098,7 @@ void D3D12PipelineStateViewer::shaderView_clicked() return; IShaderViewer *shad = - m_Ctx.ViewShader(stage->reflection, m_Ctx.CurD3D12PipelineState().pipelineResourceId); + m_Ctx.ViewShader(stage->reflection, m_Ctx.CurD3D12PipelineState()->pipelineResourceId); m_Ctx.AddDockWindow(shad->Widget(), DockReference::AddTo, this); } @@ -2378,7 +2378,7 @@ void D3D12PipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const D3D12Pipe QString shadername = tr("Unknown"); - const D3D12Pipe::State &state = m_Ctx.CurD3D12PipelineState(); + const D3D12Pipe::State &state = *m_Ctx.CurD3D12PipelineState(); if(sh.resourceId == ResourceId()) shadername = tr("Unbound"); @@ -3010,6 +3010,9 @@ void D3D12PipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const D3D12Pipe void D3D12PipelineStateViewer::on_exportHTML_clicked() { + if(!m_Ctx.IsCaptureLoaded()) + return; + QXmlStreamWriter *xmlptr = m_Common.beginHTMLExport(); if(xmlptr) @@ -3037,18 +3040,18 @@ void D3D12PipelineStateViewer::on_exportHTML_clicked() switch(stage) { - case 0: exportHTML(xml, m_Ctx.CurD3D12PipelineState().inputAssembly); break; - case 1: exportHTML(xml, m_Ctx.CurD3D12PipelineState().vertexShader); break; - case 2: exportHTML(xml, m_Ctx.CurD3D12PipelineState().hullShader); break; - case 3: exportHTML(xml, m_Ctx.CurD3D12PipelineState().domainShader); break; + case 0: exportHTML(xml, m_Ctx.CurD3D12PipelineState()->inputAssembly); break; + case 1: exportHTML(xml, m_Ctx.CurD3D12PipelineState()->vertexShader); break; + case 2: exportHTML(xml, m_Ctx.CurD3D12PipelineState()->hullShader); break; + case 3: exportHTML(xml, m_Ctx.CurD3D12PipelineState()->domainShader); break; case 4: - exportHTML(xml, m_Ctx.CurD3D12PipelineState().geometryShader); - exportHTML(xml, m_Ctx.CurD3D12PipelineState().streamOut); + exportHTML(xml, m_Ctx.CurD3D12PipelineState()->geometryShader); + exportHTML(xml, m_Ctx.CurD3D12PipelineState()->streamOut); break; - case 5: exportHTML(xml, m_Ctx.CurD3D12PipelineState().rasterizer); break; - case 6: exportHTML(xml, m_Ctx.CurD3D12PipelineState().pixelShader); break; - case 7: exportHTML(xml, m_Ctx.CurD3D12PipelineState().outputMerger); break; - case 8: exportHTML(xml, m_Ctx.CurD3D12PipelineState().computeShader); break; + case 5: exportHTML(xml, m_Ctx.CurD3D12PipelineState()->rasterizer); break; + case 6: exportHTML(xml, m_Ctx.CurD3D12PipelineState()->pixelShader); break; + case 7: exportHTML(xml, m_Ctx.CurD3D12PipelineState()->outputMerger); break; + case 8: exportHTML(xml, m_Ctx.CurD3D12PipelineState()->computeShader); break; } xml.writeEndElement(); diff --git a/qrenderdoc/Windows/PipelineState/GLPipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/GLPipelineStateViewer.cpp index d05432336..a8b074bc9 100644 --- a/qrenderdoc/Windows/PipelineState/GLPipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/GLPipelineStateViewer.cpp @@ -480,23 +480,23 @@ const GLPipe::Shader *GLPipelineStateViewer::stageForSender(QWidget *widget) while(widget) { if(widget == ui->stagesTabs->widget(0)) - return &m_Ctx.CurGLPipelineState().vertexShader; + return &m_Ctx.CurGLPipelineState()->vertexShader; if(widget == ui->stagesTabs->widget(1)) - return &m_Ctx.CurGLPipelineState().vertexShader; + return &m_Ctx.CurGLPipelineState()->vertexShader; if(widget == ui->stagesTabs->widget(2)) - return &m_Ctx.CurGLPipelineState().tessControlShader; + return &m_Ctx.CurGLPipelineState()->tessControlShader; if(widget == ui->stagesTabs->widget(3)) - return &m_Ctx.CurGLPipelineState().tessEvalShader; + return &m_Ctx.CurGLPipelineState()->tessEvalShader; if(widget == ui->stagesTabs->widget(4)) - return &m_Ctx.CurGLPipelineState().geometryShader; + return &m_Ctx.CurGLPipelineState()->geometryShader; if(widget == ui->stagesTabs->widget(5)) - return &m_Ctx.CurGLPipelineState().fragmentShader; + return &m_Ctx.CurGLPipelineState()->fragmentShader; if(widget == ui->stagesTabs->widget(6)) - return &m_Ctx.CurGLPipelineState().fragmentShader; + return &m_Ctx.CurGLPipelineState()->fragmentShader; if(widget == ui->stagesTabs->widget(7)) - return &m_Ctx.CurGLPipelineState().fragmentShader; + return &m_Ctx.CurGLPipelineState()->fragmentShader; if(widget == ui->stagesTabs->widget(8)) - return &m_Ctx.CurGLPipelineState().computeShader; + return &m_Ctx.CurGLPipelineState()->computeShader; widget = widget->parentWidget(); } @@ -599,7 +599,7 @@ void GLPipelineStateViewer::setShaderState(const GLPipe::Shader &stage, RDLabel { ShaderReflection *shaderDetails = stage.reflection; const ShaderBindpointMapping &mapping = stage.bindpointMapping; - const GLPipe::State &state = m_Ctx.CurGLPipelineState(); + const GLPipe::State &state = *m_Ctx.CurGLPipelineState(); if(stage.shaderResourceId == ResourceId()) { @@ -1148,7 +1148,7 @@ void GLPipelineStateViewer::setState() return; } - const GLPipe::State &state = m_Ctx.CurGLPipelineState(); + const GLPipe::State &state = *m_Ctx.CurGLPipelineState(); const DrawcallDescription *draw = m_Ctx.CurDrawcall(); bool showDisabled = ui->showDisabled->isChecked(); @@ -2145,7 +2145,7 @@ void GLPipelineStateViewer::highlightIABind(int slot) { int idx = ((slot + 1) * 21) % 32; // space neighbouring colours reasonably distinctly - const GLPipe::VertexInput &VI = m_Ctx.CurGLPipelineState().vertexInput; + const GLPipe::VertexInput &VI = m_Ctx.CurGLPipelineState()->vertexInput; QColor col = QColor::fromHslF(float(idx) / 32.0f, 1.0f, qBound(0.05, palette().color(QPalette::Base).lightnessF(), 0.95)); @@ -2188,7 +2188,7 @@ void GLPipelineStateViewer::on_viAttrs_mouseMove(QMouseEvent *e) vertex_leave(NULL); - const GLPipe::VertexInput &VI = m_Ctx.CurGLPipelineState().vertexInput; + const GLPipe::VertexInput &VI = m_Ctx.CurGLPipelineState()->vertexInput; if(idx.isValid()) { @@ -2314,7 +2314,7 @@ void GLPipelineStateViewer::shaderSave_clicked() void GLPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const GLPipe::VertexInput &vtx) { - const GLPipe::State &pipe = m_Ctx.CurGLPipelineState(); + const GLPipe::State &pipe = *m_Ctx.CurGLPipelineState(); { xml.writeStartElement(tr("h3")); xml.writeCharacters(tr("Vertex Attributes")); @@ -2463,7 +2463,7 @@ void GLPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const GLPipe::Vert void GLPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const GLPipe::Shader &sh) { - const GLPipe::State &pipe = m_Ctx.CurGLPipelineState(); + const GLPipe::State &pipe = *m_Ctx.CurGLPipelineState(); ShaderReflection *shaderDetails = sh.reflection; const ShaderBindpointMapping &mapping = sh.bindpointMapping; @@ -2906,7 +2906,7 @@ void GLPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const GLPipe::Shad void GLPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const GLPipe::Feedback &xfb) { - const GLPipe::State &pipe = m_Ctx.CurGLPipelineState(); + const GLPipe::State &pipe = *m_Ctx.CurGLPipelineState(); { xml.writeStartElement(tr("h3")); xml.writeCharacters(tr("States")); @@ -2952,7 +2952,7 @@ void GLPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const GLPipe::Feed void GLPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const GLPipe::Rasterizer &rs) { - const GLPipe::State &pipe = m_Ctx.CurGLPipelineState(); + const GLPipe::State &pipe = *m_Ctx.CurGLPipelineState(); xml.writeStartElement(tr("h3")); xml.writeCharacters(tr("Rasterizer")); xml.writeEndElement(); @@ -3069,7 +3069,7 @@ void GLPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const GLPipe::Rast void GLPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const GLPipe::FrameBuffer &fb) { - const GLPipe::State &pipe = m_Ctx.CurGLPipelineState(); + const GLPipe::State &pipe = *m_Ctx.CurGLPipelineState(); { xml.writeStartElement(tr("h3")); xml.writeCharacters(tr("Blend State")); @@ -3315,18 +3315,18 @@ void GLPipelineStateViewer::on_exportHTML_clicked() switch(stage) { - case 0: exportHTML(xml, m_Ctx.CurGLPipelineState().vertexInput); break; - case 1: exportHTML(xml, m_Ctx.CurGLPipelineState().vertexShader); break; - case 2: exportHTML(xml, m_Ctx.CurGLPipelineState().tessControlShader); break; - case 3: exportHTML(xml, m_Ctx.CurGLPipelineState().tessEvalShader); break; + case 0: exportHTML(xml, m_Ctx.CurGLPipelineState()->vertexInput); break; + case 1: exportHTML(xml, m_Ctx.CurGLPipelineState()->vertexShader); break; + case 2: exportHTML(xml, m_Ctx.CurGLPipelineState()->tessControlShader); break; + case 3: exportHTML(xml, m_Ctx.CurGLPipelineState()->tessEvalShader); break; case 4: - exportHTML(xml, m_Ctx.CurGLPipelineState().geometryShader); - exportHTML(xml, m_Ctx.CurGLPipelineState().transformFeedback); + exportHTML(xml, m_Ctx.CurGLPipelineState()->geometryShader); + exportHTML(xml, m_Ctx.CurGLPipelineState()->transformFeedback); break; - case 5: exportHTML(xml, m_Ctx.CurGLPipelineState().rasterizer); break; - case 6: exportHTML(xml, m_Ctx.CurGLPipelineState().fragmentShader); break; - case 7: exportHTML(xml, m_Ctx.CurGLPipelineState().framebuffer); break; - case 8: exportHTML(xml, m_Ctx.CurGLPipelineState().computeShader); break; + case 5: exportHTML(xml, m_Ctx.CurGLPipelineState()->rasterizer); break; + case 6: exportHTML(xml, m_Ctx.CurGLPipelineState()->fragmentShader); break; + case 7: exportHTML(xml, m_Ctx.CurGLPipelineState()->framebuffer); break; + case 8: exportHTML(xml, m_Ctx.CurGLPipelineState()->computeShader); break; } xml.writeEndElement(); diff --git a/qrenderdoc/Windows/PipelineState/PipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/PipelineStateViewer.cpp index 10c165b3f..a4fd58011 100644 --- a/qrenderdoc/Windows/PipelineState/PipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/PipelineStateViewer.cpp @@ -87,9 +87,6 @@ void PipelineStateViewer::OnCaptureClosed() void PipelineStateViewer::OnEventChanged(uint32_t eventId) { - if(m_Ctx.CurPipelineState().defaultType != m_Ctx.APIProps().pipelineType) - OnCaptureLoaded(); - if(m_Current) m_Current->OnEventChanged(eventId); } @@ -156,7 +153,6 @@ void PipelineStateViewer::setToD3D11() m_D3D11 = new D3D11PipelineStateViewer(m_Ctx, *this, this); ui->layout->addWidget(m_D3D11); m_Current = m_D3D11; - m_Ctx.CurPipelineState().defaultType = GraphicsAPI::D3D11; } void PipelineStateViewer::setToD3D12() @@ -169,7 +165,6 @@ void PipelineStateViewer::setToD3D12() m_D3D12 = new D3D12PipelineStateViewer(m_Ctx, *this, this); ui->layout->addWidget(m_D3D12); m_Current = m_D3D12; - m_Ctx.CurPipelineState().defaultType = GraphicsAPI::D3D12; } void PipelineStateViewer::setToGL() @@ -182,7 +177,6 @@ void PipelineStateViewer::setToGL() m_GL = new GLPipelineStateViewer(m_Ctx, *this, this); ui->layout->addWidget(m_GL); m_Current = m_GL; - m_Ctx.CurPipelineState().defaultType = GraphicsAPI::OpenGL; } void PipelineStateViewer::setToVulkan() @@ -195,7 +189,6 @@ void PipelineStateViewer::setToVulkan() m_Vulkan = new VulkanPipelineStateViewer(m_Ctx, *this, this); ui->layout->addWidget(m_Vulkan); m_Current = m_Vulkan; - m_Ctx.CurPipelineState().defaultType = GraphicsAPI::Vulkan; } QXmlStreamWriter *PipelineStateViewer::beginHTMLExport() diff --git a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp index ee30f6e99..b7b1b666e 100644 --- a/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp +++ b/qrenderdoc/Windows/PipelineState/VulkanPipelineStateViewer.cpp @@ -395,7 +395,7 @@ void VulkanPipelineStateViewer::setViewDetails(RDTreeWidgetItem *node, const bin bool viewdetails = false; { - for(const VKPipe::ImageData &im : m_Ctx.CurVulkanPipelineState().images) + for(const VKPipe::ImageData &im : m_Ctx.CurVulkanPipelineState()->images) { if(im.resourceId == tex->resourceId) { @@ -508,23 +508,23 @@ const VKPipe::Shader *VulkanPipelineStateViewer::stageForSender(QWidget *widget) while(widget) { if(widget == ui->stagesTabs->widget(0)) - return &m_Ctx.CurVulkanPipelineState().vertexShader; + return &m_Ctx.CurVulkanPipelineState()->vertexShader; if(widget == ui->stagesTabs->widget(1)) - return &m_Ctx.CurVulkanPipelineState().vertexShader; + return &m_Ctx.CurVulkanPipelineState()->vertexShader; if(widget == ui->stagesTabs->widget(2)) - return &m_Ctx.CurVulkanPipelineState().tessControlShader; + return &m_Ctx.CurVulkanPipelineState()->tessControlShader; if(widget == ui->stagesTabs->widget(3)) - return &m_Ctx.CurVulkanPipelineState().tessEvalShader; + return &m_Ctx.CurVulkanPipelineState()->tessEvalShader; if(widget == ui->stagesTabs->widget(4)) - return &m_Ctx.CurVulkanPipelineState().geometryShader; + return &m_Ctx.CurVulkanPipelineState()->geometryShader; if(widget == ui->stagesTabs->widget(5)) - return &m_Ctx.CurVulkanPipelineState().fragmentShader; + return &m_Ctx.CurVulkanPipelineState()->fragmentShader; if(widget == ui->stagesTabs->widget(6)) - return &m_Ctx.CurVulkanPipelineState().fragmentShader; + return &m_Ctx.CurVulkanPipelineState()->fragmentShader; if(widget == ui->stagesTabs->widget(7)) - return &m_Ctx.CurVulkanPipelineState().fragmentShader; + return &m_Ctx.CurVulkanPipelineState()->fragmentShader; if(widget == ui->stagesTabs->widget(8)) - return &m_Ctx.CurVulkanPipelineState().computeShader; + return &m_Ctx.CurVulkanPipelineState()->computeShader; widget = widget->parentWidget(); } @@ -1496,7 +1496,7 @@ void VulkanPipelineStateViewer::setState() m_CombinedImageSamplers.clear(); - const VKPipe::State &state = m_Ctx.CurVulkanPipelineState(); + const VKPipe::State &state = *m_Ctx.CurVulkanPipelineState(); const DrawcallDescription *draw = m_Ctx.CurDrawcall(); bool showDisabled = ui->showDisabled->isChecked(); @@ -2226,7 +2226,7 @@ void VulkanPipelineStateViewer::highlightIABind(int slot) { int idx = ((slot + 1) * 21) % 32; // space neighbouring colours reasonably distinctly - const VKPipe::VertexInput &VI = m_Ctx.CurVulkanPipelineState().vertexInput; + const VKPipe::VertexInput &VI = m_Ctx.CurVulkanPipelineState()->vertexInput; QColor col = QColor::fromHslF(float(idx) / 32.0f, 1.0f, qBound(0.05, palette().color(QPalette::Base).lightnessF(), 0.95)); @@ -2275,7 +2275,7 @@ void VulkanPipelineStateViewer::on_viAttrs_mouseMove(QMouseEvent *e) vertex_leave(NULL); - const VKPipe::VertexInput &VI = m_Ctx.CurVulkanPipelineState().vertexInput; + const VKPipe::VertexInput &VI = m_Ctx.CurVulkanPipelineState()->vertexInput; if(idx.isValid()) { @@ -2348,8 +2348,8 @@ void VulkanPipelineStateViewer::shaderView_clicked() ShaderReflection *shaderDetails = stage->reflection; ResourceId pipe = stage->stage == ShaderStage::Compute - ? m_Ctx.CurVulkanPipelineState().compute.pipelineResourceId - : m_Ctx.CurVulkanPipelineState().graphics.pipelineResourceId; + ? m_Ctx.CurVulkanPipelineState()->compute.pipelineResourceId + : m_Ctx.CurVulkanPipelineState()->graphics.pipelineResourceId; IShaderViewer *shad = m_Ctx.ViewShader(shaderDetails, pipe); @@ -2367,8 +2367,8 @@ void VulkanPipelineStateViewer::shaderEdit_clicked() const ShaderReflection *shaderDetails = stage->reflection; ResourceId pipe = stage->stage == ShaderStage::Compute - ? m_Ctx.CurVulkanPipelineState().compute.pipelineResourceId - : m_Ctx.CurVulkanPipelineState().graphics.pipelineResourceId; + ? m_Ctx.CurVulkanPipelineState()->compute.pipelineResourceId + : m_Ctx.CurVulkanPipelineState()->graphics.pipelineResourceId; if(!shaderDetails) return; @@ -2526,7 +2526,7 @@ void VulkanPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const VKPipe:: m_Common.exportHTMLTable(xml, {tr("Primitive Topology"), tr("Tessellation Control Points")}, {ToQStr(m_Ctx.CurDrawcall()->topology), - m_Ctx.CurVulkanPipelineState().tessellation.numControlPoints}); + m_Ctx.CurVulkanPipelineState()->tessellation.numControlPoints}); } void VulkanPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const VKPipe::Shader &sh) @@ -2565,8 +2565,8 @@ void VulkanPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const VKPipe:: } const VKPipe::Pipeline &pipeline = - (sh.stage == ShaderStage::Compute ? m_Ctx.CurVulkanPipelineState().compute - : m_Ctx.CurVulkanPipelineState().graphics); + (sh.stage == ShaderStage::Compute ? m_Ctx.CurVulkanPipelineState()->compute + : m_Ctx.CurVulkanPipelineState()->graphics); if(shaderDetails && !shaderDetails->constantBlocks.isEmpty()) { @@ -2891,7 +2891,7 @@ void VulkanPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const VKPipe:: Formatter::Format(rs.slopeScaledDepthBias), Formatter::Format(rs.lineWidth)}); } - const VKPipe::MultiSample &msaa = m_Ctx.CurVulkanPipelineState().multisample; + const VKPipe::MultiSample &msaa = m_Ctx.CurVulkanPipelineState()->multisample; { xml.writeStartElement(lit("h3")); @@ -2905,7 +2905,7 @@ void VulkanPipelineStateViewer::exportHTML(QXmlStreamWriter &xml, const VKPipe:: Formatter::Format(msaa.minSampleShading), Formatter::Format(msaa.sampleMask, true)}); } - const VKPipe::ViewState &vp = m_Ctx.CurVulkanPipelineState().viewportScissor; + const VKPipe::ViewState &vp = m_Ctx.CurVulkanPipelineState()->viewportScissor; { xml.writeStartElement(lit("h3")); @@ -3188,37 +3188,37 @@ void VulkanPipelineStateViewer::on_exportHTML_clicked() xml.writeStartElement(lit("h2")); xml.writeCharacters(tr("Input Assembly")); xml.writeEndElement(); - exportHTML(xml, m_Ctx.CurVulkanPipelineState().inputAssembly); + exportHTML(xml, m_Ctx.CurVulkanPipelineState()->inputAssembly); xml.writeStartElement(lit("h2")); xml.writeCharacters(tr("Vertex Input")); xml.writeEndElement(); - exportHTML(xml, m_Ctx.CurVulkanPipelineState().vertexInput); + exportHTML(xml, m_Ctx.CurVulkanPipelineState()->vertexInput); break; - case 1: exportHTML(xml, m_Ctx.CurVulkanPipelineState().vertexShader); break; - case 2: exportHTML(xml, m_Ctx.CurVulkanPipelineState().tessControlShader); break; - case 3: exportHTML(xml, m_Ctx.CurVulkanPipelineState().tessEvalShader); break; - case 4: exportHTML(xml, m_Ctx.CurVulkanPipelineState().geometryShader); break; - case 5: exportHTML(xml, m_Ctx.CurVulkanPipelineState().rasterizer); break; - case 6: exportHTML(xml, m_Ctx.CurVulkanPipelineState().fragmentShader); break; + case 1: exportHTML(xml, m_Ctx.CurVulkanPipelineState()->vertexShader); break; + case 2: exportHTML(xml, m_Ctx.CurVulkanPipelineState()->tessControlShader); break; + case 3: exportHTML(xml, m_Ctx.CurVulkanPipelineState()->tessEvalShader); break; + case 4: exportHTML(xml, m_Ctx.CurVulkanPipelineState()->geometryShader); break; + case 5: exportHTML(xml, m_Ctx.CurVulkanPipelineState()->rasterizer); break; + case 6: exportHTML(xml, m_Ctx.CurVulkanPipelineState()->fragmentShader); break; case 7: // FB xml.writeStartElement(lit("h2")); xml.writeCharacters(tr("Color Blend")); xml.writeEndElement(); - exportHTML(xml, m_Ctx.CurVulkanPipelineState().colorBlend); + exportHTML(xml, m_Ctx.CurVulkanPipelineState()->colorBlend); xml.writeStartElement(lit("h2")); xml.writeCharacters(tr("Depth Stencil")); xml.writeEndElement(); - exportHTML(xml, m_Ctx.CurVulkanPipelineState().depthStencil); + exportHTML(xml, m_Ctx.CurVulkanPipelineState()->depthStencil); xml.writeStartElement(lit("h2")); xml.writeCharacters(tr("Current Pass")); xml.writeEndElement(); - exportHTML(xml, m_Ctx.CurVulkanPipelineState().currentPass); + exportHTML(xml, m_Ctx.CurVulkanPipelineState()->currentPass); break; - case 8: exportHTML(xml, m_Ctx.CurVulkanPipelineState().computeShader); break; + case 8: exportHTML(xml, m_Ctx.CurVulkanPipelineState()->computeShader); break; } xml.writeEndElement(); diff --git a/qrenderdoc/Windows/PythonShell.cpp b/qrenderdoc/Windows/PythonShell.cpp index bb7cc4157..730284d6b 100644 --- a/qrenderdoc/Windows/PythonShell.cpp +++ b/qrenderdoc/Windows/PythonShell.cpp @@ -116,20 +116,20 @@ struct CaptureContextInvoker : ICaptureContext virtual void MarkMessagesRead() override { return m_Ctx.MarkMessagesRead(); } virtual rdcstr GetNotes(const rdcstr &key) override { return m_Ctx.GetNotes(key); } virtual rdcarray GetBookmarks() override { return m_Ctx.GetBookmarks(); } - virtual const D3D11Pipe::State &CurD3D11PipelineState() override + virtual const D3D11Pipe::State *CurD3D11PipelineState() override { return m_Ctx.CurD3D11PipelineState(); } - virtual const D3D12Pipe::State &CurD3D12PipelineState() override + virtual const D3D12Pipe::State *CurD3D12PipelineState() override { return m_Ctx.CurD3D12PipelineState(); } - virtual const GLPipe::State &CurGLPipelineState() override { return m_Ctx.CurGLPipelineState(); } - virtual const VKPipe::State &CurVulkanPipelineState() override + virtual const GLPipe::State *CurGLPipelineState() override { return m_Ctx.CurGLPipelineState(); } + virtual const VKPipe::State *CurVulkanPipelineState() override { return m_Ctx.CurVulkanPipelineState(); } - virtual CommonPipelineState &CurPipelineState() override { return m_Ctx.CurPipelineState(); } + virtual const PipeState &CurPipelineState() override { return m_Ctx.CurPipelineState(); } virtual PersistantConfig &Config() override { return m_Ctx.Config(); } // /////////////////////////////////////////////////////////////////////// diff --git a/qrenderdoc/Windows/ShaderViewer.cpp b/qrenderdoc/Windows/ShaderViewer.cpp index f76a37929..d8385c593 100644 --- a/qrenderdoc/Windows/ShaderViewer.cpp +++ b/qrenderdoc/Windows/ShaderViewer.cpp @@ -616,10 +616,12 @@ void ShaderViewer::updateWindowTitle() { QString shaderName = m_Ctx.GetResourceName(m_ShaderDetails->resourceId); - // if the shader is currently bound, look up the name through the pipeline state. This is purely + // On D3D12, get the shader name from the pipeline rather than the shader itself // for the benefit of D3D12 which doesn't have separate shader objects - if(m_Ctx.CurPipelineState().GetShader(m_Stage) == m_ShaderDetails->resourceId) - shaderName = m_Ctx.CurPipelineState().GetShaderName(m_Stage); + if(m_Ctx.CurPipelineState().IsCaptureD3D12()) + shaderName = QFormatStr("%1 %2") + .arg(m_Ctx.GetResourceName(m_Pipeline)) + .arg(m_Ctx.CurPipelineState().Abbrev(m_ShaderDetails->stage)); if(m_Trace) setWindowTitle(QFormatStr("Debugging %1 - %2").arg(shaderName).arg(m_DebugContext)); diff --git a/qrenderdoc/qrenderdoc.pro b/qrenderdoc/qrenderdoc.pro index 53e6ce58e..b6407b805 100644 --- a/qrenderdoc/qrenderdoc.pro +++ b/qrenderdoc/qrenderdoc.pro @@ -168,7 +168,6 @@ SOURCES += Code/qrenderdoc.cpp \ Code/pyrenderdoc/PythonContext.cpp \ Code/Interface/QRDInterface.cpp \ Code/Interface/Analytics.cpp \ - Code/Interface/CommonPipelineState.cpp \ Code/Interface/SPIRVDisassembler.cpp \ Code/Interface/PersistantConfig.cpp \ Code/Interface/RemoteHost.cpp \ @@ -244,7 +243,6 @@ HEADERS += Code/CaptureContext.h \ Code/pyrenderdoc/interface_check.h \ Code/Interface/QRDInterface.h \ Code/Interface/Analytics.h \ - Code/Interface/CommonPipelineState.h \ Code/Interface/PersistantConfig.h \ Code/Interface/RemoteHost.h \ Styles/StyleData.h \ diff --git a/qrenderdoc/qrenderdoc_local.vcxproj b/qrenderdoc/qrenderdoc_local.vcxproj index 9d761c735..d1bb470b0 100644 --- a/qrenderdoc/qrenderdoc_local.vcxproj +++ b/qrenderdoc/qrenderdoc_local.vcxproj @@ -575,7 +575,6 @@ - @@ -903,7 +902,6 @@ - diff --git a/qrenderdoc/qrenderdoc_local.vcxproj.filters b/qrenderdoc/qrenderdoc_local.vcxproj.filters index 62f1a9897..44d8f4c63 100644 --- a/qrenderdoc/qrenderdoc_local.vcxproj.filters +++ b/qrenderdoc/qrenderdoc_local.vcxproj.filters @@ -579,9 +579,6 @@ Generated Files - - Code\Interface - Code\Interface @@ -1001,9 +998,6 @@ Generated Files - - Code\Interface - Code\Interface diff --git a/renderdoc/api/replay/common_pipestate.h b/renderdoc/api/replay/common_pipestate.h index 38ba8a1c4..0e9ef8429 100644 --- a/renderdoc/api/replay/common_pipestate.h +++ b/renderdoc/api/replay/common_pipestate.h @@ -24,6 +24,8 @@ #pragma once +#include "shader_types.h" + DOCUMENT("Information about a viewport."); struct Viewport { @@ -207,4 +209,177 @@ struct StencilFace uint32_t writeMask = 0; }; -DECLARE_REFLECTION_STRUCT(StencilFace); \ No newline at end of file +DECLARE_REFLECTION_STRUCT(StencilFace); + +DOCUMENT("Information about a single resource bound to a slot in an API-specific way."); +struct BoundResource +{ + DOCUMENT(""); + BoundResource() + { + resourceId = ResourceId(); + firstMip = -1; + firstSlice = -1; + typeHint = CompType::Typeless; + } + BoundResource(ResourceId id) + { + resourceId = id; + firstMip = -1; + firstSlice = -1; + typeHint = CompType::Typeless; + } + + bool operator==(const BoundResource &o) const + { + return resourceId == o.resourceId && firstMip == o.firstMip && firstSlice == o.firstSlice && + typeHint == o.typeHint; + } + bool operator<(const BoundResource &o) const + { + if(resourceId != o.resourceId) + return resourceId < o.resourceId; + if(firstMip != o.firstMip) + return firstMip < o.firstMip; + if(firstSlice != o.firstSlice) + return firstSlice < o.firstSlice; + if(typeHint != o.typeHint) + return typeHint < o.typeHint; + return false; + } + DOCUMENT("A :class:`~renderdoc.ResourceId` identifying the bound resource."); + ResourceId resourceId; + DOCUMENT("For textures, the highest mip level available on this binding, or -1 for all mips"); + int firstMip; + DOCUMENT("For textures, the first array slice available on this binding. or -1 for all slices."); + int firstSlice; + DOCUMENT( + "For textures, a :class:`~renderdoc.CompType` hint for how to interpret typeless textures."); + CompType typeHint; +}; + +DECLARE_REFLECTION_STRUCT(BoundResource); + +// TODO this should be replaced with an rdcmap +DOCUMENT(R"(Contains all of the bound resources at a particular bindpoint. In APIs that don't +support resource arrays, there will only be one bound resource. +)"); +struct BoundResourceArray +{ + DOCUMENT(""); + BoundResourceArray() = default; + BoundResourceArray(Bindpoint b) : bindPoint(b) {} + BoundResourceArray(Bindpoint b, const rdcarray &r) : bindPoint(b), resources(r) {} + // for convenience for searching the array, we compare only using the BindPoint + bool operator==(const BoundResourceArray &o) const { return bindPoint == o.bindPoint; } + bool operator!=(const BoundResourceArray &o) const { return !(bindPoint == o.bindPoint); } + bool operator<(const BoundResourceArray &o) const { return bindPoint < o.bindPoint; } + DOCUMENT("The bind point for this array of bound resources."); + Bindpoint bindPoint; + + DOCUMENT("The resources at this bind point"); + rdcarray resources; +}; + +DECLARE_REFLECTION_STRUCT(BoundResourceArray); + +DOCUMENT("Information about a single vertex or index buffer binding."); +struct BoundVBuffer +{ + DOCUMENT(""); + bool operator==(const BoundVBuffer &o) const + { + return resourceId == o.resourceId && byteOffset == o.byteOffset && byteStride == o.byteStride; + } + bool operator<(const BoundVBuffer &o) const + { + if(resourceId != o.resourceId) + return resourceId < o.resourceId; + if(byteOffset != o.byteOffset) + return byteOffset < o.byteOffset; + if(byteStride != o.byteStride) + return byteStride < o.byteStride; + return false; + } + DOCUMENT("A :class:`~renderdoc.ResourceId` identifying the buffer."); + ResourceId resourceId; + DOCUMENT("The offset in bytes from the start of the buffer to the data."); + uint64_t byteOffset = 0; + DOCUMENT("The stride in bytes between the start of one element and the start of the next."); + uint32_t byteStride = 0; +}; + +DECLARE_REFLECTION_STRUCT(BoundVBuffer); + +DOCUMENT("Information about a single constant buffer binding."); +struct BoundCBuffer +{ + DOCUMENT("A :class:`~renderdoc.ResourceId` identifying the buffer."); + ResourceId resourceId; + DOCUMENT("The offset in bytes from the start of the buffer to the constant data."); + uint64_t byteOffset = 0; + DOCUMENT("The size in bytes for the constant buffer. Access outside this size returns 0."); + uint64_t byteSize = 0; +}; + +DECLARE_REFLECTION_STRUCT(BoundCBuffer); + +DOCUMENT("Information about a vertex input attribute feeding the vertex shader."); +struct VertexInputAttribute +{ + DOCUMENT(""); + bool operator==(const VertexInputAttribute &o) const + { + return name == o.name && vertexBuffer == o.vertexBuffer && byteOffset == o.byteOffset && + perInstance == o.perInstance && instanceRate == o.instanceRate && format == o.format && + !memcmp(&genericValue, &o.genericValue, sizeof(genericValue)) && + genericEnabled == o.genericEnabled && used == o.used; + } + bool operator<(const VertexInputAttribute &o) const + { + if(name != o.name) + return name < o.name; + if(vertexBuffer != o.vertexBuffer) + return vertexBuffer < o.vertexBuffer; + if(byteOffset != o.byteOffset) + return byteOffset < o.byteOffset; + if(perInstance != o.perInstance) + return perInstance < o.perInstance; + if(instanceRate != o.instanceRate) + return instanceRate < o.instanceRate; + if(format != o.format) + return format < o.format; + if(memcmp(&genericValue, &o.genericValue, sizeof(genericValue)) < 0) + return true; + if(genericEnabled != o.genericEnabled) + return genericEnabled < o.genericEnabled; + if(used != o.used) + return used < o.used; + return false; + } + + DOCUMENT("The name of this input. This may be a variable name or a semantic name."); + rdcstr name; + DOCUMENT("The index of the vertex buffer used to provide this attribute."); + int vertexBuffer; + DOCUMENT("The byte offset from the start of the vertex data for this VB to this attribute."); + uint32_t byteOffset; + DOCUMENT("``True`` if this attribute runs at instance rate."); + bool perInstance; + DOCUMENT(R"(If :data:`perInstance` is ``True``, the number of instances that source the same value +from the vertex buffer before advancing to the next value. +)"); + int instanceRate; + DOCUMENT("A :class:`~renderdoc.ResourceFormat` with the interpreted format of this attribute."); + ResourceFormat format; + DOCUMENT(R"(A :class:`~renderdoc.PixelValue` with the generic value for this attribute if it has +no VB bound. +)"); + PixelValue genericValue; + DOCUMENT("``True`` if this attribute is using :data:`genericValue` for its data."); + bool genericEnabled; + DOCUMENT("``True`` if this attribute is enabled and used by the vertex shader."); + bool used; +}; + +DECLARE_REFLECTION_STRUCT(VertexInputAttribute); \ No newline at end of file diff --git a/renderdoc/api/replay/d3d11_pipestate.h b/renderdoc/api/replay/d3d11_pipestate.h index 61faf9e19..63eb88d20 100644 --- a/renderdoc/api/replay/d3d11_pipestate.h +++ b/renderdoc/api/replay/d3d11_pipestate.h @@ -553,6 +553,12 @@ struct Predication DOCUMENT("The full current D3D11 pipeline state."); struct State { +#if !defined(RENDERDOC_EXPORTS) + // disallow creation/copy of this object externally + State() = delete; + State(const State &) = delete; +#endif + DOCUMENT("A :class:`D3D11InputAssembly` describing the input assembly pipeline stage."); InputAssembly inputAssembly; diff --git a/renderdoc/api/replay/d3d12_pipestate.h b/renderdoc/api/replay/d3d12_pipestate.h index 5f79c9843..e8714681b 100644 --- a/renderdoc/api/replay/d3d12_pipestate.h +++ b/renderdoc/api/replay/d3d12_pipestate.h @@ -665,6 +665,12 @@ struct ResourceData DOCUMENT("The full current D3D12 pipeline state."); struct State { +#if !defined(RENDERDOC_EXPORTS) + // disallow creation/copy of this object externally + State() = delete; + State(const State &) = delete; +#endif + DOCUMENT("The :class:`ResourceId` of the pipeline state object."); ResourceId pipelineResourceId; diff --git a/renderdoc/api/replay/gl_pipestate.h b/renderdoc/api/replay/gl_pipestate.h index b9e9297a5..3571c055f 100644 --- a/renderdoc/api/replay/gl_pipestate.h +++ b/renderdoc/api/replay/gl_pipestate.h @@ -624,6 +624,12 @@ struct Hints DOCUMENT("The full current OpenGL pipeline state."); struct State { +#if !defined(RENDERDOC_EXPORTS) + // disallow creation/copy of this object externally + State() = delete; + State(const State &) = delete; +#endif + DOCUMENT("A :class:`GLVertexInput` describing the vertex input stage."); VertexInput vertexInput; diff --git a/renderdoc/api/replay/pipestate.h b/renderdoc/api/replay/pipestate.h new file mode 100644 index 000000000..8be3a7a5e --- /dev/null +++ b/renderdoc/api/replay/pipestate.h @@ -0,0 +1,346 @@ +/****************************************************************************** + * The MIT License (MIT) + * + * Copyright (c) 2017-2018 Baldur Karlsson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + +#pragma once + +#include "d3d11_pipestate.h" +#include "d3d12_pipestate.h" +#include "gl_pipestate.h" +#include "vk_pipestate.h" + +DOCUMENT(R"(An API-agnostic view of the common aspects of the pipeline state. This allows simple +access to e.g. find out the bound resources or vertex buffers, or certain pipeline state which is +available on all APIs. + +For more detailed or precise information without abstraction, access the specific pipeline state +for the capture that's open. +)"); +struct PipeState +{ +public: + PipeState() = default; + // disallow copy of this object + PipeState(const PipeState &) = delete; + +#if defined(RENDERDOC_EXPORTS) + // we initialise this internally only + void SetStates(APIProperties props, const D3D11Pipe::State *d3d11, const D3D12Pipe::State *d3d12, + const GLPipe::State *gl, const VKPipe::State *vk) + { + m_PipelineType = props.pipelineType; + m_D3D11 = d3d11; + m_D3D12 = d3d12; + m_GL = gl; + m_Vulkan = vk; + } +#endif + + DOCUMENT(R"(Determines whether or not a capture is currently loaded. + +:return: A boolean indicating if a capture is currently loaded. +:rtype: ``bool`` +)"); + bool IsCaptureLoaded() const + { + return m_D3D11 != NULL || m_D3D12 != NULL || m_GL != NULL || m_Vulkan != NULL; + } + + DOCUMENT(R"(Determines whether or not a D3D11 capture is currently loaded. + +:return: A boolean indicating if a D3D11 capture is currently loaded. +:rtype: ``bool`` +)"); + bool IsCaptureD3D11() const + { + return IsCaptureLoaded() && m_PipelineType == GraphicsAPI::D3D11 && m_D3D11 != NULL; + } + + DOCUMENT(R"(Determines whether or not a D3D12 capture is currently loaded. + +:return: A boolean indicating if a D3D12 capture is currently loaded. +:rtype: ``bool`` +)"); + bool IsCaptureD3D12() const + { + return IsCaptureLoaded() && m_PipelineType == GraphicsAPI::D3D12 && m_D3D12 != NULL; + } + + DOCUMENT(R"(Determines whether or not an OpenGL capture is currently loaded. + +:return: A boolean indicating if an OpenGL capture is currently loaded. +:rtype: ``bool`` +)"); + bool IsCaptureGL() const + { + return IsCaptureLoaded() && m_PipelineType == GraphicsAPI::OpenGL && m_GL != NULL; + } + + DOCUMENT(R"(Determines whether or not a Vulkan capture is currently loaded. + +:return: A boolean indicating if a Vulkan capture is currently loaded. +:rtype: ``bool`` +)"); + bool IsCaptureVK() const + { + return IsCaptureLoaded() && m_PipelineType == GraphicsAPI::Vulkan && m_Vulkan != NULL; + } + + // add a bunch of generic properties that people can check to save having to see which pipeline + // state is valid and look at the appropriate part of it + DOCUMENT(R"(Determines whether or not tessellation is currently enabled. + +:return: A boolean indicating if tessellation is currently enabled. +:rtype: ``bool`` +)"); + bool IsTessellationEnabled() const + { + if(IsCaptureLoaded()) + { + if(IsCaptureD3D11()) + return m_D3D11 != NULL && m_D3D11->hullShader.resourceId != ResourceId(); + + if(IsCaptureD3D12()) + return m_D3D12 != NULL && m_D3D12->hullShader.resourceId != ResourceId(); + + if(IsCaptureGL()) + return m_GL != NULL && m_GL->tessEvalShader.shaderResourceId != ResourceId(); + + if(IsCaptureVK()) + return m_Vulkan != NULL && m_Vulkan->tessEvalShader.resourceId != ResourceId(); + } + + return false; + } + + DOCUMENT(R"(Determines whether or not the current capture supports binding arrays of resources. + +:return: A boolean indicating if binding arrays of resources is supported. +:rtype: ``bool`` +)"); + bool SupportsResourceArrays() const { return IsCaptureLoaded() && IsCaptureVK(); } + DOCUMENT(R"(Determines whether or not the current capture uses explicit barriers. + +:return: A boolean indicating if explicit barriers are used. +:rtype: ``bool`` +)"); + bool SupportsBarriers() const { return IsCaptureLoaded() && (IsCaptureVK() || IsCaptureD3D12()); } + DOCUMENT(R"(Determines whether or not the PostVS data is aligned in the typical fashion (ie. +vectors not crossing ``float4`` boundaries). APIs that use stream-out or transform feedback have +tightly packed data, but APIs that rewrite shaders to dump data might have these alignment +requirements. + +:return: A boolean indicating if post-VS data is aligned. +:rtype: ``bool`` +)"); + bool HasAlignedPostVSData() const { return IsCaptureLoaded() && IsCaptureVK(); } + DOCUMENT(R"(For APIs that have explicit barriers, retrieves the current layout of a resource. + +:return: The name of the current resource layout. +:rtype: ``str`` +)"); + rdcstr GetResourceLayout(ResourceId id) const; + + DOCUMENT(R"(Retrieves a suitable two or three letter abbreviation of the given shader stage. + +:param ShaderStage stage: The shader stage to abbreviate. +:return: The abbreviation of the stage. +:rtype: ``str`` +)"); + rdcstr Abbrev(ShaderStage stage) const; + + DOCUMENT(R"(Retrieves a suitable two or three letter abbreviation of the output stage. Typically +'OM' or 'FBO'. + +:return: The abbreviation of the output stage. +:rtype: ``str`` +)"); + rdcstr OutputAbbrev() const; + + DOCUMENT(R"(Retrieves the common file extension for high level shaders in the current API. + +Typically this is ``glsl`` or ``hlsl``. + +:return: The file extension with no ``.``. +:rtype: ``str`` +)"); + rdcstr GetShaderExtension() const; + + DOCUMENT(R"(Retrieves the viewport for a given index. + +:param int index: The index to retrieve. +:return: The viewport for the given index. +:rtype: Viewport +)"); + Viewport GetViewport(int index) const; + + DOCUMENT(R"(Retrieves the scissor region for a given index. + +:param int index: The index to retrieve. +:return: The scissor region for the given index. +:rtype: Scissor +)"); + Scissor GetScissor(int index) const; + + DOCUMENT(R"(Retrieves the current bindpoint mapping for a shader stage. + +This returns an empty bindpoint mapping if no shader is bound. + +:param ShaderStage stage: The shader stage to fetch. +:return: The bindpoint mapping for the given shader. +:rtype: ShaderBindpointMapping +)"); + const ShaderBindpointMapping &GetBindpointMapping(ShaderStage stage) const; + + DOCUMENT(R"(Retrieves the shader reflection information for a shader stage. + +This returns ``None`` if no shader is bound. + +:param ShaderStage stage: The shader stage to fetch. +:return: The reflection data for the given shader. +:rtype: :class:`ShaderBindpointMapping` or ``None`` +)"); + const ShaderReflection *GetShaderReflection(ShaderStage stage) const; + + DOCUMENT(R"(Retrieves the the compute pipeline state object, if applicable. + +:return: The object ID for the given pipeline object. +:rtype: ResourceId +)"); + ResourceId GetComputePipelineObject() const; + + DOCUMENT(R"(Retrieves the the graphics pipeline state object, if applicable. + +:return: The object ID for the given pipeline object. +:rtype: ResourceId +)"); + ResourceId GetGraphicsPipelineObject() const; + + DOCUMENT(R"(Retrieves the name of the entry point function for a shader stage. + +For some APIs that don't distinguish by entry point, this may be empty. + +:param ShaderStage stage: The shader stage to fetch. +:return: The entry point name for the given shader. +:rtype: ``str`` +)"); + rdcstr GetShaderEntryPoint(ShaderStage stage) const; + + DOCUMENT(R"(Retrieves the object ID of the shader bound at a shader stage. + +:param ShaderStage stage: The shader stage to fetch. +:return: The object ID for the given shader. +:rtype: ResourceId +)"); + ResourceId GetShader(ShaderStage stage) const; + + DOCUMENT(R"(Retrieves the current index buffer binding. + +:return: A :class:`BoundVBuffer` with the index buffer details. The stride is always 0. +:rtype: ``BoundVBuffer`` +)"); + BoundVBuffer GetIBuffer() const; + + DOCUMENT(R"(Determines whether or not primitive restart is enabled. + +:return: A boolean indicating if primitive restart is enabled. +:rtype: ``bool`` +)"); + bool IsStripRestartEnabled() const; + + DOCUMENT(R"(Retrieves the primitive restart index. + +:param int indexByteWidth: The width in bytes of the indices. +:return: The index value that represents a strip restart not a real index. +:rtype: ``int`` +)"); + uint32_t GetStripRestartIndex() const; + + DOCUMENT(R"(Retrieves the currently bound vertex buffers. + +:return: The list of bound vertex buffers. +:rtype: ``list`` of :class:`BoundVBuffer`. +)"); + rdcarray GetVBuffers() const; + + DOCUMENT(R"(Retrieves the currently specified vertex attributes. + +:return: The list of current vertex attributes. +:rtype: ``list`` of :class:`VertexInputAttribute`. +)"); + rdcarray GetVertexInputs() const; + + DOCUMENT(R"(Retrieves the constant buffer at a given binding. + +:param ShaderStage stage: The shader stage to fetch from. +:param int BufIdx: The index in the shader's ConstantBlocks array to look up. +:param int ArrayIdx: For APIs that support arrays of constant buffers in a single binding, the index + in that array to look up. +:return: The constant buffer at the specified binding. +:rtype: BoundCBuffer +)"); + BoundCBuffer GetConstantBuffer(ShaderStage stage, uint32_t BufIdx, uint32_t ArrayIdx) const; + + DOCUMENT(R"(Retrieves the read-only resources bound to a particular shader stage. + +:param ShaderStage stage: The shader stage to fetch from. +:return: The currently bound read-only resoruces. +:rtype: ``list`` of :class:`BoundResourceArray` entries +)"); + rdcarray GetReadOnlyResources(ShaderStage stage) const; + + DOCUMENT(R"(Retrieves the read/write resources bound to a particular shader stage. + +:param ShaderStage stage: The shader stage to fetch from. +:return: The currently bound read/write resoruces. +:rtype: ``list`` of :class:`BoundResourceArray` entries +)"); + rdcarray GetReadWriteResources(ShaderStage stage) const; + + DOCUMENT(R"(Retrieves the read/write resources bound to the depth-stencil output. + +:return: The currently bound depth-stencil resource. +:rtype: BoundResource +)"); + BoundResource GetDepthTarget() const; + + DOCUMENT(R"(Retrieves the resources bound to the color outputs. + +:return: The currently bound output targets. +:rtype: ``list`` of :class:`BoundResource`. +)"); + rdcarray GetOutputTargets() const; + +private: + const D3D11Pipe::State *m_D3D11 = NULL; + const D3D12Pipe::State *m_D3D12 = NULL; + const GLPipe::State *m_GL = NULL; + const VKPipe::State *m_Vulkan = NULL; + GraphicsAPI m_PipelineType = GraphicsAPI::D3D11; + + // helper functions + const D3D11Pipe::Shader &GetD3D11Stage(ShaderStage stage) const; + const D3D12Pipe::Shader &GetD3D12Stage(ShaderStage stage) const; + const GLPipe::Shader &GetGLStage(ShaderStage stage) const; + const VKPipe::Shader &GetVulkanStage(ShaderStage stage) const; +}; \ No newline at end of file diff --git a/qrenderdoc/Code/Interface/CommonPipelineState.cpp b/renderdoc/api/replay/pipestate.inl similarity index 84% rename from qrenderdoc/Code/Interface/CommonPipelineState.cpp rename to renderdoc/api/replay/pipestate.inl index 7efc1a81a..28a9e09f8 100644 --- a/qrenderdoc/Code/Interface/CommonPipelineState.cpp +++ b/renderdoc/api/replay/pipestate.inl @@ -1,7 +1,7 @@ /****************************************************************************** * The MIT License (MIT) * - * Copyright (c) 2016-2018 Baldur Karlsson + * Copyright (c) 2017-2018 Baldur Karlsson * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -22,11 +22,7 @@ * THE SOFTWARE. ******************************************************************************/ -#include -#include "Code/QRDUtils.h" -#include "QRDInterface.h" - -rdcstr CommonPipelineState::GetResourceLayout(ResourceId id) +rdcstr PipeState::GetResourceLayout(ResourceId id) const { if(IsCaptureLoaded()) { @@ -49,55 +45,52 @@ rdcstr CommonPipelineState::GetResourceLayout(ResourceId id) } } - return lit("Unknown"); + return "Unknown"; } -rdcstr CommonPipelineState::Abbrev(ShaderStage stage) +rdcstr PipeState::Abbrev(ShaderStage stage) const { - if(IsCaptureD3D11() || (!IsCaptureLoaded() && defaultType == GraphicsAPI::D3D11) || - IsCaptureD3D12() || (!IsCaptureLoaded() && defaultType == GraphicsAPI::D3D12)) + if(IsCaptureGL() || IsCaptureVK()) { switch(stage) { - case ShaderStage::Vertex: return lit("VS"); - case ShaderStage::Hull: return lit("HS"); - case ShaderStage::Domain: return lit("DS"); - case ShaderStage::Geometry: return lit("GS"); - case ShaderStage::Pixel: return lit("PS"); - case ShaderStage::Compute: return lit("CS"); + case ShaderStage::Vertex: return "VS"; + case ShaderStage::Tess_Control: return "TCS"; + case ShaderStage::Tess_Eval: return "TES"; + case ShaderStage::Geometry: return "GS"; + case ShaderStage::Fragment: return "FS"; + case ShaderStage::Compute: return "CS"; default: break; } } - else if(IsCaptureGL() || (!IsCaptureLoaded() && defaultType == GraphicsAPI::OpenGL) || - IsCaptureVK() || (!IsCaptureLoaded() && defaultType == GraphicsAPI::Vulkan)) + else { switch(stage) { - case ShaderStage::Vertex: return lit("VS"); - case ShaderStage::Tess_Control: return lit("TCS"); - case ShaderStage::Tess_Eval: return lit("TES"); - case ShaderStage::Geometry: return lit("GS"); - case ShaderStage::Fragment: return lit("FS"); - case ShaderStage::Compute: return lit("CS"); + case ShaderStage::Vertex: return "VS"; + case ShaderStage::Hull: return "HS"; + case ShaderStage::Domain: return "DS"; + case ShaderStage::Geometry: return "GS"; + case ShaderStage::Pixel: return "PS"; + case ShaderStage::Compute: return "CS"; default: break; } } - return lit("?S"); + return "?S"; } -rdcstr CommonPipelineState::OutputAbbrev() +rdcstr PipeState::OutputAbbrev() const { - if(IsCaptureGL() || (!IsCaptureLoaded() && defaultType == GraphicsAPI::OpenGL) || IsCaptureVK() || - (!IsCaptureLoaded() && defaultType == GraphicsAPI::Vulkan)) + if(IsCaptureGL() || IsCaptureVK()) { - return lit("FB"); + return "FB"; } - return lit("RT"); + return "RT"; } -const D3D11Pipe::Shader &CommonPipelineState::GetD3D11Stage(ShaderStage stage) +const D3D11Pipe::Shader &PipeState::GetD3D11Stage(ShaderStage stage) const { if(stage == ShaderStage::Vertex) return m_D3D11->vertexShader; @@ -112,11 +105,11 @@ const D3D11Pipe::Shader &CommonPipelineState::GetD3D11Stage(ShaderStage stage) if(stage == ShaderStage::Compute) return m_D3D11->computeShader; - qCritical() << "Error - invalid stage " << (int)stage; + RENDERDOC_LogMessage(LogType::Error, "PIPE", __FILE__, __LINE__, "Error - invalid stage"); return m_D3D11->computeShader; } -const D3D12Pipe::Shader &CommonPipelineState::GetD3D12Stage(ShaderStage stage) +const D3D12Pipe::Shader &PipeState::GetD3D12Stage(ShaderStage stage) const { if(stage == ShaderStage::Vertex) return m_D3D12->vertexShader; @@ -131,11 +124,11 @@ const D3D12Pipe::Shader &CommonPipelineState::GetD3D12Stage(ShaderStage stage) if(stage == ShaderStage::Compute) return m_D3D12->computeShader; - qCritical() << "Error - invalid stage " << (int)stage; + RENDERDOC_LogMessage(LogType::Error, "PIPE", __FILE__, __LINE__, "Error - invalid stage"); return m_D3D12->computeShader; } -const GLPipe::Shader &CommonPipelineState::GetGLStage(ShaderStage stage) +const GLPipe::Shader &PipeState::GetGLStage(ShaderStage stage) const { if(stage == ShaderStage::Vertex) return m_GL->vertexShader; @@ -150,11 +143,11 @@ const GLPipe::Shader &CommonPipelineState::GetGLStage(ShaderStage stage) if(stage == ShaderStage::Compute) return m_GL->computeShader; - qCritical() << "Error - invalid stage " << (int)stage; + RENDERDOC_LogMessage(LogType::Error, "PIPE", __FILE__, __LINE__, "Error - invalid stage"); return m_GL->computeShader; } -const VKPipe::Shader &CommonPipelineState::GetVulkanStage(ShaderStage stage) +const VKPipe::Shader &PipeState::GetVulkanStage(ShaderStage stage) const { if(stage == ShaderStage::Vertex) return m_Vulkan->vertexShader; @@ -169,22 +162,21 @@ const VKPipe::Shader &CommonPipelineState::GetVulkanStage(ShaderStage stage) if(stage == ShaderStage::Compute) return m_Vulkan->computeShader; - qCritical() << "Error - invalid stage " << (int)stage; + RENDERDOC_LogMessage(LogType::Error, "PIPE", __FILE__, __LINE__, "Error - invalid stage"); return m_Vulkan->computeShader; } -rdcstr CommonPipelineState::GetShaderExtension() +rdcstr PipeState::GetShaderExtension() const { - if(IsCaptureGL() || (!IsCaptureLoaded() && defaultType == GraphicsAPI::OpenGL) || IsCaptureVK() || - (!IsCaptureLoaded() && defaultType == GraphicsAPI::Vulkan)) + if(IsCaptureGL() || IsCaptureVK()) { - return lit("glsl"); + return "glsl"; } - return lit("hlsl"); + return "hlsl"; } -Viewport CommonPipelineState::GetViewport(int index) +Viewport PipeState::GetViewport(int index) const { Viewport ret = {}; @@ -211,7 +203,7 @@ Viewport CommonPipelineState::GetViewport(int index) return ret; } -Scissor CommonPipelineState::GetScissor(int index) +Scissor PipeState::GetScissor(int index) const { Scissor ret = {}; @@ -238,7 +230,7 @@ Scissor CommonPipelineState::GetScissor(int index) return ret; } -const ShaderBindpointMapping &CommonPipelineState::GetBindpointMapping(ShaderStage stage) +const ShaderBindpointMapping &PipeState::GetBindpointMapping(ShaderStage stage) const { if(IsCaptureLoaded()) { @@ -301,7 +293,7 @@ const ShaderBindpointMapping &CommonPipelineState::GetBindpointMapping(ShaderSta return empty; } -const ShaderReflection *CommonPipelineState::GetShaderReflection(ShaderStage stage) +const ShaderReflection *PipeState::GetShaderReflection(ShaderStage stage) const { if(IsCaptureLoaded()) { @@ -362,7 +354,7 @@ const ShaderReflection *CommonPipelineState::GetShaderReflection(ShaderStage sta return NULL; } -ResourceId CommonPipelineState::GetComputePipelineObject() +ResourceId PipeState::GetComputePipelineObject() const { if(IsCaptureLoaded() && IsCaptureVK()) { @@ -376,7 +368,7 @@ ResourceId CommonPipelineState::GetComputePipelineObject() return ResourceId(); } -ResourceId CommonPipelineState::GetGraphicsPipelineObject() +ResourceId PipeState::GetGraphicsPipelineObject() const { if(IsCaptureLoaded() && IsCaptureVK()) { @@ -390,7 +382,7 @@ ResourceId CommonPipelineState::GetGraphicsPipelineObject() return ResourceId(); } -rdcstr CommonPipelineState::GetShaderEntryPoint(ShaderStage stage) +rdcstr PipeState::GetShaderEntryPoint(ShaderStage stage) const { if(IsCaptureLoaded() && IsCaptureVK()) { @@ -406,10 +398,10 @@ rdcstr CommonPipelineState::GetShaderEntryPoint(ShaderStage stage) } } - return ""; + return "main"; } -ResourceId CommonPipelineState::GetShader(ShaderStage stage) +ResourceId PipeState::GetShader(ShaderStage stage) const { if(IsCaptureLoaded()) { @@ -470,82 +462,7 @@ ResourceId CommonPipelineState::GetShader(ShaderStage stage) return ResourceId(); } -rdcstr CommonPipelineState::GetShaderName(ShaderStage stage) -{ - if(IsCaptureLoaded()) - { - if(IsCaptureD3D11()) - { - switch(stage) - { - case ShaderStage::Vertex: return m_Ctx.GetResourceName(m_D3D11->vertexShader.resourceId); - case ShaderStage::Domain: return m_Ctx.GetResourceName(m_D3D11->domainShader.resourceId); - case ShaderStage::Hull: return m_Ctx.GetResourceName(m_D3D11->hullShader.resourceId); - case ShaderStage::Geometry: - return m_Ctx.GetResourceName(m_D3D11->geometryShader.resourceId); - case ShaderStage::Pixel: return m_Ctx.GetResourceName(m_D3D11->pixelShader.resourceId); - case ShaderStage::Compute: return m_Ctx.GetResourceName(m_D3D11->computeShader.resourceId); - default: break; - } - } - else if(IsCaptureD3D12()) - { - switch(stage) - { - case ShaderStage::Vertex: - return m_Ctx.GetResourceName(m_D3D12->pipelineResourceId) + lit(" VS"); - case ShaderStage::Domain: - return m_Ctx.GetResourceName(m_D3D12->pipelineResourceId) + lit(" DS"); - case ShaderStage::Hull: - return m_Ctx.GetResourceName(m_D3D12->pipelineResourceId) + lit(" HS"); - case ShaderStage::Geometry: - return m_Ctx.GetResourceName(m_D3D12->pipelineResourceId) + lit(" GS"); - case ShaderStage::Pixel: - return m_Ctx.GetResourceName(m_D3D12->pipelineResourceId) + lit(" PS"); - case ShaderStage::Compute: - return m_Ctx.GetResourceName(m_D3D12->pipelineResourceId) + lit(" CS"); - default: break; - } - } - else if(IsCaptureGL()) - { - switch(stage) - { - case ShaderStage::Vertex: return m_Ctx.GetResourceName(m_GL->vertexShader.shaderResourceId); - case ShaderStage::Tess_Control: - return m_Ctx.GetResourceName(m_GL->tessControlShader.shaderResourceId); - case ShaderStage::Tess_Eval: - return m_Ctx.GetResourceName(m_GL->tessEvalShader.shaderResourceId); - case ShaderStage::Geometry: - return m_Ctx.GetResourceName(m_GL->geometryShader.shaderResourceId); - case ShaderStage::Fragment: - return m_Ctx.GetResourceName(m_GL->fragmentShader.shaderResourceId); - case ShaderStage::Compute: - return m_Ctx.GetResourceName(m_GL->computeShader.shaderResourceId); - default: break; - } - } - else if(IsCaptureVK()) - { - switch(stage) - { - case ShaderStage::Vertex: return m_Ctx.GetResourceName(m_Vulkan->vertexShader.resourceId); - case ShaderStage::Domain: - return m_Ctx.GetResourceName(m_Vulkan->tessControlShader.resourceId); - case ShaderStage::Hull: return m_Ctx.GetResourceName(m_Vulkan->tessEvalShader.resourceId); - case ShaderStage::Geometry: - return m_Ctx.GetResourceName(m_Vulkan->geometryShader.resourceId); - case ShaderStage::Pixel: return m_Ctx.GetResourceName(m_Vulkan->fragmentShader.resourceId); - case ShaderStage::Compute: return m_Ctx.GetResourceName(m_Vulkan->computeShader.resourceId); - default: break; - } - } - } - - return ""; -} - -BoundVBuffer CommonPipelineState::GetIBuffer() +BoundVBuffer PipeState::GetIBuffer() const { ResourceId buf; uint64_t ByteOffset = 0; @@ -581,7 +498,7 @@ BoundVBuffer CommonPipelineState::GetIBuffer() return ret; } -bool CommonPipelineState::IsStripRestartEnabled() +bool PipeState::IsStripRestartEnabled() const { if(IsCaptureLoaded()) { @@ -607,7 +524,7 @@ bool CommonPipelineState::IsStripRestartEnabled() return false; } -uint32_t CommonPipelineState::GetStripRestartIndex() +uint32_t PipeState::GetStripRestartIndex() const { if(IsCaptureLoaded()) { @@ -622,14 +539,14 @@ uint32_t CommonPipelineState::GetStripRestartIndex() } else if(IsCaptureGL()) { - return qMin(UINT32_MAX, m_GL->vertexInput.restartIndex); + return std::min(UINT32_MAX, m_GL->vertexInput.restartIndex); } } return UINT32_MAX; } -rdcarray CommonPipelineState::GetVBuffers() +rdcarray PipeState::GetVBuffers() const { rdcarray ret; @@ -684,8 +601,19 @@ rdcarray CommonPipelineState::GetVBuffers() return ret; } -rdcarray CommonPipelineState::GetVertexInputs() +rdcarray PipeState::GetVertexInputs() const { + auto striequal = [](const std::string &a, const std::string &b) { + if(a.length() != b.length()) + return false; + + for(size_t i = 0; i < a.length(); i++) + if(toupper(a[i]) == toupper(b[i])) + return false; + + return true; + }; + if(IsCaptureLoaded()) { if(IsCaptureD3D11()) @@ -698,12 +626,12 @@ rdcarray CommonPipelineState::GetVertexInputs() ret.resize(layouts.size()); for(int i = 0; i < layouts.count(); i++) { - QString semName = layouts[i].semanticName; + std::string semName = layouts[i].semanticName; bool needsSemanticIdx = false; for(int j = 0; j < layouts.count(); j++) { - if(i != j && !semName.compare(layouts[j].semanticName, Qt::CaseInsensitive)) + if(i != j && !striequal(semName, layouts[j].semanticName)) { needsSemanticIdx = true; break; @@ -719,8 +647,7 @@ rdcarray CommonPipelineState::GetVertexInputs() byteOffs[layouts[i].inputSlot] += layouts[i].format.compByteWidth * layouts[i].format.compCount; - ret[i].name = - semName + (needsSemanticIdx ? QString::number(layouts[i].semanticIndex) : QString()); + ret[i].name = semName + (needsSemanticIdx ? ToStr(layouts[i].semanticIndex) : ""); ret[i].vertexBuffer = (int)layouts[i].inputSlot; ret[i].byteOffset = offs; ret[i].perInstance = layouts[i].perInstance; @@ -735,7 +662,7 @@ rdcarray CommonPipelineState::GetVertexInputs() rdcarray &sig = m_D3D11->inputAssembly.bytecode->inputSignature; for(int ia = 0; ia < sig.count(); ia++) { - if(!semName.compare(sig[ia].semanticName, Qt::CaseInsensitive) && + if(!striequal(semName, sig[ia].semanticName) && sig[ia].semanticIndex == layouts[i].semanticIndex) { ret[i].used = true; @@ -757,12 +684,12 @@ rdcarray CommonPipelineState::GetVertexInputs() ret.resize(layouts.size()); for(int i = 0; i < layouts.count(); i++) { - QString semName = layouts[i].semanticName; + std::string semName = layouts[i].semanticName; bool needsSemanticIdx = false; for(int j = 0; j < layouts.count(); j++) { - if(i != j && !semName.compare(QString(layouts[j].semanticName), Qt::CaseInsensitive)) + if(i != j && !striequal(semName, std::string(layouts[j].semanticName))) { needsSemanticIdx = true; break; @@ -778,8 +705,7 @@ rdcarray CommonPipelineState::GetVertexInputs() byteOffs[layouts[i].inputSlot] += layouts[i].format.compByteWidth * layouts[i].format.compCount; - ret[i].name = - semName + (needsSemanticIdx ? QString::number(layouts[i].semanticIndex) : QString()); + ret[i].name = semName + (needsSemanticIdx ? ToStr(layouts[i].semanticIndex) : ""); ret[i].vertexBuffer = (int)layouts[i].inputSlot; ret[i].byteOffset = offs; ret[i].perInstance = layouts[i].perInstance; @@ -794,7 +720,7 @@ rdcarray CommonPipelineState::GetVertexInputs() rdcarray &sig = m_D3D12->vertexShader.reflection->inputSignature; for(int ia = 0; ia < sig.count(); ia++) { - if(!semName.compare(sig[ia].semanticName, Qt::CaseInsensitive) && + if(!striequal(semName, sig[ia].semanticName) && sig[ia].semanticIndex == layouts[i].semanticIndex) { ret[i].used = true; @@ -828,7 +754,7 @@ rdcarray CommonPipelineState::GetVertexInputs() ret.resize(attrs.count()); for(int i = 0; i < attrs.count() && a < num; i++) { - ret[a].name = lit("attr%1").arg(i); + ret[a].name = "attr" + ToStr((uint32_t)i); memset(&ret[a].genericValue, 0, sizeof(PixelValue)); ret[a].vertexBuffer = (int)attrs[i].vertexBufferSlot; ret[a].byteOffset = attrs[i].byteOffset; @@ -874,7 +800,7 @@ rdcarray CommonPipelineState::GetVertexInputs() ret[a].perInstance = false; ret[a].instanceRate = 0; ret[a].format.compByteWidth = 4; - ret[a].format.compCount = compCount; + ret[a].format.compCount = (uint8_t)compCount; ret[a].format.compType = compType; ret[a].format.type = ResourceFormatType::Regular; ret[a].format.srgbCorrected = false; @@ -912,7 +838,7 @@ rdcarray CommonPipelineState::GetVertexInputs() ret.resize(num); for(int i = 0; i < attrs.count() && a < num; i++) { - ret[a].name = lit("attr%1").arg(i); + ret[a].name = "attr" + ToStr((uint32_t)i); memset(&ret[a].genericValue, 0, sizeof(PixelValue)); ret[a].vertexBuffer = (int)attrs[i].binding; ret[a].byteOffset = attrs[i].byteOffset; @@ -952,8 +878,7 @@ rdcarray CommonPipelineState::GetVertexInputs() return rdcarray(); } -BoundCBuffer CommonPipelineState::GetConstantBuffer(ShaderStage stage, uint32_t BufIdx, - uint32_t ArrayIdx) +BoundCBuffer PipeState::GetConstantBuffer(ShaderStage stage, uint32_t BufIdx, uint32_t ArrayIdx) const { ResourceId buf; uint64_t ByteOffset = 0; @@ -1060,7 +985,7 @@ BoundCBuffer CommonPipelineState::GetConstantBuffer(ShaderStage stage, uint32_t return ret; } -rdcarray CommonPipelineState::GetReadOnlyResources(ShaderStage stage) +rdcarray PipeState::GetReadOnlyResources(ShaderStage stage) const { rdcarray ret; @@ -1176,7 +1101,7 @@ rdcarray CommonPipelineState::GetReadOnlyResources(ShaderSta return ret; } -rdcarray CommonPipelineState::GetReadWriteResources(ShaderStage stage) +rdcarray PipeState::GetReadWriteResources(ShaderStage stage) const { rdcarray ret; @@ -1205,7 +1130,7 @@ rdcarray CommonPipelineState::GetReadWriteResources(ShaderSt { int uavstart = (int)m_D3D11->outputMerger.uavStartSlot; - ret.reserve(m_D3D11->outputMerger.uavs.size() + qMax(0, uavstart)); + ret.reserve(m_D3D11->outputMerger.uavs.size() + std::max(0, uavstart)); // up to UAVStartSlot treat these bindings as empty. for(int i = 0; i < uavstart; i++) @@ -1313,7 +1238,7 @@ rdcarray CommonPipelineState::GetReadWriteResources(ShaderSt return ret; } -BoundResource CommonPipelineState::GetDepthTarget() +BoundResource PipeState::GetDepthTarget() const { if(IsCaptureLoaded()) { @@ -1366,7 +1291,7 @@ BoundResource CommonPipelineState::GetDepthTarget() return BoundResource(); } -rdcarray CommonPipelineState::GetOutputTargets() +rdcarray PipeState::GetOutputTargets() const { rdcarray ret; diff --git a/renderdoc/api/replay/renderdoc_replay.h b/renderdoc/api/replay/renderdoc_replay.h index 34d92eb7a..3ec1ec07a 100644 --- a/renderdoc/api/replay/renderdoc_replay.h +++ b/renderdoc/api/replay/renderdoc_replay.h @@ -476,13 +476,10 @@ DECLARE_REFLECTION_STRUCT(ResourceId); #include "capture_options.h" #include "control_types.h" -#include "d3d11_pipestate.h" -#include "d3d12_pipestate.h" #include "data_types.h" -#include "gl_pipestate.h" #include "replay_enums.h" #include "shader_types.h" -#include "vk_pipestate.h" +#include "pipestate.h" DOCUMENT(R"(Internal structure used for initialising environment in a replay application.)"); struct GlobalEnvironment @@ -775,43 +772,61 @@ function must be called from another thread. DOCUMENT(R"(Retrieve the current :class:`D3D11State` pipeline state. -This pipeline state will be filled with default values if the capture is not using the D3D11 API. +The return value will be ``None`` if the capture is not using the D3D11 API. You should use :meth:`GetAPIProperties` to determine the API of the capture. +See also :meth:`GetPipelineState`. + :return: The current D3D11 pipeline state. :rtype: D3D11State )"); - virtual const D3D11Pipe::State &GetD3D11PipelineState() = 0; + virtual const D3D11Pipe::State *GetD3D11PipelineState() = 0; DOCUMENT(R"(Retrieve the current :class:`D3D12State` pipeline state. -This pipeline state will be filled with default values if the capture is not using the D3D12 API. +The return value will be ``None`` if the capture is not using the D3D12 API. You should use :meth:`GetAPIProperties` to determine the API of the capture. +See also :meth:`GetPipelineState`. + :return: The current D3D12 pipeline state. :rtype: D3D12State )"); - virtual const D3D12Pipe::State &GetD3D12PipelineState() = 0; + virtual const D3D12Pipe::State *GetD3D12PipelineState() = 0; DOCUMENT(R"(Retrieve the current :class:`GLState` pipeline state. -This pipeline state will be filled with default values if the capture is not using the OpenGL API. +The return value will be ``None`` if the capture is not using the OpenGL API. You should use :meth:`GetAPIProperties` to determine the API of the capture. +See also :meth:`GetPipelineState`. + :return: The current OpenGL pipeline state. :rtype: GLState )"); - virtual const GLPipe::State &GetGLPipelineState() = 0; + virtual const GLPipe::State *GetGLPipelineState() = 0; DOCUMENT(R"(Retrieve the current :class:`VKState` pipeline state. -This pipeline state will be filled with default values if the capture is not using the Vulkan API. +The return value will be ``None`` if the capture is not using the Vulkan API. You should use :meth:`GetAPIProperties` to determine the API of the capture. +See also :meth:`GetPipelineState`. + :return: The current Vulkan pipeline state. :rtype: VKState )"); - virtual const VKPipe::State &GetVulkanPipelineState() = 0; + virtual const VKPipe::State *GetVulkanPipelineState() = 0; + + DOCUMENT(R"(Retrieve the current :class:`PipeState` pipeline state abstraction. + +This pipeline state will always be valid, and allows queries that will work regardless of the +capture's API. + +:return: The current pipeline state abstraction. +:rtype: PipeState +)"); + virtual const PipeState &GetPipelineState() = 0; DOCUMENT(R"(Retrieve the list of possible disassembly targets for :meth:`DisassembleShader`. The values are implementation dependent but will always include a default target first which is the diff --git a/renderdoc/api/replay/vk_pipestate.h b/renderdoc/api/replay/vk_pipestate.h index bca33acd2..5de70bcfe 100644 --- a/renderdoc/api/replay/vk_pipestate.h +++ b/renderdoc/api/replay/vk_pipestate.h @@ -729,6 +729,12 @@ struct ImageData DOCUMENT("The full current Vulkan pipeline state."); struct State { +#if !defined(RENDERDOC_EXPORTS) + // disallow creation/copy of this object externally + State() = delete; + State(const State &) = delete; +#endif + DOCUMENT("A :class:`VKPipeline` with the currently bound compute pipeline, if any."); Pipeline compute; DOCUMENT("A :class:`VKPipeline` with the currently bound graphics pipeline, if any."); diff --git a/renderdoc/core/core.cpp b/renderdoc/core/core.cpp index 1526a2617..f8f029f15 100644 --- a/renderdoc/core/core.cpp +++ b/renderdoc/core/core.cpp @@ -37,6 +37,8 @@ #include "api/replay/renderdoc_tostr.inl" +#include "api/replay/pipestate.inl" + #include "replay/renderdoc_serialise.inl" // this one is done by hand as we format it diff --git a/renderdoc/core/image_viewer.cpp b/renderdoc/core/image_viewer.cpp index 874b1632d..603772586 100644 --- a/renderdoc/core/image_viewer.cpp +++ b/renderdoc/core/image_viewer.cpp @@ -151,7 +151,7 @@ public: // handle a couple of operations ourselves to return a simple fake log APIProperties GetAPIProperties() { return m_Props; } FrameRecord GetFrameRecord() { return m_FrameRecord; } - const D3D11Pipe::State &GetD3D11PipelineState() { return m_PipelineState; } + const D3D11Pipe::State *GetD3D11PipelineState() { return &m_PipelineState; } // other operations are dropped/ignored, to avoid confusion ReplayStatus ReadLogInitialisation(RDCFile *rdc, bool storeStructuredBuffers) { @@ -170,9 +170,9 @@ public: return ret; } void SavePipelineState() {} - const D3D12Pipe::State &GetD3D12PipelineState() { return m_D3D12State; } - const GLPipe::State &GetGLPipelineState() { return m_GLState; } - const VKPipe::State &GetVulkanPipelineState() { return m_VKState; } + const D3D12Pipe::State *GetD3D12PipelineState() { return NULL; } + const GLPipe::State *GetGLPipelineState() { return NULL; } + const VKPipe::State *GetVulkanPipelineState() { return NULL; } void ReplayLog(uint32_t endEventID, ReplayLogType replayType) {} vector GetPassEvents(uint32_t eventId) { return vector(); } vector GetUsage(ResourceId id) { return vector(); } @@ -280,9 +280,6 @@ private: APIProperties m_Props; FrameRecord m_FrameRecord; D3D11Pipe::State m_PipelineState; - D3D12Pipe::State m_D3D12State; - VKPipe::State m_VKState; - GLPipe::State m_GLState; IReplayDriver *m_Proxy; string m_Filename; ResourceId m_TextureID; diff --git a/renderdoc/core/replay_proxy.cpp b/renderdoc/core/replay_proxy.cpp index 1efc8d3e5..080c4ba9a 100644 --- a/renderdoc/core/replay_proxy.cpp +++ b/renderdoc/core/replay_proxy.cpp @@ -1189,13 +1189,13 @@ void ReplayProxy::Proxied_SavePipelineState(ParamSerialiser ¶mser, ReturnSer m_Remote->SavePipelineState(); if(m_APIProps.pipelineType == GraphicsAPI::D3D11) - m_D3D11PipelineState = m_Remote->GetD3D11PipelineState(); + m_D3D11PipelineState = *m_Remote->GetD3D11PipelineState(); else if(m_APIProps.pipelineType == GraphicsAPI::D3D12) - m_D3D12PipelineState = m_Remote->GetD3D12PipelineState(); + m_D3D12PipelineState = *m_Remote->GetD3D12PipelineState(); else if(m_APIProps.pipelineType == GraphicsAPI::OpenGL) - m_GLPipelineState = m_Remote->GetGLPipelineState(); + m_GLPipelineState = *m_Remote->GetGLPipelineState(); else if(m_APIProps.pipelineType == GraphicsAPI::Vulkan) - m_VulkanPipelineState = m_Remote->GetVulkanPipelineState(); + m_VulkanPipelineState = *m_Remote->GetVulkanPipelineState(); } { diff --git a/renderdoc/core/replay_proxy.h b/renderdoc/core/replay_proxy.h index c5d222b1f..c015a03a6 100644 --- a/renderdoc/core/replay_proxy.h +++ b/renderdoc/core/replay_proxy.h @@ -418,10 +418,10 @@ public: bool Tick(int type); - const D3D11Pipe::State &GetD3D11PipelineState() { return m_D3D11PipelineState; } - const D3D12Pipe::State &GetD3D12PipelineState() { return m_D3D12PipelineState; } - const GLPipe::State &GetGLPipelineState() { return m_GLPipelineState; } - const VKPipe::State &GetVulkanPipelineState() { return m_VulkanPipelineState; } + const D3D11Pipe::State *GetD3D11PipelineState() { return &m_D3D11PipelineState; } + const D3D12Pipe::State *GetD3D12PipelineState() { return &m_D3D12PipelineState; } + const GLPipe::State *GetGLPipelineState() { return &m_GLPipelineState; } + const VKPipe::State *GetVulkanPipelineState() { return &m_VulkanPipelineState; } const SDFile &GetStructuredFile() { return m_StructuredFile; } IMPLEMENT_FUNCTION_PROXIED(void, FetchStructuredFile); diff --git a/renderdoc/driver/d3d11/d3d11_replay.h b/renderdoc/driver/d3d11/d3d11_replay.h index d4cb85323..db7e66e16 100644 --- a/renderdoc/driver/d3d11/d3d11_replay.h +++ b/renderdoc/driver/d3d11/d3d11_replay.h @@ -127,10 +127,10 @@ public: FrameRecord GetFrameRecord(); void SavePipelineState(); - const D3D11Pipe::State &GetD3D11PipelineState() { return m_CurPipelineState; } - const D3D12Pipe::State &GetD3D12PipelineState() { return m_D3D12State; } - const GLPipe::State &GetGLPipelineState() { return m_GLState; } - const VKPipe::State &GetVulkanPipelineState() { return m_VKState; } + const D3D11Pipe::State *GetD3D11PipelineState() { return &m_CurPipelineState; } + const D3D12Pipe::State *GetD3D12PipelineState() { return NULL; } + const GLPipe::State *GetGLPipelineState() { return NULL; } + const VKPipe::State *GetVulkanPipelineState() { return NULL; } void FreeTargetResource(ResourceId id); void FreeCustomShader(ResourceId id); @@ -450,7 +450,4 @@ private: std::map m_ResourceIdx; D3D11Pipe::State m_CurPipelineState; - D3D12Pipe::State m_D3D12State; - VKPipe::State m_VKState; - GLPipe::State m_GLState; }; diff --git a/renderdoc/driver/d3d12/d3d12_replay.h b/renderdoc/driver/d3d12/d3d12_replay.h index 221c30ef8..3eb4113a6 100644 --- a/renderdoc/driver/d3d12/d3d12_replay.h +++ b/renderdoc/driver/d3d12/d3d12_replay.h @@ -85,10 +85,10 @@ public: FrameRecord GetFrameRecord(); void SavePipelineState(); - const D3D11Pipe::State &GetD3D11PipelineState() { return m_D3D11State; } - const D3D12Pipe::State &GetD3D12PipelineState() { return m_PipelineState; } - const GLPipe::State &GetGLPipelineState() { return m_GLState; } - const VKPipe::State &GetVulkanPipelineState() { return m_VKState; } + const D3D11Pipe::State *GetD3D11PipelineState() { return NULL; } + const D3D12Pipe::State *GetD3D12PipelineState() { return &m_PipelineState; } + const GLPipe::State *GetGLPipelineState() { return NULL; } + const VKPipe::State *GetVulkanPipelineState() { return NULL; } void FreeTargetResource(ResourceId id); void FreeCustomShader(ResourceId id); @@ -392,9 +392,6 @@ private: bool m_ISAAvailable = false; D3D12Pipe::State m_PipelineState; - D3D11Pipe::State m_D3D11State; - VKPipe::State m_VKState; - GLPipe::State m_GLState; WrappedID3D12Device *m_pDevice = NULL; diff --git a/renderdoc/driver/gl/gl_replay.h b/renderdoc/driver/gl/gl_replay.h index 99dad3981..f124dd48e 100644 --- a/renderdoc/driver/gl/gl_replay.h +++ b/renderdoc/driver/gl/gl_replay.h @@ -116,10 +116,10 @@ public: FrameRecord GetFrameRecord(); void SavePipelineState(); - const D3D11Pipe::State &GetD3D11PipelineState() { return m_D3D11State; } - const D3D12Pipe::State &GetD3D12PipelineState() { return m_D3D12State; } - const GLPipe::State &GetGLPipelineState() { return m_CurPipelineState; } - const VKPipe::State &GetVulkanPipelineState() { return m_VKState; } + const D3D11Pipe::State *GetD3D11PipelineState() { return NULL; } + const D3D12Pipe::State *GetD3D12PipelineState() { return NULL; } + const GLPipe::State *GetGLPipelineState() { return &m_CurPipelineState; } + const VKPipe::State *GetVulkanPipelineState() { return NULL; } void FreeTargetResource(ResourceId id); ReplayStatus ReadLogInitialisation(RDCFile *rdc, bool storeStructuredBuffers); @@ -425,9 +425,6 @@ private: std::map m_ResourceIdx; GLPipe::State m_CurPipelineState; - D3D11Pipe::State m_D3D11State; - D3D12Pipe::State m_D3D12State; - VKPipe::State m_VKState; // AMD counter instance AMDCounters *m_pAMDCounters = NULL; diff --git a/renderdoc/driver/vulkan/vk_replay.h b/renderdoc/driver/vulkan/vk_replay.h index 6d4d07ff4..603f2cc29 100644 --- a/renderdoc/driver/vulkan/vk_replay.h +++ b/renderdoc/driver/vulkan/vk_replay.h @@ -208,10 +208,10 @@ public: vector GetDebugMessages(); void SavePipelineState(); - const D3D11Pipe::State &GetD3D11PipelineState() { return m_D3D11State; } - const D3D12Pipe::State &GetD3D12PipelineState() { return m_D3D12State; } - const GLPipe::State &GetGLPipelineState() { return m_GLState; } - const VKPipe::State &GetVulkanPipelineState() { return m_VulkanPipelineState; } + const D3D11Pipe::State *GetD3D11PipelineState() { return NULL; } + const D3D12Pipe::State *GetD3D12PipelineState() { return NULL; } + const GLPipe::State *GetGLPipelineState() { return NULL; } + const VKPipe::State *GetVulkanPipelineState() { return &m_VulkanPipelineState; } void FreeTargetResource(ResourceId id); ReplayStatus ReadLogInitialisation(RDCFile *rdc, bool storeStructuredBuffers); @@ -578,9 +578,6 @@ private: std::map m_ResourceIdx; VKPipe::State m_VulkanPipelineState; - D3D11Pipe::State m_D3D11State; - D3D12Pipe::State m_D3D12State; - GLPipe::State m_GLState; void FillTimersAMD(uint32_t *eventStartID, uint32_t *sampleIndex, vector *eventIDs); diff --git a/renderdoc/renderdoc.vcxproj b/renderdoc/renderdoc.vcxproj index 576bd36c5..ecba2f87c 100644 --- a/renderdoc/renderdoc.vcxproj +++ b/renderdoc/renderdoc.vcxproj @@ -157,6 +157,7 @@ + @@ -484,6 +485,7 @@ + diff --git a/renderdoc/renderdoc.vcxproj.filters b/renderdoc/renderdoc.vcxproj.filters index 914fa66ef..f41cad07c 100644 --- a/renderdoc/renderdoc.vcxproj.filters +++ b/renderdoc/renderdoc.vcxproj.filters @@ -438,6 +438,9 @@ 3rdparty\miniz + + API\Replay + @@ -862,6 +865,9 @@ Replay + + Replay + diff --git a/renderdoc/replay/replay_controller.cpp b/renderdoc/replay/replay_controller.cpp index 9c499b422..61be3f6c7 100644 --- a/renderdoc/replay/replay_controller.cpp +++ b/renderdoc/replay/replay_controller.cpp @@ -221,24 +221,29 @@ void ReplayController::SetFrameEvent(uint32_t eventId, bool force) } } -const D3D11Pipe::State &ReplayController::GetD3D11PipelineState() +const D3D11Pipe::State *ReplayController::GetD3D11PipelineState() { - return *m_D3D11PipelineState; + return m_D3D11PipelineState; } -const D3D12Pipe::State &ReplayController::GetD3D12PipelineState() +const D3D12Pipe::State *ReplayController::GetD3D12PipelineState() { - return *m_D3D12PipelineState; + return m_D3D12PipelineState; } -const GLPipe::State &ReplayController::GetGLPipelineState() +const GLPipe::State *ReplayController::GetGLPipelineState() { - return *m_GLPipelineState; + return m_GLPipelineState; } -const VKPipe::State &ReplayController::GetVulkanPipelineState() +const VKPipe::State *ReplayController::GetVulkanPipelineState() { - return *m_VulkanPipelineState; + return m_VulkanPipelineState; +} + +const PipeState &ReplayController::GetPipelineState() +{ + return m_PipeState; } rdcarray ReplayController::GetDisassemblyTargets() @@ -1732,8 +1737,11 @@ void ReplayController::FetchPipelineState() { m_pDevice->SavePipelineState(); - m_D3D11PipelineState = &m_pDevice->GetD3D11PipelineState(); - m_D3D12PipelineState = &m_pDevice->GetD3D12PipelineState(); - m_GLPipelineState = &m_pDevice->GetGLPipelineState(); - m_VulkanPipelineState = &m_pDevice->GetVulkanPipelineState(); + m_D3D11PipelineState = m_pDevice->GetD3D11PipelineState(); + m_D3D12PipelineState = m_pDevice->GetD3D12PipelineState(); + m_GLPipelineState = m_pDevice->GetGLPipelineState(); + m_VulkanPipelineState = m_pDevice->GetVulkanPipelineState(); + + m_PipeState.SetStates(m_APIProps, m_D3D11PipelineState, m_D3D12PipelineState, m_GLPipelineState, + m_VulkanPipelineState); } diff --git a/renderdoc/replay/replay_controller.h b/renderdoc/replay/replay_controller.h index 5c72e5131..948e13bfb 100644 --- a/renderdoc/replay/replay_controller.h +++ b/renderdoc/replay/replay_controller.h @@ -136,10 +136,11 @@ public: void FetchPipelineState(); - const D3D11Pipe::State &GetD3D11PipelineState(); - const D3D12Pipe::State &GetD3D12PipelineState(); - const GLPipe::State &GetGLPipelineState(); - const VKPipe::State &GetVulkanPipelineState(); + const D3D11Pipe::State *GetD3D11PipelineState(); + const D3D12Pipe::State *GetD3D12PipelineState(); + const GLPipe::State *GetGLPipelineState(); + const VKPipe::State *GetVulkanPipelineState(); + const PipeState &GetPipelineState(); rdcarray GetDisassemblyTargets(); rdcstr DisassembleShader(ResourceId pipeline, const ShaderReflection *refl, const char *target); @@ -224,6 +225,7 @@ private: const D3D12Pipe::State *m_D3D12PipelineState; const GLPipe::State *m_GLPipelineState; const VKPipe::State *m_VulkanPipelineState; + PipeState m_PipeState; std::vector m_Outputs; diff --git a/renderdoc/replay/replay_driver.h b/renderdoc/replay/replay_driver.h index b493e7081..5abc83dba 100644 --- a/renderdoc/replay/replay_driver.h +++ b/renderdoc/replay/replay_driver.h @@ -112,10 +112,10 @@ public: virtual vector GetUsage(ResourceId id) = 0; virtual void SavePipelineState() = 0; - virtual const D3D11Pipe::State &GetD3D11PipelineState() = 0; - virtual const D3D12Pipe::State &GetD3D12PipelineState() = 0; - virtual const GLPipe::State &GetGLPipelineState() = 0; - virtual const VKPipe::State &GetVulkanPipelineState() = 0; + virtual const D3D11Pipe::State *GetD3D11PipelineState() = 0; + virtual const D3D12Pipe::State *GetD3D12PipelineState() = 0; + virtual const GLPipe::State *GetGLPipelineState() = 0; + virtual const VKPipe::State *GetVulkanPipelineState() = 0; virtual FrameRecord GetFrameRecord() = 0;