Move API-agnostic pipeline state wrapper into core interface

* There's no need for this to be in the UI, and moving it allows it to be used
  from script which is very useful.
This commit is contained in:
baldurk
2018-06-18 17:33:48 +01:00
parent 7ae6581a65
commit 14e3a3d360
48 changed files with 1057 additions and 1203 deletions
@@ -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
@@ -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
@@ -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)
@@ -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