mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-08 07:41:12 +00:00
Create and fill out D3D12 pipeline state, without shader resources.
* We make shaders into fake resources with IDs, so they can be identified individually (for replacement, fetching reflection data, and things like that). This is a little but ugly but worth it for the simplicity it will provide everywhere else.
This commit is contained in:
@@ -75,8 +75,8 @@ struct D3D12PipelineState
|
||||
|
||||
struct ShaderStage
|
||||
{
|
||||
ShaderStage() : Present(false), ShaderDetails(NULL), stage(eShaderStage_Vertex) {}
|
||||
bool32 Present;
|
||||
ShaderStage() : ShaderDetails(NULL), stage(eShaderStage_Vertex) {}
|
||||
ResourceId Shader;
|
||||
ShaderReflection *ShaderDetails;
|
||||
ShaderBindpointMapping BindpointMapping;
|
||||
|
||||
|
||||
@@ -28,6 +28,10 @@
|
||||
#include "d3d12_manager.h"
|
||||
#include "d3d12_resources.h"
|
||||
|
||||
void MakeShaderReflection(DXBC::DXBCFile *dxbc, ShaderReflection *refl,
|
||||
ShaderBindpointMapping *mapping)
|
||||
{
|
||||
}
|
||||
enum D3D12ResourceBarrierSubresource
|
||||
{
|
||||
D3D12AllSubresources = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES
|
||||
|
||||
@@ -33,7 +33,8 @@
|
||||
#include "driver/shaders/dxbc/dxbc_compile.h"
|
||||
#include "serialise/serialiser.h"
|
||||
|
||||
ShaderReflection *MakeShaderReflection(DXBC::DXBCFile *dxbc);
|
||||
void MakeShaderReflection(DXBC::DXBCFile *dxbc, ShaderReflection *refl,
|
||||
ShaderBindpointMapping *mapping);
|
||||
|
||||
// similar to RDCUNIMPLEMENTED but for things that are hit often so we don't want to fire the
|
||||
// debugbreak.
|
||||
|
||||
@@ -290,22 +290,9 @@ bool WrappedID3D12Device::Serialise_CreateGraphicsPipelineState(
|
||||
for(size_t i = 0; i < ARRAY_COUNT(shaders); i++)
|
||||
{
|
||||
if(shaders[i]->BytecodeLength == 0)
|
||||
{
|
||||
shaders[i]->pShaderBytecode = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
WrappedID3D12PipelineState::DXBCKey *key =
|
||||
new WrappedID3D12PipelineState::DXBCKey(*shaders[i]);
|
||||
|
||||
if(WrappedID3D12PipelineState::m_Shaders[*key] == NULL)
|
||||
WrappedID3D12PipelineState::m_Shaders[*key] =
|
||||
new WrappedID3D12PipelineState::ShaderEntry(*shaders[i]);
|
||||
else
|
||||
WrappedID3D12PipelineState::m_Shaders[*key]->AddRef();
|
||||
|
||||
shaders[i]->pShaderBytecode = key;
|
||||
}
|
||||
shaders[i]->pShaderBytecode = WrappedID3D12PipelineState::AddShader(*shaders[i], this);
|
||||
}
|
||||
|
||||
GetResourceManager()->AddLiveResource(Pipe, ret);
|
||||
@@ -380,22 +367,11 @@ bool WrappedID3D12Device::Serialise_CreateComputePipelineState(
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = new WrappedID3D12PipelineState(ret, this);
|
||||
WrappedID3D12PipelineState *wrapped = new WrappedID3D12PipelineState(ret, this);
|
||||
ret = wrapped;
|
||||
|
||||
WrappedID3D12PipelineState *wrapped = (WrappedID3D12PipelineState *)ret;
|
||||
|
||||
wrapped->compute = new D3D12_COMPUTE_PIPELINE_STATE_DESC(Descriptor);
|
||||
|
||||
WrappedID3D12PipelineState::DXBCKey *key =
|
||||
new WrappedID3D12PipelineState::DXBCKey(wrapped->compute->CS);
|
||||
|
||||
if(WrappedID3D12PipelineState::m_Shaders[*key] == NULL)
|
||||
WrappedID3D12PipelineState::m_Shaders[*key] =
|
||||
new WrappedID3D12PipelineState::ShaderEntry(wrapped->compute->CS);
|
||||
else
|
||||
WrappedID3D12PipelineState::m_Shaders[*key]->AddRef();
|
||||
|
||||
wrapped->compute->CS.pShaderBytecode = key;
|
||||
wrapped->compute->CS.pShaderBytecode =
|
||||
WrappedID3D12PipelineState::AddShader(wrapped->compute->CS, this);
|
||||
|
||||
GetResourceManager()->AddLiveResource(Pipe, ret);
|
||||
}
|
||||
|
||||
@@ -198,6 +198,17 @@ FetchTexture D3D12Replay::GetTexture(ResourceId id)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ShaderReflection *D3D12Replay::GetShader(ResourceId shader, string entryPoint)
|
||||
{
|
||||
WrappedID3D12PipelineState::ShaderEntry *sh =
|
||||
m_pDevice->GetResourceManager()->GetCurrentAs<WrappedID3D12PipelineState::ShaderEntry>(shader);
|
||||
|
||||
if(sh)
|
||||
return &sh->GetDetails();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void D3D12Replay::FreeTargetResource(ResourceId id)
|
||||
{
|
||||
if(m_pDevice->GetResourceManager()->HasLiveResource(id))
|
||||
@@ -233,6 +244,834 @@ vector<EventUsage> D3D12Replay::GetUsage(ResourceId id)
|
||||
return m_pDevice->GetQueue()->GetUsage(id);
|
||||
}
|
||||
|
||||
void D3D12Replay::FillResourceView(D3D12PipelineState::ResourceView &view,
|
||||
const PortableHandle &resHandle)
|
||||
{
|
||||
D3D12ResourceManager *rm = m_pDevice->GetResourceManager();
|
||||
|
||||
if(resHandle.heap == ResourceId())
|
||||
return;
|
||||
|
||||
WrappedID3D12DescriptorHeap *heap = rm->GetLiveAs<WrappedID3D12DescriptorHeap>(resHandle.heap);
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE handle = heap->GetCPUDescriptorHandleForHeapStart();
|
||||
|
||||
D3D12Descriptor *desc = (D3D12Descriptor *)handle.ptr;
|
||||
desc += resHandle.index;
|
||||
|
||||
if(desc->GetType() == D3D12Descriptor::TypeSampler || desc->GetType() == D3D12Descriptor::TypeCBV)
|
||||
{
|
||||
RDCERR("Invalid descriptors - expected a resource view");
|
||||
return;
|
||||
}
|
||||
|
||||
view.Resource = rm->GetOriginalID(GetResID(desc->nonsamp.resource));
|
||||
|
||||
if(view.Resource == ResourceId())
|
||||
return;
|
||||
|
||||
D3D12_RESOURCE_DESC res = desc->nonsamp.resource->GetDesc();
|
||||
|
||||
{
|
||||
DXGI_FORMAT fmt = DXGI_FORMAT_UNKNOWN;
|
||||
|
||||
if(desc->GetType() == D3D12Descriptor::TypeRTV)
|
||||
fmt = desc->nonsamp.rtv.Format;
|
||||
else if(desc->GetType() == D3D12Descriptor::TypeSRV)
|
||||
fmt = desc->nonsamp.srv.Format;
|
||||
else if(desc->GetType() == D3D12Descriptor::TypeUAV)
|
||||
fmt = (DXGI_FORMAT)desc->nonsamp.uav.desc.Format;
|
||||
|
||||
if(fmt == DXGI_FORMAT_UNKNOWN)
|
||||
fmt = res.Format;
|
||||
|
||||
view.ElementSize = fmt == DXGI_FORMAT_UNKNOWN ? 1 : GetByteSize(1, 1, 1, fmt, 0);
|
||||
|
||||
view.Format = MakeResourceFormat(fmt);
|
||||
|
||||
if(desc->GetType() == D3D12Descriptor::TypeRTV)
|
||||
{
|
||||
view.Type = ToStr::Get(desc->nonsamp.rtv.ViewDimension);
|
||||
|
||||
if(desc->nonsamp.rtv.ViewDimension == D3D12_RTV_DIMENSION_BUFFER)
|
||||
{
|
||||
view.FirstElement = desc->nonsamp.rtv.Buffer.FirstElement;
|
||||
view.NumElements = desc->nonsamp.rtv.Buffer.NumElements;
|
||||
}
|
||||
else if(desc->nonsamp.rtv.ViewDimension == D3D12_RTV_DIMENSION_TEXTURE1D)
|
||||
{
|
||||
view.HighestMip = desc->nonsamp.rtv.Texture1D.MipSlice;
|
||||
}
|
||||
else if(desc->nonsamp.rtv.ViewDimension == D3D12_RTV_DIMENSION_TEXTURE1DARRAY)
|
||||
{
|
||||
view.ArraySize = desc->nonsamp.rtv.Texture1DArray.ArraySize;
|
||||
view.FirstArraySlice = desc->nonsamp.rtv.Texture1DArray.FirstArraySlice;
|
||||
view.HighestMip = desc->nonsamp.rtv.Texture1DArray.MipSlice;
|
||||
}
|
||||
else if(desc->nonsamp.rtv.ViewDimension == D3D12_RTV_DIMENSION_TEXTURE2D)
|
||||
{
|
||||
view.HighestMip = desc->nonsamp.rtv.Texture2D.MipSlice;
|
||||
}
|
||||
else if(desc->nonsamp.rtv.ViewDimension == D3D12_RTV_DIMENSION_TEXTURE2DARRAY)
|
||||
{
|
||||
view.ArraySize = desc->nonsamp.rtv.Texture2DArray.ArraySize;
|
||||
view.FirstArraySlice = desc->nonsamp.rtv.Texture2DArray.FirstArraySlice;
|
||||
view.HighestMip = desc->nonsamp.rtv.Texture2DArray.MipSlice;
|
||||
}
|
||||
else if(desc->nonsamp.rtv.ViewDimension == D3D12_RTV_DIMENSION_TEXTURE2DMS)
|
||||
{
|
||||
}
|
||||
else if(desc->nonsamp.rtv.ViewDimension == D3D12_RTV_DIMENSION_TEXTURE2DMSARRAY)
|
||||
{
|
||||
view.ArraySize = desc->nonsamp.rtv.Texture2DMSArray.ArraySize;
|
||||
view.FirstArraySlice = desc->nonsamp.rtv.Texture2DArray.FirstArraySlice;
|
||||
}
|
||||
else if(desc->nonsamp.rtv.ViewDimension == D3D12_RTV_DIMENSION_TEXTURE3D)
|
||||
{
|
||||
view.ArraySize = desc->nonsamp.rtv.Texture3D.WSize;
|
||||
view.FirstArraySlice = desc->nonsamp.rtv.Texture3D.FirstWSlice;
|
||||
view.HighestMip = desc->nonsamp.rtv.Texture3D.MipSlice;
|
||||
}
|
||||
}
|
||||
else if(desc->GetType() == D3D12Descriptor::TypeDSV)
|
||||
{
|
||||
view.Type = ToStr::Get(desc->nonsamp.dsv.ViewDimension);
|
||||
|
||||
if(desc->nonsamp.dsv.ViewDimension == D3D12_DSV_DIMENSION_TEXTURE1D)
|
||||
{
|
||||
view.HighestMip = desc->nonsamp.dsv.Texture1D.MipSlice;
|
||||
}
|
||||
else if(desc->nonsamp.dsv.ViewDimension == D3D12_DSV_DIMENSION_TEXTURE1DARRAY)
|
||||
{
|
||||
view.ArraySize = desc->nonsamp.dsv.Texture1DArray.ArraySize;
|
||||
view.FirstArraySlice = desc->nonsamp.dsv.Texture1DArray.FirstArraySlice;
|
||||
view.HighestMip = desc->nonsamp.dsv.Texture1DArray.MipSlice;
|
||||
}
|
||||
else if(desc->nonsamp.dsv.ViewDimension == D3D12_DSV_DIMENSION_TEXTURE2D)
|
||||
{
|
||||
view.HighestMip = desc->nonsamp.dsv.Texture2D.MipSlice;
|
||||
}
|
||||
else if(desc->nonsamp.dsv.ViewDimension == D3D12_DSV_DIMENSION_TEXTURE2DARRAY)
|
||||
{
|
||||
view.ArraySize = desc->nonsamp.dsv.Texture2DArray.ArraySize;
|
||||
view.FirstArraySlice = desc->nonsamp.dsv.Texture2DArray.FirstArraySlice;
|
||||
view.HighestMip = desc->nonsamp.dsv.Texture2DArray.MipSlice;
|
||||
}
|
||||
else if(desc->nonsamp.dsv.ViewDimension == D3D12_DSV_DIMENSION_TEXTURE2DMS)
|
||||
{
|
||||
}
|
||||
else if(desc->nonsamp.dsv.ViewDimension == D3D12_DSV_DIMENSION_TEXTURE2DMSARRAY)
|
||||
{
|
||||
view.ArraySize = desc->nonsamp.dsv.Texture2DMSArray.ArraySize;
|
||||
view.FirstArraySlice = desc->nonsamp.dsv.Texture2DArray.FirstArraySlice;
|
||||
}
|
||||
}
|
||||
else if(desc->GetType() == D3D12Descriptor::TypeSRV)
|
||||
{
|
||||
view.Type = ToStr::Get(desc->nonsamp.srv.ViewDimension);
|
||||
|
||||
view.swizzle[0] = (TextureSwizzle)D3D12_DECODE_SHADER_4_COMPONENT_MAPPING(
|
||||
0, desc->nonsamp.srv.Shader4ComponentMapping);
|
||||
view.swizzle[1] = (TextureSwizzle)D3D12_DECODE_SHADER_4_COMPONENT_MAPPING(
|
||||
1, desc->nonsamp.srv.Shader4ComponentMapping);
|
||||
view.swizzle[2] = (TextureSwizzle)D3D12_DECODE_SHADER_4_COMPONENT_MAPPING(
|
||||
2, desc->nonsamp.srv.Shader4ComponentMapping);
|
||||
view.swizzle[3] = (TextureSwizzle)D3D12_DECODE_SHADER_4_COMPONENT_MAPPING(
|
||||
3, desc->nonsamp.srv.Shader4ComponentMapping);
|
||||
|
||||
if(desc->nonsamp.srv.ViewDimension == D3D12_SRV_DIMENSION_BUFFER)
|
||||
{
|
||||
view.FirstElement = desc->nonsamp.srv.Buffer.FirstElement;
|
||||
view.NumElements = desc->nonsamp.srv.Buffer.NumElements;
|
||||
|
||||
view.BufferFlags = desc->nonsamp.srv.Buffer.Flags;
|
||||
view.ElementSize = desc->nonsamp.srv.Buffer.StructureByteStride;
|
||||
}
|
||||
else if(desc->nonsamp.srv.ViewDimension == D3D12_SRV_DIMENSION_TEXTURE1D)
|
||||
{
|
||||
view.HighestMip = desc->nonsamp.srv.Texture1D.MostDetailedMip;
|
||||
view.NumMipLevels = desc->nonsamp.srv.Texture1D.MipLevels;
|
||||
view.MinLODClamp = desc->nonsamp.srv.Texture1D.ResourceMinLODClamp;
|
||||
}
|
||||
else if(desc->nonsamp.srv.ViewDimension == D3D12_SRV_DIMENSION_TEXTURE1DARRAY)
|
||||
{
|
||||
view.ArraySize = desc->nonsamp.srv.Texture1DArray.ArraySize;
|
||||
view.FirstArraySlice = desc->nonsamp.srv.Texture1DArray.FirstArraySlice;
|
||||
view.HighestMip = desc->nonsamp.srv.Texture1DArray.MostDetailedMip;
|
||||
view.NumMipLevels = desc->nonsamp.srv.Texture1DArray.MipLevels;
|
||||
view.MinLODClamp = desc->nonsamp.srv.Texture1DArray.ResourceMinLODClamp;
|
||||
}
|
||||
else if(desc->nonsamp.srv.ViewDimension == D3D12_SRV_DIMENSION_TEXTURE2D)
|
||||
{
|
||||
view.HighestMip = desc->nonsamp.srv.Texture2D.MostDetailedMip;
|
||||
view.NumMipLevels = desc->nonsamp.srv.Texture2D.MipLevels;
|
||||
view.MinLODClamp = desc->nonsamp.srv.Texture2D.ResourceMinLODClamp;
|
||||
}
|
||||
else if(desc->nonsamp.srv.ViewDimension == D3D12_SRV_DIMENSION_TEXTURE2DARRAY)
|
||||
{
|
||||
view.ArraySize = desc->nonsamp.srv.Texture2DArray.ArraySize;
|
||||
view.FirstArraySlice = desc->nonsamp.srv.Texture2DArray.FirstArraySlice;
|
||||
view.HighestMip = desc->nonsamp.srv.Texture2DArray.MostDetailedMip;
|
||||
view.NumMipLevels = desc->nonsamp.srv.Texture2DArray.MipLevels;
|
||||
view.MinLODClamp = desc->nonsamp.srv.Texture2DArray.ResourceMinLODClamp;
|
||||
}
|
||||
else if(desc->nonsamp.srv.ViewDimension == D3D12_SRV_DIMENSION_TEXTURE2DMS)
|
||||
{
|
||||
}
|
||||
else if(desc->nonsamp.srv.ViewDimension == D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY)
|
||||
{
|
||||
view.ArraySize = desc->nonsamp.srv.Texture2DMSArray.ArraySize;
|
||||
view.FirstArraySlice = desc->nonsamp.srv.Texture2DMSArray.FirstArraySlice;
|
||||
}
|
||||
else if(desc->nonsamp.srv.ViewDimension == D3D12_SRV_DIMENSION_TEXTURE3D)
|
||||
{
|
||||
view.HighestMip = desc->nonsamp.srv.Texture3D.MostDetailedMip;
|
||||
view.NumMipLevels = desc->nonsamp.srv.Texture3D.MipLevels;
|
||||
view.MinLODClamp = desc->nonsamp.srv.Texture3D.ResourceMinLODClamp;
|
||||
}
|
||||
}
|
||||
else if(desc->GetType() == D3D12Descriptor::TypeUAV)
|
||||
{
|
||||
D3D12_UNORDERED_ACCESS_VIEW_DESC uav = desc->nonsamp.uav.desc.AsDesc();
|
||||
|
||||
view.CounterResource = rm->GetOriginalID(GetResID(desc->nonsamp.uav.counterResource));
|
||||
|
||||
view.Type = ToStr::Get(uav.ViewDimension);
|
||||
|
||||
if(uav.ViewDimension == D3D12_UAV_DIMENSION_BUFFER)
|
||||
{
|
||||
view.FirstElement = uav.Buffer.FirstElement;
|
||||
view.NumElements = uav.Buffer.NumElements;
|
||||
|
||||
view.BufferFlags = uav.Buffer.Flags;
|
||||
view.ElementSize = uav.Buffer.StructureByteStride;
|
||||
|
||||
view.CounterByteOffset = uav.Buffer.CounterOffsetInBytes;
|
||||
}
|
||||
else if(uav.ViewDimension == D3D12_UAV_DIMENSION_TEXTURE1D)
|
||||
{
|
||||
view.HighestMip = uav.Texture1D.MipSlice;
|
||||
}
|
||||
else if(uav.ViewDimension == D3D12_UAV_DIMENSION_TEXTURE1DARRAY)
|
||||
{
|
||||
view.ArraySize = uav.Texture1DArray.ArraySize;
|
||||
view.FirstArraySlice = uav.Texture1DArray.FirstArraySlice;
|
||||
view.HighestMip = uav.Texture1DArray.MipSlice;
|
||||
}
|
||||
else if(uav.ViewDimension == D3D12_UAV_DIMENSION_TEXTURE2D)
|
||||
{
|
||||
view.HighestMip = uav.Texture2D.MipSlice;
|
||||
}
|
||||
else if(uav.ViewDimension == D3D12_UAV_DIMENSION_TEXTURE2DARRAY)
|
||||
{
|
||||
view.ArraySize = uav.Texture2DArray.ArraySize;
|
||||
view.FirstArraySlice = uav.Texture2DArray.FirstArraySlice;
|
||||
view.HighestMip = uav.Texture2DArray.MipSlice;
|
||||
}
|
||||
else if(uav.ViewDimension == D3D12_UAV_DIMENSION_TEXTURE3D)
|
||||
{
|
||||
view.ArraySize = uav.Texture3D.WSize;
|
||||
view.FirstArraySlice = uav.Texture3D.FirstWSlice;
|
||||
view.HighestMip = uav.Texture3D.MipSlice;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void D3D12Replay::MakePipelineState()
|
||||
{
|
||||
const D3D12RenderState &rs = m_pDevice->GetQueue()->GetCommandData()->m_RenderState;
|
||||
|
||||
D3D12PipelineState &state = m_PipelineState;
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// Input Assembler
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
D3D12ResourceManager *rm = m_pDevice->GetResourceManager();
|
||||
|
||||
state.pipeline = rm->GetOriginalID(rs.pipe);
|
||||
|
||||
state.customName = true;
|
||||
string str = m_pDevice->GetResourceName(rs.pipe);
|
||||
|
||||
WrappedID3D12PipelineState *pipe = NULL;
|
||||
|
||||
if(rs.pipe != ResourceId())
|
||||
pipe = rm->GetCurrentAs<WrappedID3D12PipelineState>(rs.pipe);
|
||||
|
||||
if(str == "")
|
||||
{
|
||||
state.customName = false;
|
||||
|
||||
if(pipe)
|
||||
str = StringFormat::Fmt(pipe->IsGraphics() ? "Graphics Pipe %llu" : "Compute Pipe %llu",
|
||||
state.pipeline);
|
||||
else
|
||||
str = "Unbound";
|
||||
}
|
||||
|
||||
state.PipelineName = str;
|
||||
|
||||
if(pipe && pipe->IsGraphics())
|
||||
{
|
||||
const D3D12_INPUT_ELEMENT_DESC *inputEl = pipe->graphics->InputLayout.pInputElementDescs;
|
||||
UINT numInput = pipe->graphics->InputLayout.NumElements;
|
||||
|
||||
create_array_uninit(state.m_IA.layouts, numInput);
|
||||
for(UINT i = 0; i < numInput; i++)
|
||||
{
|
||||
D3D12PipelineState::InputAssembler::LayoutInput &l = state.m_IA.layouts[i];
|
||||
|
||||
l.ByteOffset = inputEl[i].AlignedByteOffset;
|
||||
l.Format = MakeResourceFormat(inputEl[i].Format);
|
||||
l.InputSlot = inputEl[i].InputSlot;
|
||||
l.PerInstance = inputEl[i].InputSlotClass == D3D12_INPUT_CLASSIFICATION_PER_INSTANCE_DATA;
|
||||
l.InstanceDataStepRate = inputEl[i].InstanceDataStepRate;
|
||||
l.SemanticIndex = inputEl[i].SemanticIndex;
|
||||
l.SemanticName = inputEl[i].SemanticName;
|
||||
}
|
||||
|
||||
state.m_IA.indexStripCutValue = 0;
|
||||
switch(pipe->graphics->IBStripCutValue)
|
||||
{
|
||||
case D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFF: state.m_IA.indexStripCutValue = 0xFFFF; break;
|
||||
case D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFFFFFF:
|
||||
state.m_IA.indexStripCutValue = 0xFFFFFFFF;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
create_array_uninit(state.m_IA.vbuffers, rs.vbuffers.size());
|
||||
for(size_t i = 0; i < rs.vbuffers.size(); i++)
|
||||
{
|
||||
D3D12PipelineState::InputAssembler::VertexBuffer &vb = state.m_IA.vbuffers[i];
|
||||
|
||||
vb.Buffer = rm->GetOriginalID(rs.vbuffers[i].buf);
|
||||
vb.Offset = rs.vbuffers[i].offs;
|
||||
vb.Size = rs.vbuffers[i].size;
|
||||
vb.Stride = rs.vbuffers[i].stride;
|
||||
}
|
||||
|
||||
state.m_IA.ibuffer.Buffer = rm->GetOriginalID(rs.ibuffer.buf);
|
||||
state.m_IA.ibuffer.Offset = rs.ibuffer.offs;
|
||||
state.m_IA.ibuffer.Size = rs.ibuffer.size;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// Shaders
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
ResourceId rootSig;
|
||||
|
||||
if(pipe && pipe->IsCompute())
|
||||
{
|
||||
WrappedID3D12PipelineState::ShaderEntry *sh =
|
||||
(WrappedID3D12PipelineState::ShaderEntry *)pipe->compute->CS.pShaderBytecode;
|
||||
|
||||
state.m_CS.Shader = sh->GetResourceID();
|
||||
state.m_CS.stage = eShaderStage_Compute;
|
||||
|
||||
rootSig = rs.compute.rootsig;
|
||||
}
|
||||
else if(pipe)
|
||||
{
|
||||
D3D12PipelineState::ShaderStage *dstArr[] = {&state.m_VS, &state.m_HS, &state.m_DS, &state.m_GS,
|
||||
&state.m_PS};
|
||||
|
||||
D3D12_SHADER_BYTECODE *srcArr[] = {&pipe->graphics->VS, &pipe->graphics->HS, &pipe->graphics->DS,
|
||||
&pipe->graphics->GS, &pipe->graphics->PS};
|
||||
|
||||
for(size_t stage = 0; stage < 5; stage++)
|
||||
{
|
||||
D3D12PipelineState::ShaderStage &dst = *dstArr[stage];
|
||||
D3D12_SHADER_BYTECODE &src = *srcArr[stage];
|
||||
|
||||
dst.stage = (ShaderStageType)stage;
|
||||
|
||||
WrappedID3D12PipelineState::ShaderEntry *sh =
|
||||
(WrappedID3D12PipelineState::ShaderEntry *)src.pShaderBytecode;
|
||||
|
||||
if(sh)
|
||||
{
|
||||
dst.Shader = sh->GetResourceID();
|
||||
dst.BindpointMapping = sh->GetMapping();
|
||||
}
|
||||
}
|
||||
|
||||
rootSig = rs.graphics.rootsig;
|
||||
}
|
||||
|
||||
#if 0
|
||||
{
|
||||
D3D11PipelineState::ShaderStage &dst = *dstArr[stage];
|
||||
const D3D11RenderState::shader &src = *srcArr[stage];
|
||||
|
||||
dst.stage = (ShaderStageType)stage;
|
||||
|
||||
ResourceId id = GetIDForResource(src.Shader);
|
||||
|
||||
WrappedShader *shad = (WrappedShader *)(WrappedID3D11Shader<ID3D11VertexShader> *)src.Shader;
|
||||
|
||||
ShaderReflection *refl = NULL;
|
||||
|
||||
if(shad != NULL)
|
||||
refl = shad->GetDetails();
|
||||
|
||||
dst.Shader = rm->GetOriginalID(id);
|
||||
dst.ShaderDetails = NULL;
|
||||
|
||||
string str = GetDebugName(src.Shader);
|
||||
dst.customName = true;
|
||||
|
||||
if(str == "" && dst.Shader != ResourceId())
|
||||
{
|
||||
dst.customName = false;
|
||||
str = StringFormat::Fmt("%s Shader %llu", stageNames[stage], dst.Shader);
|
||||
}
|
||||
|
||||
dst.ShaderName = str;
|
||||
|
||||
// create identity bindpoint mapping
|
||||
create_array_uninit(dst.BindpointMapping.InputAttributes,
|
||||
D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT);
|
||||
for(int s = 0; s < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; s++)
|
||||
{
|
||||
// TODO: this should do any semantic rematching as defined by the bytecode
|
||||
// the input layout was built with (not necessarily the vertex shader's bytecode -
|
||||
// in the case of a mismatch). It's commonly, but not always the identity mapping
|
||||
dst.BindpointMapping.InputAttributes[s] = s;
|
||||
}
|
||||
|
||||
create_array_uninit(dst.BindpointMapping.ConstantBlocks,
|
||||
D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT);
|
||||
for(int s = 0; s < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; s++)
|
||||
{
|
||||
dst.BindpointMapping.ConstantBlocks[s].bindset = 0;
|
||||
dst.BindpointMapping.ConstantBlocks[s].bind = s;
|
||||
dst.BindpointMapping.ConstantBlocks[s].used = false;
|
||||
dst.BindpointMapping.ConstantBlocks[s].arraySize = 1;
|
||||
}
|
||||
|
||||
create_array_uninit(dst.BindpointMapping.ReadOnlyResources,
|
||||
D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT);
|
||||
for(int32_t s = 0; s < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; s++)
|
||||
{
|
||||
dst.BindpointMapping.ReadOnlyResources[s].bindset = 0;
|
||||
dst.BindpointMapping.ReadOnlyResources[s].bind = s;
|
||||
dst.BindpointMapping.ReadOnlyResources[s].used = false;
|
||||
dst.BindpointMapping.ReadOnlyResources[s].arraySize = 1;
|
||||
}
|
||||
|
||||
create_array_uninit(dst.BindpointMapping.ReadWriteResources, D3D11_1_UAV_SLOT_COUNT);
|
||||
for(int32_t s = 0; s < D3D11_1_UAV_SLOT_COUNT; s++)
|
||||
{
|
||||
dst.BindpointMapping.ReadWriteResources[s].bindset = 0;
|
||||
dst.BindpointMapping.ReadWriteResources[s].bind = s;
|
||||
dst.BindpointMapping.ReadWriteResources[s].used = false;
|
||||
dst.BindpointMapping.ReadWriteResources[s].arraySize = 1;
|
||||
}
|
||||
|
||||
// mark resources as used if they are referenced by the shader
|
||||
if(refl)
|
||||
{
|
||||
for(int32_t i = 0; i < refl->ConstantBlocks.count; i++)
|
||||
if(refl->ConstantBlocks[i].bufferBacked)
|
||||
dst.BindpointMapping.ConstantBlocks[refl->ConstantBlocks[i].bindPoint].used = true;
|
||||
|
||||
for(int32_t i = 0; i < refl->ReadOnlyResources.count; i++)
|
||||
if(!refl->ReadOnlyResources[i].IsSampler)
|
||||
dst.BindpointMapping.ReadOnlyResources[refl->ReadOnlyResources[i].bindPoint].used = true;
|
||||
|
||||
for(int32_t i = 0; i < refl->ReadWriteResources.count; i++)
|
||||
dst.BindpointMapping.ReadWriteResources[refl->ReadWriteResources[i].bindPoint].used = true;
|
||||
}
|
||||
|
||||
create_array_uninit(dst.ConstantBuffers, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT);
|
||||
for(size_t s = 0; s < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; s++)
|
||||
{
|
||||
dst.ConstantBuffers[s].Buffer = rm->GetOriginalID(GetIDForResource(src.ConstantBuffers[s]));
|
||||
dst.ConstantBuffers[s].VecOffset = src.CBOffsets[s];
|
||||
dst.ConstantBuffers[s].VecCount = src.CBCounts[s];
|
||||
}
|
||||
|
||||
create_array_uninit(dst.Samplers, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT);
|
||||
for(size_t s = 0; s < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; s++)
|
||||
{
|
||||
D3D11PipelineState::ShaderStage::Sampler &samp = dst.Samplers[s];
|
||||
|
||||
samp.Samp = rm->GetOriginalID(GetIDForResource(src.Samplers[s]));
|
||||
|
||||
if(samp.Samp != ResourceId())
|
||||
{
|
||||
samp.SamplerName = GetDebugName(src.Samplers[s]);
|
||||
samp.customSamplerName = true;
|
||||
|
||||
if(samp.SamplerName.count == 0)
|
||||
{
|
||||
samp.customSamplerName = false;
|
||||
samp.SamplerName = StringFormat::Fmt("Sampler %llu", samp.Samp);
|
||||
}
|
||||
|
||||
D3D11_SAMPLER_DESC desc;
|
||||
src.Samplers[s]->GetDesc(&desc);
|
||||
|
||||
samp.AddressU = ToStr::Get(desc.AddressU);
|
||||
samp.AddressV = ToStr::Get(desc.AddressV);
|
||||
samp.AddressW = ToStr::Get(desc.AddressW);
|
||||
|
||||
memcpy(samp.BorderColor, desc.BorderColor, sizeof(FLOAT) * 4);
|
||||
|
||||
samp.Comparison = ToStr::Get(desc.ComparisonFunc);
|
||||
samp.Filter = ToStr::Get(desc.Filter);
|
||||
samp.MaxAniso = 0;
|
||||
if(desc.Filter == D3D11_FILTER_ANISOTROPIC ||
|
||||
desc.Filter == D3D11_FILTER_COMPARISON_ANISOTROPIC)
|
||||
samp.MaxAniso = desc.MaxAnisotropy;
|
||||
samp.MaxLOD = desc.MaxLOD;
|
||||
samp.MinLOD = desc.MinLOD;
|
||||
samp.MipLODBias = desc.MipLODBias;
|
||||
samp.UseComparison = (desc.Filter >= D3D11_FILTER_COMPARISON_MIN_MAG_MIP_POINT);
|
||||
samp.UseBorder = (desc.AddressU == D3D11_TEXTURE_ADDRESS_BORDER ||
|
||||
desc.AddressV == D3D11_TEXTURE_ADDRESS_BORDER ||
|
||||
desc.AddressW == D3D11_TEXTURE_ADDRESS_BORDER);
|
||||
}
|
||||
}
|
||||
|
||||
create_array_uninit(dst.SRVs, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT);
|
||||
for(size_t s = 0; s < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; s++)
|
||||
{
|
||||
D3D11PipelineState::ShaderStage::ResourceView &view = dst.SRVs[s];
|
||||
|
||||
view.View = rm->GetOriginalID(GetIDForResource(src.SRVs[s]));
|
||||
|
||||
if(view.View != ResourceId())
|
||||
{
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC desc;
|
||||
src.SRVs[s]->GetDesc(&desc);
|
||||
|
||||
view.Format = MakeResourceFormat(desc.Format);
|
||||
|
||||
ID3D11Resource *res = NULL;
|
||||
src.SRVs[s]->GetResource(&res);
|
||||
|
||||
view.Structured = false;
|
||||
view.BufferStructCount = 0;
|
||||
|
||||
view.ElementSize =
|
||||
desc.Format == DXGI_FORMAT_UNKNOWN ? 1 : GetByteSize(1, 1, 1, desc.Format, 0);
|
||||
|
||||
view.Resource = rm->GetOriginalID(GetIDForResource(res));
|
||||
|
||||
view.Type = ToStr::Get(desc.ViewDimension);
|
||||
|
||||
if(desc.ViewDimension == D3D11_SRV_DIMENSION_BUFFER)
|
||||
{
|
||||
view.FirstElement = desc.Buffer.FirstElement;
|
||||
view.NumElements = desc.Buffer.NumElements;
|
||||
view.ElementOffset = desc.Buffer.ElementOffset;
|
||||
view.ElementWidth = desc.Buffer.ElementWidth;
|
||||
|
||||
D3D11_BUFFER_DESC bufdesc;
|
||||
((ID3D11Buffer *)res)->GetDesc(&bufdesc);
|
||||
|
||||
view.Structured = bufdesc.StructureByteStride > 0 && desc.Format == DXGI_FORMAT_UNKNOWN;
|
||||
|
||||
if(view.Structured)
|
||||
view.ElementSize = bufdesc.StructureByteStride;
|
||||
}
|
||||
else if(desc.ViewDimension == D3D11_SRV_DIMENSION_BUFFEREX)
|
||||
{
|
||||
view.FirstElement = desc.BufferEx.FirstElement;
|
||||
view.NumElements = desc.BufferEx.NumElements;
|
||||
view.Flags = desc.BufferEx.Flags;
|
||||
}
|
||||
else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE1D)
|
||||
{
|
||||
view.HighestMip = desc.Texture1D.MostDetailedMip;
|
||||
view.NumMipLevels = desc.Texture1D.MipLevels;
|
||||
}
|
||||
else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE1DARRAY)
|
||||
{
|
||||
view.ArraySize = desc.Texture1DArray.ArraySize;
|
||||
view.FirstArraySlice = desc.Texture1DArray.FirstArraySlice;
|
||||
view.HighestMip = desc.Texture1DArray.MostDetailedMip;
|
||||
view.NumMipLevels = desc.Texture1DArray.MipLevels;
|
||||
}
|
||||
else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE2D)
|
||||
{
|
||||
view.HighestMip = desc.Texture2D.MostDetailedMip;
|
||||
view.NumMipLevels = desc.Texture2D.MipLevels;
|
||||
}
|
||||
else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE2DARRAY)
|
||||
{
|
||||
view.ArraySize = desc.Texture2DArray.ArraySize;
|
||||
view.FirstArraySlice = desc.Texture2DArray.FirstArraySlice;
|
||||
view.HighestMip = desc.Texture2DArray.MostDetailedMip;
|
||||
view.NumMipLevels = desc.Texture2DArray.MipLevels;
|
||||
}
|
||||
else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE2DMS)
|
||||
{
|
||||
}
|
||||
else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY)
|
||||
{
|
||||
view.ArraySize = desc.Texture2DArray.ArraySize;
|
||||
view.FirstArraySlice = desc.Texture2DArray.FirstArraySlice;
|
||||
}
|
||||
else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURE3D)
|
||||
{
|
||||
view.HighestMip = desc.Texture3D.MostDetailedMip;
|
||||
view.NumMipLevels = desc.Texture3D.MipLevels;
|
||||
}
|
||||
else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURECUBE)
|
||||
{
|
||||
view.ArraySize = 6;
|
||||
view.HighestMip = desc.TextureCube.MostDetailedMip;
|
||||
view.NumMipLevels = desc.TextureCube.MipLevels;
|
||||
}
|
||||
else if(desc.ViewDimension == D3D11_SRV_DIMENSION_TEXTURECUBEARRAY)
|
||||
{
|
||||
view.ArraySize = desc.TextureCubeArray.NumCubes * 6;
|
||||
view.FirstArraySlice = desc.TextureCubeArray.First2DArrayFace;
|
||||
view.HighestMip = desc.TextureCubeArray.MostDetailedMip;
|
||||
view.NumMipLevels = desc.TextureCubeArray.MipLevels;
|
||||
}
|
||||
|
||||
SAFE_RELEASE(res);
|
||||
}
|
||||
}
|
||||
|
||||
create_array(dst.UAVs, D3D11_1_UAV_SLOT_COUNT);
|
||||
for(size_t s = 0; dst.stage == eShaderStage_Compute && s < D3D11_1_UAV_SLOT_COUNT; s++)
|
||||
{
|
||||
D3D11PipelineState::ShaderStage::ResourceView &view = dst.UAVs[s];
|
||||
|
||||
view.View = rm->GetOriginalID(GetIDForResource(rs.CSUAVs[s]));
|
||||
|
||||
if(view.View != ResourceId())
|
||||
{
|
||||
D3D11_UNORDERED_ACCESS_VIEW_DESC desc;
|
||||
rs.CSUAVs[s]->GetDesc(&desc);
|
||||
|
||||
ID3D11Resource *res = NULL;
|
||||
rs.CSUAVs[s]->GetResource(&res);
|
||||
|
||||
view.Structured = false;
|
||||
view.BufferStructCount = 0;
|
||||
|
||||
view.ElementSize =
|
||||
desc.Format == DXGI_FORMAT_UNKNOWN ? 1 : GetByteSize(1, 1, 1, desc.Format, 0);
|
||||
|
||||
if(desc.ViewDimension == D3D11_UAV_DIMENSION_BUFFER &&
|
||||
(desc.Buffer.Flags & (D3D11_BUFFER_UAV_FLAG_APPEND | D3D11_BUFFER_UAV_FLAG_COUNTER)))
|
||||
{
|
||||
view.BufferStructCount = m_pDevice->GetDebugManager()->GetStructCount(rs.CSUAVs[s]);
|
||||
}
|
||||
|
||||
view.Resource = rm->GetOriginalID(GetIDForResource(res));
|
||||
|
||||
view.Format = MakeResourceFormat(desc.Format);
|
||||
view.Type = ToStr::Get(desc.ViewDimension);
|
||||
|
||||
if(desc.ViewDimension == D3D11_UAV_DIMENSION_BUFFER)
|
||||
{
|
||||
view.FirstElement = desc.Buffer.FirstElement;
|
||||
view.NumElements = desc.Buffer.NumElements;
|
||||
view.Flags = desc.Buffer.Flags;
|
||||
|
||||
D3D11_BUFFER_DESC bufdesc;
|
||||
((ID3D11Buffer *)res)->GetDesc(&bufdesc);
|
||||
|
||||
view.Structured = bufdesc.StructureByteStride > 0 && desc.Format == DXGI_FORMAT_UNKNOWN;
|
||||
|
||||
if(view.Structured)
|
||||
view.ElementSize = bufdesc.StructureByteStride;
|
||||
}
|
||||
else if(desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE1D)
|
||||
{
|
||||
view.HighestMip = desc.Texture1D.MipSlice;
|
||||
view.NumMipLevels = 1;
|
||||
}
|
||||
else if(desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE1DARRAY)
|
||||
{
|
||||
view.ArraySize = desc.Texture1DArray.ArraySize;
|
||||
view.FirstArraySlice = desc.Texture1DArray.FirstArraySlice;
|
||||
view.HighestMip = desc.Texture1DArray.MipSlice;
|
||||
view.NumMipLevels = 1;
|
||||
}
|
||||
else if(desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE2D)
|
||||
{
|
||||
view.HighestMip = desc.Texture2D.MipSlice;
|
||||
view.NumMipLevels = 1;
|
||||
}
|
||||
else if(desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE2DARRAY)
|
||||
{
|
||||
view.ArraySize = desc.Texture2DArray.ArraySize;
|
||||
view.FirstArraySlice = desc.Texture2DArray.FirstArraySlice;
|
||||
view.HighestMip = desc.Texture2DArray.MipSlice;
|
||||
view.NumMipLevels = 1;
|
||||
}
|
||||
else if(desc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE3D)
|
||||
{
|
||||
view.ArraySize = desc.Texture3D.WSize;
|
||||
view.FirstArraySlice = desc.Texture3D.FirstWSlice;
|
||||
view.HighestMip = desc.Texture3D.MipSlice;
|
||||
view.NumMipLevels = 1;
|
||||
}
|
||||
|
||||
SAFE_RELEASE(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if(pipe && pipe->IsGraphics())
|
||||
{
|
||||
/////////////////////////////////////////////////
|
||||
// Stream Out
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
create_array_uninit(state.m_SO.Outputs, rs.streamouts.size());
|
||||
for(size_t s = 0; s < rs.streamouts.size(); s++)
|
||||
{
|
||||
state.m_SO.Outputs[s].Buffer = rm->GetOriginalID(rs.streamouts[s].buf);
|
||||
state.m_SO.Outputs[s].Offset = rs.streamouts[s].offs;
|
||||
state.m_SO.Outputs[s].Size = rs.streamouts[s].size;
|
||||
|
||||
state.m_SO.Outputs[s].WrittenCountBuffer = rm->GetOriginalID(rs.streamouts[s].countbuf);
|
||||
state.m_SO.Outputs[s].WrittenCountOffset = rs.streamouts[s].countoffs;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// Rasterizer
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
state.m_RS.SampleMask = pipe->graphics->SampleMask;
|
||||
|
||||
{
|
||||
D3D12PipelineState::Rasterizer::RasterizerState &dst = state.m_RS.m_State;
|
||||
D3D12_RASTERIZER_DESC &src = pipe->graphics->RasterizerState;
|
||||
|
||||
dst.AntialiasedLineEnable = src.AntialiasedLineEnable == TRUE;
|
||||
|
||||
dst.CullMode = eCull_None;
|
||||
if(src.CullMode == D3D12_CULL_MODE_FRONT)
|
||||
dst.CullMode = eCull_Front;
|
||||
if(src.CullMode == D3D12_CULL_MODE_BACK)
|
||||
dst.CullMode = eCull_Back;
|
||||
|
||||
dst.FillMode = eFill_Solid;
|
||||
if(src.FillMode == D3D12_FILL_MODE_WIREFRAME)
|
||||
dst.FillMode = eFill_Wireframe;
|
||||
|
||||
dst.DepthBias = src.DepthBias;
|
||||
dst.DepthBiasClamp = src.DepthBiasClamp;
|
||||
dst.DepthClip = src.DepthClipEnable == TRUE;
|
||||
dst.FrontCCW = src.FrontCounterClockwise == TRUE;
|
||||
dst.MultisampleEnable = src.MultisampleEnable == TRUE;
|
||||
dst.SlopeScaledDepthBias = src.SlopeScaledDepthBias;
|
||||
dst.ForcedSampleCount = src.ForcedSampleCount;
|
||||
dst.ConservativeRasterization =
|
||||
src.ConservativeRaster == D3D12_CONSERVATIVE_RASTERIZATION_MODE_ON;
|
||||
}
|
||||
|
||||
size_t i = 0;
|
||||
create_array_uninit(state.m_RS.Scissors,
|
||||
D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE);
|
||||
for(i = 0; i < rs.scissors.size(); i++)
|
||||
state.m_RS.Scissors[i] = D3D12PipelineState::Rasterizer::Scissor(
|
||||
rs.scissors[i].left, rs.scissors[i].top, rs.scissors[i].right, rs.scissors[i].bottom);
|
||||
|
||||
for(; i < D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; i++)
|
||||
state.m_RS.Scissors[i] = D3D12PipelineState::Rasterizer::Scissor(0, 0, 0, 0);
|
||||
|
||||
create_array_uninit(state.m_RS.Viewports,
|
||||
D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE);
|
||||
for(i = 0; i < rs.views.size(); i++)
|
||||
state.m_RS.Viewports[i] = D3D12PipelineState::Rasterizer::Viewport(
|
||||
rs.views[i].TopLeftX, rs.views[i].TopLeftY, rs.views[i].Width, rs.views[i].Height,
|
||||
rs.views[i].MinDepth, rs.views[i].MaxDepth);
|
||||
|
||||
for(; i < D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE; i++)
|
||||
state.m_RS.Viewports[i] = D3D12PipelineState::Rasterizer::Viewport(0, 0, 0, 0, 0, 0);
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// Output Merger
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
create_array(state.m_OM.RenderTargets, rs.rts.size());
|
||||
for(size_t i = 0; i < rs.rts.size(); i++)
|
||||
{
|
||||
D3D12PipelineState::ResourceView &view = state.m_OM.RenderTargets[i];
|
||||
|
||||
PortableHandle h = rs.rtSingle ? rs.rts[i] : rs.rts[i];
|
||||
|
||||
if(rs.rtSingle)
|
||||
h.index += (uint32_t)i;
|
||||
|
||||
FillResourceView(view, h);
|
||||
}
|
||||
|
||||
{
|
||||
D3D12PipelineState::ResourceView &view = state.m_OM.DepthTarget;
|
||||
|
||||
FillResourceView(view, rs.dsv);
|
||||
}
|
||||
|
||||
memcpy(state.m_OM.m_BlendState.BlendFactor, rs.blendFactor, sizeof(FLOAT) * 4);
|
||||
|
||||
{
|
||||
D3D12_BLEND_DESC &src = pipe->graphics->BlendState;
|
||||
|
||||
state.m_OM.m_BlendState.AlphaToCoverage = src.AlphaToCoverageEnable == TRUE;
|
||||
state.m_OM.m_BlendState.IndependentBlend = src.IndependentBlendEnable == TRUE;
|
||||
|
||||
create_array_uninit(state.m_OM.m_BlendState.Blends, 8);
|
||||
for(size_t i = 0; i < 8; i++)
|
||||
{
|
||||
D3D12PipelineState::OutputMerger::BlendState::RTBlend &blend =
|
||||
state.m_OM.m_BlendState.Blends[i];
|
||||
|
||||
blend.Enabled = src.RenderTarget[i].BlendEnable == TRUE;
|
||||
|
||||
blend.LogicEnabled = src.RenderTarget[i].LogicOpEnable == TRUE;
|
||||
blend.LogicOp = ToStr::Get(src.RenderTarget[i].LogicOp);
|
||||
|
||||
blend.m_AlphaBlend.Source = ToStr::Get(src.RenderTarget[i].SrcBlendAlpha);
|
||||
blend.m_AlphaBlend.Destination = ToStr::Get(src.RenderTarget[i].DestBlendAlpha);
|
||||
blend.m_AlphaBlend.Operation = ToStr::Get(src.RenderTarget[i].BlendOpAlpha);
|
||||
|
||||
blend.m_Blend.Source = ToStr::Get(src.RenderTarget[i].SrcBlend);
|
||||
blend.m_Blend.Destination = ToStr::Get(src.RenderTarget[i].DestBlend);
|
||||
blend.m_Blend.Operation = ToStr::Get(src.RenderTarget[i].BlendOp);
|
||||
|
||||
blend.WriteMask = src.RenderTarget[i].RenderTargetWriteMask;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
D3D12_DEPTH_STENCIL_DESC &src = pipe->graphics->DepthStencilState;
|
||||
|
||||
state.m_OM.m_State.DepthEnable = src.DepthEnable == TRUE;
|
||||
state.m_OM.m_State.DepthFunc = ToStr::Get(src.DepthFunc);
|
||||
state.m_OM.m_State.DepthWrites = src.DepthWriteMask == D3D12_DEPTH_WRITE_MASK_ALL;
|
||||
state.m_OM.m_State.StencilEnable = src.StencilEnable == TRUE;
|
||||
state.m_OM.m_State.StencilRef = rs.stencilRef;
|
||||
state.m_OM.m_State.StencilReadMask = src.StencilReadMask;
|
||||
state.m_OM.m_State.StencilWriteMask = src.StencilWriteMask;
|
||||
|
||||
state.m_OM.m_State.m_FrontFace.Func = ToStr::Get(src.FrontFace.StencilFunc);
|
||||
state.m_OM.m_State.m_FrontFace.DepthFailOp = ToStr::Get(src.FrontFace.StencilDepthFailOp);
|
||||
state.m_OM.m_State.m_FrontFace.PassOp = ToStr::Get(src.FrontFace.StencilPassOp);
|
||||
state.m_OM.m_State.m_FrontFace.FailOp = ToStr::Get(src.FrontFace.StencilFailOp);
|
||||
|
||||
state.m_OM.m_State.m_BackFace.Func = ToStr::Get(src.BackFace.StencilFunc);
|
||||
state.m_OM.m_State.m_BackFace.DepthFailOp = ToStr::Get(src.BackFace.StencilDepthFailOp);
|
||||
state.m_OM.m_State.m_BackFace.PassOp = ToStr::Get(src.BackFace.StencilPassOp);
|
||||
state.m_OM.m_State.m_BackFace.FailOp = ToStr::Get(src.BackFace.StencilFailOp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void D3D12Replay::RenderCheckerboard(Vec3f light, Vec3f dark)
|
||||
{
|
||||
m_pDevice->GetDebugManager()->RenderCheckerboard(light, dark);
|
||||
@@ -333,11 +1172,6 @@ APIProperties D3D12Replay::GetAPIProperties()
|
||||
return ret;
|
||||
}
|
||||
|
||||
ShaderReflection *D3D12Replay::GetShader(ResourceId shader, string entryPoint)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vector<DebugMessage> D3D12Replay::GetDebugMessages()
|
||||
{
|
||||
return vector<DebugMessage>();
|
||||
@@ -350,10 +1184,6 @@ vector<uint32_t> D3D12Replay::GetPassEvents(uint32_t eventID)
|
||||
return passEvents;
|
||||
}
|
||||
|
||||
void D3D12Replay::MakePipelineState()
|
||||
{
|
||||
}
|
||||
|
||||
void D3D12Replay::InitPostVSBuffers(uint32_t eventID)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
|
||||
class WrappedID3D12Device;
|
||||
|
||||
struct PortableHandle;
|
||||
|
||||
class D3D12Replay : public IReplayDriver
|
||||
{
|
||||
public:
|
||||
@@ -163,6 +165,8 @@ public:
|
||||
private:
|
||||
void MakePipelineState();
|
||||
|
||||
void FillResourceView(D3D12PipelineState::ResourceView &view, const PortableHandle &resHandle);
|
||||
|
||||
bool m_Proxy;
|
||||
|
||||
vector<ID3D12Resource *> m_ProxyResources;
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
******************************************************************************/
|
||||
|
||||
#include "d3d12_resources.h"
|
||||
#include "3rdparty/lz4/lz4.h"
|
||||
#include "d3d12_command_list.h"
|
||||
#include "d3d12_command_queue.h"
|
||||
|
||||
@@ -31,11 +32,121 @@ std::map<ResourceId, WrappedID3D12Resource *> WrappedID3D12Resource::m_List;
|
||||
std::map<WrappedID3D12PipelineState::DXBCKey, WrappedID3D12PipelineState::ShaderEntry *>
|
||||
WrappedID3D12PipelineState::m_Shaders;
|
||||
|
||||
const GUID RENDERDOC_ID3D12ShaderGUID_ShaderDebugMagicValue = RENDERDOC_ShaderDebugMagicValue_struct;
|
||||
|
||||
void WrappedID3D12PipelineState::ShaderEntry::TryReplaceOriginalByteCode()
|
||||
{
|
||||
if(!DXBC::DXBCFile::CheckForDebugInfo((const void *)&m_Bytecode[0], m_Bytecode.size()))
|
||||
{
|
||||
string originalPath = m_DebugInfoPath;
|
||||
|
||||
if(originalPath.empty())
|
||||
originalPath =
|
||||
DXBC::DXBCFile::GetDebugBinaryPath((const void *)&m_Bytecode[0], m_Bytecode.size());
|
||||
|
||||
if(!originalPath.empty())
|
||||
{
|
||||
bool lz4 = false;
|
||||
|
||||
if(!strncmp(originalPath.c_str(), "lz4#", 4))
|
||||
{
|
||||
originalPath = originalPath.substr(4);
|
||||
lz4 = true;
|
||||
}
|
||||
// could support more if we're willing to compile in the decompressor
|
||||
|
||||
FILE *originalShaderFile = NULL;
|
||||
|
||||
size_t numSearchPaths = m_DebugInfoSearchPaths ? m_DebugInfoSearchPaths->size() : 0;
|
||||
|
||||
string foundPath;
|
||||
|
||||
// while we haven't found a file, keep trying through the search paths. For i==0
|
||||
// check the path on its own, in case it's an absolute path.
|
||||
for(size_t i = 0; originalShaderFile == NULL && i <= numSearchPaths; i++)
|
||||
{
|
||||
if(i == 0)
|
||||
{
|
||||
originalShaderFile = FileIO::fopen(originalPath.c_str(), "rb");
|
||||
foundPath = originalPath;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
const std::string &searchPath = (*m_DebugInfoSearchPaths)[i - 1];
|
||||
foundPath = searchPath + "/" + originalPath;
|
||||
originalShaderFile = FileIO::fopen(foundPath.c_str(), "rb");
|
||||
}
|
||||
}
|
||||
|
||||
if(originalShaderFile == NULL)
|
||||
return;
|
||||
|
||||
FileIO::fseek64(originalShaderFile, 0L, SEEK_END);
|
||||
uint64_t originalShaderSize = FileIO::ftell64(originalShaderFile);
|
||||
FileIO::fseek64(originalShaderFile, 0, SEEK_SET);
|
||||
|
||||
if(lz4 || originalShaderSize >= m_Bytecode.size())
|
||||
{
|
||||
vector<byte> originalBytecode;
|
||||
|
||||
originalBytecode.resize((size_t)originalShaderSize);
|
||||
FileIO::fread(&originalBytecode[0], sizeof(byte), (size_t)originalShaderSize,
|
||||
originalShaderFile);
|
||||
|
||||
if(lz4)
|
||||
{
|
||||
vector<byte> decompressed;
|
||||
|
||||
// first try decompressing to 1MB flat
|
||||
decompressed.resize(100 * 1024);
|
||||
|
||||
int ret = LZ4_decompress_safe((const char *)&originalBytecode[0], (char *)&decompressed[0],
|
||||
(int)originalBytecode.size(), (int)decompressed.size());
|
||||
|
||||
if(ret < 0)
|
||||
{
|
||||
// if it failed, either source is corrupt or we didn't allocate enough space.
|
||||
// Just allocate 255x compressed size since it can't need any more than that.
|
||||
decompressed.resize(255 * originalBytecode.size());
|
||||
|
||||
ret = LZ4_decompress_safe((const char *)&originalBytecode[0], (char *)&decompressed[0],
|
||||
(int)originalBytecode.size(), (int)decompressed.size());
|
||||
|
||||
if(ret < 0)
|
||||
{
|
||||
RDCERR("Failed to decompress LZ4 data from %s", foundPath.c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
RDCASSERT(ret > 0, ret);
|
||||
|
||||
// we resize and memcpy instead of just doing .swap() because that would
|
||||
// transfer over the over-large pessimistic capacity needed for decompression
|
||||
originalBytecode.resize(ret);
|
||||
memcpy(&originalBytecode[0], &decompressed[0], originalBytecode.size());
|
||||
}
|
||||
|
||||
if(DXBC::DXBCFile::CheckForDebugInfo((const void *)&originalBytecode[0],
|
||||
originalBytecode.size()))
|
||||
{
|
||||
m_Bytecode.swap(originalBytecode);
|
||||
}
|
||||
}
|
||||
|
||||
FileIO::fclose(originalShaderFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#undef D3D12_TYPE_MACRO
|
||||
#define D3D12_TYPE_MACRO(iface) WRAPPED_POOL_INST(CONCAT(Wrapped, iface));
|
||||
|
||||
ALL_D3D12_TYPES;
|
||||
|
||||
WRAPPED_POOL_INST(WrappedID3D12PipelineState::ShaderEntry);
|
||||
|
||||
D3D12ResourceType IdentifyTypeByPtr(ID3D12DeviceChild *ptr)
|
||||
{
|
||||
if(ptr == NULL)
|
||||
@@ -70,6 +181,9 @@ TrackedResource *GetTracked(ID3D12DeviceChild *ptr)
|
||||
|
||||
ALL_D3D12_TYPES;
|
||||
|
||||
if(WrappedID3D12PipelineState::ShaderEntry::IsAlloc(ptr))
|
||||
return (TrackedResource *)(WrappedID3D12PipelineState::ShaderEntry *)ptr;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ private:
|
||||
D3D12ResourceRecord *m_pRecord;
|
||||
};
|
||||
|
||||
extern const GUID RENDERDOC_ID3D11ShaderGUID_ShaderDebugMagicValue;
|
||||
extern const GUID RENDERDOC_ID3D12ShaderGUID_ShaderDebugMagicValue;
|
||||
|
||||
template <typename NestedType, typename NestedType1 = NestedType, typename NestedType2 = NestedType1>
|
||||
class WrappedDeviceChild12 : public RefCounter12<NestedType>, public NestedType2, public TrackedResource
|
||||
@@ -61,16 +61,21 @@ protected:
|
||||
{
|
||||
m_pDevice->SoftRef();
|
||||
|
||||
bool ret = m_pDevice->GetResourceManager()->AddWrapper(this, real);
|
||||
if(!ret)
|
||||
RDCERR("Error adding wrapper for type %s", ToStr::Get(__uuidof(NestedType)).c_str());
|
||||
if(real)
|
||||
{
|
||||
bool ret = m_pDevice->GetResourceManager()->AddWrapper(this, real);
|
||||
if(!ret)
|
||||
RDCERR("Error adding wrapper for type %s", ToStr::Get(__uuidof(NestedType)).c_str());
|
||||
}
|
||||
|
||||
m_pDevice->GetResourceManager()->AddCurrentResource(GetResourceID(), this);
|
||||
}
|
||||
|
||||
virtual void Shutdown()
|
||||
{
|
||||
m_pDevice->GetResourceManager()->RemoveWrapper(m_pReal);
|
||||
if(m_pReal)
|
||||
m_pDevice->GetResourceManager()->RemoveWrapper(m_pReal);
|
||||
|
||||
m_pDevice->GetResourceManager()->ReleaseCurrentResource(GetResourceID());
|
||||
m_pDevice->ReleaseResource((NestedType *)this);
|
||||
SAFE_RELEASE(m_pReal);
|
||||
@@ -225,7 +230,7 @@ public:
|
||||
|
||||
HRESULT STDMETHODCALLTYPE SetPrivateData(REFGUID guid, UINT DataSize, const void *pData)
|
||||
{
|
||||
if(guid == RENDERDOC_ID3D11ShaderGUID_ShaderDebugMagicValue)
|
||||
if(guid == RENDERDOC_ID3D12ShaderGUID_ShaderDebugMagicValue)
|
||||
return m_pDevice->SetShaderDebugPath(this, (const char *)pData);
|
||||
|
||||
if(guid == WKPDID_D3DDebugObjectName)
|
||||
@@ -419,6 +424,8 @@ public:
|
||||
D3D12_GRAPHICS_PIPELINE_STATE_DESC *graphics;
|
||||
D3D12_COMPUTE_PIPELINE_STATE_DESC *compute;
|
||||
|
||||
bool IsGraphics() { return graphics != NULL; }
|
||||
bool IsCompute() { return compute != NULL; }
|
||||
struct DXBCKey
|
||||
{
|
||||
DXBCKey(const D3D12_SHADER_BYTECODE &byteCode)
|
||||
@@ -450,40 +457,34 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class ShaderEntry
|
||||
class ShaderEntry : public WrappedDeviceChild12<ID3D12DeviceChild>
|
||||
{
|
||||
public:
|
||||
ShaderEntry() : m_DebugInfoSearchPaths(NULL), m_DXBCFile(NULL), m_Details(NULL) {}
|
||||
ShaderEntry(const D3D12_SHADER_BYTECODE &byteCode)
|
||||
static const int AllocPoolCount = 16384;
|
||||
static const int AllocMaxByteSize = 8 * 1024 * 1024;
|
||||
ALLOCATE_WITH_WRAPPED_POOL(ShaderEntry, AllocPoolCount, AllocMaxByteSize);
|
||||
|
||||
ShaderEntry(const D3D12_SHADER_BYTECODE &byteCode, WrappedID3D12Device *device)
|
||||
: WrappedDeviceChild12(NULL, device), m_Key(byteCode)
|
||||
{
|
||||
const byte *code = (const byte *)byteCode.pShaderBytecode;
|
||||
m_Bytecode.assign(code, code + byteCode.BytecodeLength);
|
||||
m_DebugInfoSearchPaths = NULL;
|
||||
m_DXBCFile = NULL;
|
||||
m_Details = NULL;
|
||||
|
||||
m_RefCount = 1;
|
||||
device->GetResourceManager()->AddLiveResource(GetResourceID(), this);
|
||||
|
||||
m_Built = false;
|
||||
}
|
||||
~ShaderEntry()
|
||||
|
||||
virtual ~ShaderEntry()
|
||||
{
|
||||
m_Bytecode.clear();
|
||||
SAFE_DELETE(m_DXBCFile);
|
||||
SAFE_DELETE(m_Details);
|
||||
}
|
||||
|
||||
void AddRef() { m_RefCount++; }
|
||||
bool Release()
|
||||
{
|
||||
m_RefCount--;
|
||||
if(m_RefCount <= 0)
|
||||
{
|
||||
delete this;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
DXBCKey GetKey() { return m_Key; }
|
||||
void SetDebugInfoPath(vector<std::string> *searchPaths, const std::string &path)
|
||||
{
|
||||
m_DebugInfoSearchPaths = searchPaths;
|
||||
@@ -499,40 +500,73 @@ public:
|
||||
}
|
||||
return m_DXBCFile;
|
||||
}
|
||||
ShaderReflection *GetDetails()
|
||||
ShaderReflection &GetDetails()
|
||||
{
|
||||
if(m_Details == NULL && GetDXBC() != NULL)
|
||||
m_Details = MakeShaderReflection(m_DXBCFile);
|
||||
if(!m_Built && GetDXBC() != NULL)
|
||||
MakeShaderReflection(m_DXBCFile, &m_Details, &m_Mapping);
|
||||
m_Built = true;
|
||||
return m_Details;
|
||||
}
|
||||
const ShaderBindpointMapping &GetMapping()
|
||||
{
|
||||
if(!m_Built && GetDXBC() != NULL)
|
||||
MakeShaderReflection(m_DXBCFile, &m_Details, &m_Mapping);
|
||||
m_Built = true;
|
||||
return m_Mapping;
|
||||
}
|
||||
|
||||
private:
|
||||
ShaderEntry(const ShaderEntry &e);
|
||||
void TryReplaceOriginalByteCode();
|
||||
ShaderEntry &operator=(const ShaderEntry &e);
|
||||
|
||||
int m_RefCount;
|
||||
DXBCKey m_Key;
|
||||
|
||||
std::string m_DebugInfoPath;
|
||||
vector<std::string> *m_DebugInfoSearchPaths;
|
||||
|
||||
vector<byte> m_Bytecode;
|
||||
|
||||
bool m_Built;
|
||||
DXBC::DXBCFile *m_DXBCFile;
|
||||
ShaderReflection *m_Details;
|
||||
ShaderReflection m_Details;
|
||||
ShaderBindpointMapping m_Mapping;
|
||||
};
|
||||
|
||||
static map<DXBCKey, ShaderEntry *> m_Shaders;
|
||||
|
||||
enum
|
||||
{
|
||||
TypeEnum = Resource_PipelineState,
|
||||
};
|
||||
|
||||
static ShaderEntry *AddShader(const D3D12_SHADER_BYTECODE &byteCode, WrappedID3D12Device *device)
|
||||
{
|
||||
DXBCKey key(byteCode);
|
||||
ShaderEntry *shader = m_Shaders[key];
|
||||
|
||||
if(shader == NULL)
|
||||
shader = m_Shaders[key] = new ShaderEntry(byteCode, device);
|
||||
else
|
||||
shader->AddRef();
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
static void ReleaseShader(ShaderEntry *shader)
|
||||
{
|
||||
if(shader == NULL)
|
||||
return;
|
||||
|
||||
DXBCKey key = shader->GetKey();
|
||||
|
||||
if(shader->Release() == 0)
|
||||
m_Shaders.erase(key);
|
||||
}
|
||||
|
||||
WrappedID3D12PipelineState(ID3D12PipelineState *real, WrappedID3D12Device *device)
|
||||
: WrappedDeviceChild12(real, device)
|
||||
{
|
||||
graphics = NULL;
|
||||
compute = NULL;
|
||||
}
|
||||
virtual ~WrappedID3D12PipelineState()
|
||||
{
|
||||
@@ -540,44 +574,26 @@ public:
|
||||
|
||||
if(graphics)
|
||||
{
|
||||
DXBCKey *vs = (DXBCKey *)graphics->VS.pShaderBytecode;
|
||||
DXBCKey *hs = (DXBCKey *)graphics->HS.pShaderBytecode;
|
||||
DXBCKey *ds = (DXBCKey *)graphics->DS.pShaderBytecode;
|
||||
DXBCKey *gs = (DXBCKey *)graphics->GS.pShaderBytecode;
|
||||
DXBCKey *ps = (DXBCKey *)graphics->PS.pShaderBytecode;
|
||||
ShaderEntry *vs = (ShaderEntry *)graphics->VS.pShaderBytecode;
|
||||
ShaderEntry *hs = (ShaderEntry *)graphics->HS.pShaderBytecode;
|
||||
ShaderEntry *ds = (ShaderEntry *)graphics->DS.pShaderBytecode;
|
||||
ShaderEntry *gs = (ShaderEntry *)graphics->GS.pShaderBytecode;
|
||||
ShaderEntry *ps = (ShaderEntry *)graphics->PS.pShaderBytecode;
|
||||
|
||||
if(m_Shaders[*vs]->Release())
|
||||
m_Shaders.erase(*vs);
|
||||
|
||||
if(m_Shaders[*hs]->Release())
|
||||
m_Shaders.erase(*hs);
|
||||
|
||||
if(m_Shaders[*ds]->Release())
|
||||
m_Shaders.erase(*ds);
|
||||
|
||||
if(m_Shaders[*gs]->Release())
|
||||
m_Shaders.erase(*gs);
|
||||
|
||||
if(m_Shaders[*ps]->Release())
|
||||
m_Shaders.erase(*ps);
|
||||
|
||||
SAFE_DELETE(vs);
|
||||
SAFE_DELETE(hs);
|
||||
SAFE_DELETE(ds);
|
||||
SAFE_DELETE(gs);
|
||||
SAFE_DELETE(ps);
|
||||
ReleaseShader(vs);
|
||||
ReleaseShader(hs);
|
||||
ReleaseShader(ds);
|
||||
ReleaseShader(gs);
|
||||
ReleaseShader(ps);
|
||||
|
||||
SAFE_DELETE(graphics);
|
||||
}
|
||||
|
||||
if(compute)
|
||||
{
|
||||
DXBCKey *cs = (DXBCKey *)compute->CS.pShaderBytecode;
|
||||
ShaderEntry *cs = (ShaderEntry *)compute->CS.pShaderBytecode;
|
||||
|
||||
if(m_Shaders[*cs]->Release())
|
||||
m_Shaders.erase(*cs);
|
||||
|
||||
SAFE_DELETE(cs);
|
||||
ReleaseShader(cs);
|
||||
|
||||
SAFE_DELETE(compute);
|
||||
}
|
||||
@@ -590,6 +606,9 @@ public:
|
||||
{
|
||||
return m_pReal->GetCachedBlob(ppBlob);
|
||||
}
|
||||
|
||||
private:
|
||||
static map<DXBCKey, ShaderEntry *> m_Shaders;
|
||||
};
|
||||
|
||||
class WrappedID3D12QueryHeap : public WrappedDeviceChild12<ID3D12QueryHeap>
|
||||
|
||||
@@ -157,6 +157,17 @@ struct D3D12RenderState
|
||||
|
||||
vector<ResourceId> heaps;
|
||||
|
||||
struct StreamOut
|
||||
{
|
||||
ResourceId buf;
|
||||
UINT64 offs;
|
||||
UINT64 size;
|
||||
|
||||
ResourceId countbuf;
|
||||
UINT64 countoffs;
|
||||
};
|
||||
vector<StreamOut> streamouts;
|
||||
|
||||
struct Pipeline
|
||||
{
|
||||
ResourceId rootsig;
|
||||
|
||||
@@ -1643,12 +1643,9 @@ void ReplayRenderer::FetchPipelineState()
|
||||
&m_D3D12PipelineState.m_GS, &m_D3D12PipelineState.m_PS, &m_D3D12PipelineState.m_CS,
|
||||
};
|
||||
|
||||
const char *stageNames[] = {"VS", "HS", "DS", "GS", "PS", "CS"};
|
||||
|
||||
for(int i = 0; i < 6; i++)
|
||||
if(stages[i]->Present)
|
||||
stages[i]->ShaderDetails =
|
||||
m_pDevice->GetShader(m_pDevice->GetLiveID(m_D3D12PipelineState.pipeline), stageNames[i]);
|
||||
if(stages[i]->Shader != ResourceId())
|
||||
stages[i]->ShaderDetails = m_pDevice->GetShader(m_pDevice->GetLiveID(stages[i]->Shader), "");
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
@@ -95,7 +95,6 @@ namespace renderdoc
|
||||
}
|
||||
|
||||
public ResourceId Shader;
|
||||
public bool Present;
|
||||
private IntPtr _ptr_ShaderDetails;
|
||||
[CustomMarshalAs(CustomUnmanagedType.Skip)]
|
||||
public ShaderReflection ShaderDetails;
|
||||
@@ -122,7 +121,7 @@ namespace renderdoc
|
||||
public D3DBufferViewFlags BufferFlags;
|
||||
public UInt32 BufferStructCount;
|
||||
public UInt32 ElementSize;
|
||||
public UInt32 FirstElement;
|
||||
public UInt64 FirstElement;
|
||||
public UInt32 NumElements;
|
||||
|
||||
public ResourceId CounterResource;
|
||||
|
||||
@@ -300,12 +300,12 @@ namespace renderdocui.Windows.PipelineState
|
||||
D3D12PipelineState state = m_Core.CurD3D12PipelineState;
|
||||
ShaderReflection shaderDetails = stage.ShaderDetails;
|
||||
|
||||
if (!stage.Present)
|
||||
if (stage.Shader == ResourceId.Null)
|
||||
shader.Text = "Unbound";
|
||||
else if (state.customName)
|
||||
shader.Text = state.PipelineName + " - " + m_Core.CurPipelineState.Abbrev(stage.stage);
|
||||
else
|
||||
shader.Text = stage.stage.Str(GraphicsAPI.D3D12);
|
||||
shader.Text = state.PipelineName + " - " + stage.stage.Str(GraphicsAPI.D3D12) + " Shader";
|
||||
|
||||
if (shaderDetails != null && shaderDetails.DebugInfo.entryFunc.Length > 0 && shaderDetails.DebugInfo.files.Length > 0)
|
||||
{
|
||||
@@ -439,7 +439,7 @@ namespace renderdocui.Windows.PipelineState
|
||||
|
||||
bool iaUsed = false;
|
||||
|
||||
if (state.m_VS.Present)
|
||||
if (state.m_VS.Shader != ResourceId.Null)
|
||||
{
|
||||
for (int ia = 0; ia < state.m_VS.ShaderDetails.InputSig.Length; ia++)
|
||||
{
|
||||
@@ -2469,7 +2469,7 @@ namespace renderdocui.Windows.PipelineState
|
||||
|
||||
string shadername = "Unknown";
|
||||
|
||||
if (!sh.Present)
|
||||
if (sh.Shader == ResourceId.Null)
|
||||
shadername = "Unbound";
|
||||
else if (state.customName)
|
||||
shadername = state.PipelineName + " - " + m_Core.CurPipelineState.Abbrev(sh.stage);
|
||||
|
||||
@@ -1476,6 +1476,9 @@ namespace renderdocui.Windows
|
||||
ShaderReflection details = Following.GetReflection(m_Core, stage);
|
||||
ShaderBindpointMapping mapping = Following.GetMapping(m_Core, stage);
|
||||
|
||||
if (mapping == null)
|
||||
continue;
|
||||
|
||||
InitStageResourcePreviews(stage,
|
||||
details != null ? details.ReadWriteResources : new ShaderResource[0],
|
||||
mapping.ReadWriteResources,
|
||||
|
||||
Reference in New Issue
Block a user