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:
baldurk
2016-09-22 12:05:47 +02:00
parent d40b87aed0
commit 0f660e3ec2
13 changed files with 1073 additions and 115 deletions
+2 -2
View File
@@ -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;
+4
View File
@@ -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
+2 -1
View File
@@ -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.
+5 -29
View File
@@ -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);
}
+839 -9
View File
@@ -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)
{
}
+4
View File
@@ -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;
+114
View File
@@ -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;
}
+82 -63
View File
@@ -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>
+11
View File
@@ -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;
+2 -5
View File
@@ -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), "");
}
{
+1 -2
View File
@@ -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);
+3
View File
@@ -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,