Process root signature elements into pipeline state

This commit is contained in:
baldurk
2016-09-22 12:05:47 +02:00
parent 2e8b758fef
commit b9b419c86a
10 changed files with 688 additions and 395 deletions
+38 -36
View File
@@ -83,10 +83,16 @@ struct D3D12PipelineState
ShaderStageType stage;
} m_VS, m_HS, m_DS, m_GS, m_PS, m_CS;
// Immediate indicates either a root parameter (not in a table), or static samplers
// RootElement is the index in the original root signature that this descriptor came from.
struct ResourceView
{
ResourceView()
: Resource(),
: VisibilityMask(),
Immediate(0),
RootElement(0),
Resource(),
Format(),
BufferFlags(0),
BufferStructCount(0),
@@ -106,6 +112,12 @@ struct D3D12PipelineState
swizzle[3] = eSwizzle_Alpha;
}
// parameters from descriptor
ShaderStageBits VisibilityMask;
bool32 Immediate;
uint32_t RootElement;
// parameters from resource/view
ResourceId Resource;
rdctype::str Type;
ResourceFormat Format;
@@ -134,7 +146,10 @@ struct D3D12PipelineState
struct Sampler
{
Sampler()
: UseBorder(false),
: VisibilityMask(),
Immediate(0),
RootElement(0),
UseBorder(false),
UseComparison(false),
MaxAniso(0),
MaxLOD(0.0f),
@@ -143,6 +158,13 @@ struct D3D12PipelineState
{
BorderColor[0] = BorderColor[1] = BorderColor[2] = BorderColor[3] = 0.0f;
}
// parameters from descriptor
ShaderStageBits VisibilityMask;
bool32 Immediate;
uint32_t RootElement;
// parameters from resource/view
rdctype::str AddressU, AddressV, AddressW;
float BorderColor[4];
rdctype::str Comparison;
@@ -157,52 +179,32 @@ struct D3D12PipelineState
struct CBuffer
{
CBuffer() : Buffer(), Offset(0), ByteSize(0) {}
CBuffer() : VisibilityMask(), Immediate(0), RootElement(0), Buffer(), Offset(0), ByteSize(0) {}
// parameters from descriptor
ShaderStageBits VisibilityMask;
bool32 Immediate;
uint32_t RootElement;
// parameters from resource/view
ResourceId Buffer;
uint64_t Offset;
uint32_t ByteSize;
rdctype::array<uint32_t> Immediate;
rdctype::array<uint32_t> RootValues;
};
struct RootSignature
{
ResourceId obj;
// Immediate indicates either a root parameter (not in a table), or static samplers
// RootElement is the index in the original root signature that this descriptor came from.
struct CBufferDescriptor
struct RegisterSpace
{
ShaderStageBits VisibilityMask;
bool32 Immediate;
uint32_t RootElement;
CBuffer obj;
rdctype::array<CBuffer> ConstantBuffers;
rdctype::array<Sampler> Samplers;
rdctype::array<ResourceView> SRVs;
rdctype::array<ResourceView> UAVs;
};
struct ViewDescriptor
{
ShaderStageBits VisibilityMask;
bool32 Immediate;
uint32_t RootElement;
ResourceView obj;
};
struct SamplerDescriptor
{
ShaderStageBits VisibilityMask;
bool32 Immediate;
uint32_t RootElement;
Sampler obj;
};
rdctype::array<CBufferDescriptor> ConstantBuffers;
rdctype::array<SamplerDescriptor> Samplers;
rdctype::array<ViewDescriptor> SRVs;
rdctype::array<ViewDescriptor> UAVs;
rdctype::array<RegisterSpace> Spaces;
} m_RootSig;
struct Streamout
+4
View File
@@ -320,6 +320,7 @@ enum ShaderStageType
enum ShaderStageBits
{
eStageBits_None = 0,
eStageBits_Vertex = 1 << eShaderStage_Vertex,
eStageBits_Hull = 1 << eShaderStage_Hull,
eStageBits_Tess_Control = 1 << eShaderStage_Tess_Control,
@@ -329,6 +330,9 @@ enum ShaderStageBits
eStageBits_Pixel = 1 << eShaderStage_Pixel,
eStageBits_Fragment = 1 << eShaderStage_Fragment,
eStageBits_Compute = 1 << eShaderStage_Compute,
eStageBits_All = eStageBits_Vertex | eStageBits_Hull | eStageBits_Domain | eStageBits_Geometry |
eStageBits_Pixel |
eStageBits_Compute,
};
enum DebugMessageCategory
+5 -2
View File
@@ -647,12 +647,15 @@ D3D11PipelineState D3D11Replay::MakePipelineState()
samp.Filter = ToStr::Get(desc.Filter);
samp.MaxAniso = 0;
if(desc.Filter == D3D11_FILTER_ANISOTROPIC ||
desc.Filter == D3D11_FILTER_COMPARISON_ANISOTROPIC)
desc.Filter == D3D11_FILTER_COMPARISON_ANISOTROPIC ||
desc.Filter == D3D11_FILTER_MINIMUM_ANISOTROPIC ||
desc.Filter == D3D11_FILTER_MAXIMUM_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.UseComparison = (desc.Filter >= D3D11_FILTER_COMPARISON_MIN_MAG_MIP_POINT &&
desc.Filter <= D3D11_FILTER_COMPARISON_ANISOTROPIC);
samp.UseBorder = (desc.AddressU == D3D11_TEXTURE_ADDRESS_BORDER ||
desc.AddressV == D3D11_TEXTURE_ADDRESS_BORDER ||
desc.AddressW == D3D11_TEXTURE_ADDRESS_BORDER);
+314
View File
@@ -28,9 +28,308 @@
#include "d3d12_manager.h"
#include "d3d12_resources.h"
static ShaderConstant MakeConstantBufferVariable(const DXBC::CBufferVariable &var, uint32_t &offset);
static ShaderVariableType MakeShaderVariableType(DXBC::CBufferVariableType type, uint32_t &offset)
{
ShaderVariableType ret;
switch(type.descriptor.type)
{
case DXBC::VARTYPE_INT: ret.descriptor.type = eVar_Int; break;
case DXBC::VARTYPE_BOOL:
case DXBC::VARTYPE_UINT: ret.descriptor.type = eVar_UInt; break;
case DXBC::VARTYPE_DOUBLE: ret.descriptor.type = eVar_Double; break;
case DXBC::VARTYPE_FLOAT:
default: ret.descriptor.type = eVar_Float; break;
}
ret.descriptor.rows = type.descriptor.rows;
ret.descriptor.cols = type.descriptor.cols;
ret.descriptor.elements = type.descriptor.elements;
ret.descriptor.name = type.descriptor.name;
ret.descriptor.rowMajorStorage = (type.descriptor.varClass == DXBC::CLASS_MATRIX_ROWS);
uint32_t baseElemSize = (ret.descriptor.type == eVar_Double) ? 8 : 4;
if(ret.descriptor.rowMajorStorage)
{
uint32_t primary = ret.descriptor.rows;
if(primary == 3)
primary = 4;
ret.descriptor.arrayStride = baseElemSize * primary * ret.descriptor.cols;
}
else
{
uint32_t primary = ret.descriptor.cols;
if(primary == 3)
primary = 4;
ret.descriptor.arrayStride = baseElemSize * primary * ret.descriptor.rows;
}
uint32_t o = offset;
create_array_uninit(ret.members, type.members.size());
for(size_t i = 0; i < type.members.size(); i++)
{
offset = o;
ret.members[i] = MakeConstantBufferVariable(type.members[i], offset);
}
if(ret.members.count > 0)
{
ret.descriptor.rows = 0;
ret.descriptor.cols = 0;
ret.descriptor.elements = 0;
}
return ret;
}
static ShaderConstant MakeConstantBufferVariable(const DXBC::CBufferVariable &var, uint32_t &offset)
{
ShaderConstant ret;
ret.name = var.name;
ret.reg.vec = offset + var.descriptor.offset / 16;
ret.reg.comp = (var.descriptor.offset - (var.descriptor.offset & ~0xf)) / 4;
ret.defaultValue = 0;
offset = ret.reg.vec;
ret.type = MakeShaderVariableType(var.type, offset);
offset = ret.reg.vec + RDCMAX(1U, var.type.descriptor.bytesize / 16);
return ret;
}
void MakeShaderReflection(DXBC::DXBCFile *dxbc, ShaderReflection *refl,
ShaderBindpointMapping *mapping)
{
if(dxbc == NULL || !RenderDoc::Inst().IsReplayApp())
return;
if(dxbc->m_DebugInfo)
{
refl->DebugInfo.entryFunc = dxbc->m_DebugInfo->GetEntryFunction();
refl->DebugInfo.compileFlags = dxbc->m_DebugInfo->GetShaderCompileFlags();
refl->DebugInfo.entryFile = -1;
create_array_uninit(refl->DebugInfo.files, dxbc->m_DebugInfo->Files.size());
for(size_t i = 0; i < dxbc->m_DebugInfo->Files.size(); i++)
{
refl->DebugInfo.files[i].first = dxbc->m_DebugInfo->Files[i].first;
refl->DebugInfo.files[i].second = dxbc->m_DebugInfo->Files[i].second;
if(refl->DebugInfo.entryFile == -1 &&
strstr(refl->DebugInfo.files[i].second.elems, refl->DebugInfo.entryFunc.elems))
{
refl->DebugInfo.entryFile = (int32_t)i;
}
}
}
refl->Disassembly = dxbc->GetDisassembly();
if(dxbc->m_ShaderBlob.empty())
create_array_uninit(refl->RawBytes, 0);
else
create_array_init(refl->RawBytes, dxbc->m_ShaderBlob.size(), &dxbc->m_ShaderBlob[0]);
refl->DispatchThreadsDimension[0] = dxbc->DispatchThreadsDimension[0];
refl->DispatchThreadsDimension[1] = dxbc->DispatchThreadsDimension[1];
refl->DispatchThreadsDimension[2] = dxbc->DispatchThreadsDimension[2];
refl->InputSig = dxbc->m_InputSig;
refl->OutputSig = dxbc->m_OutputSig;
create_array_uninit(mapping->InputAttributes, D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT);
for(int s = 0; s < D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; s++)
mapping->InputAttributes[s] = s;
int numCbuffers = 0;
// skip 'empty' cbuffers added for the benefit of D3D11
for(size_t i = 0; i < dxbc->m_CBuffers.size(); i++)
{
if(dxbc->m_CBuffers[i].descriptor.type == DXBC::CBuffer::Descriptor::TYPE_CBUFFER)
numCbuffers++;
}
create_array_uninit(mapping->ConstantBlocks, numCbuffers);
create_array_uninit(refl->ConstantBlocks, numCbuffers);
for(size_t i = 0, c = 0; i < dxbc->m_CBuffers.size(); i++)
{
ConstantBlock &cb = refl->ConstantBlocks[c];
if(dxbc->m_CBuffers[i].descriptor.type != DXBC::CBuffer::Descriptor::TYPE_CBUFFER)
continue;
cb.name = dxbc->m_CBuffers[i].name;
cb.bufferBacked = true;
cb.byteSize = dxbc->m_CBuffers[i].descriptor.byteSize;
cb.bindPoint = (uint32_t)c;
BindpointMap map = {};
map.arraySize = 1;
map.bind = (int32_t)i;
map.used = true;
mapping->ConstantBlocks[c] = map;
create_array_uninit(cb.variables, dxbc->m_CBuffers[i].variables.size());
for(size_t v = 0; v < dxbc->m_CBuffers[i].variables.size(); v++)
{
uint32_t vecOffset = 0;
cb.variables[v] = MakeConstantBufferVariable(dxbc->m_CBuffers[i].variables[v], vecOffset);
}
}
int numRWResources = 0;
int numROResources = 0;
for(size_t i = 0; i < dxbc->m_Resources.size(); i++)
{
const auto &r = dxbc->m_Resources[i];
if(r.type != DXBC::ShaderInputBind::TYPE_CBUFFER)
{
bool IsReadWrite = (r.type == DXBC::ShaderInputBind::TYPE_UAV_RWTYPED ||
r.type == DXBC::ShaderInputBind::TYPE_UAV_RWSTRUCTURED ||
r.type == DXBC::ShaderInputBind::TYPE_UAV_RWBYTEADDRESS ||
r.type == DXBC::ShaderInputBind::TYPE_UAV_APPEND_STRUCTURED ||
r.type == DXBC::ShaderInputBind::TYPE_UAV_CONSUME_STRUCTURED ||
r.type == DXBC::ShaderInputBind::TYPE_UAV_RWSTRUCTURED_WITH_COUNTER);
if(IsReadWrite)
numRWResources++;
else
numROResources++;
}
}
create_array_uninit(mapping->ReadWriteResources, numRWResources);
create_array_uninit(refl->ReadWriteResources, numRWResources);
create_array_uninit(mapping->ReadOnlyResources, numROResources);
create_array_uninit(refl->ReadOnlyResources, numROResources);
int32_t rwidx = 0, roidx = 0;
for(size_t i = 0; i < dxbc->m_Resources.size(); i++)
{
const auto &r = dxbc->m_Resources[i];
if(r.type == DXBC::ShaderInputBind::TYPE_CBUFFER)
continue;
ShaderResource res;
res.name = r.name;
res.IsSampler = (r.type == DXBC::ShaderInputBind::TYPE_SAMPLER);
res.IsTexture = (r.type == DXBC::ShaderInputBind::TYPE_TEXTURE &&
r.dimension != DXBC::ShaderInputBind::DIM_UNKNOWN &&
r.dimension != DXBC::ShaderInputBind::DIM_BUFFER &&
r.dimension != DXBC::ShaderInputBind::DIM_BUFFEREX);
res.IsSRV = (r.type == DXBC::ShaderInputBind::TYPE_TBUFFER ||
r.type == DXBC::ShaderInputBind::TYPE_TEXTURE ||
r.type == DXBC::ShaderInputBind::TYPE_STRUCTURED ||
r.type == DXBC::ShaderInputBind::TYPE_BYTEADDRESS);
bool IsReadWrite = (r.type == DXBC::ShaderInputBind::TYPE_UAV_RWTYPED ||
r.type == DXBC::ShaderInputBind::TYPE_UAV_RWSTRUCTURED ||
r.type == DXBC::ShaderInputBind::TYPE_UAV_RWBYTEADDRESS ||
r.type == DXBC::ShaderInputBind::TYPE_UAV_APPEND_STRUCTURED ||
r.type == DXBC::ShaderInputBind::TYPE_UAV_CONSUME_STRUCTURED ||
r.type == DXBC::ShaderInputBind::TYPE_UAV_RWSTRUCTURED_WITH_COUNTER);
switch(r.dimension)
{
default:
case DXBC::ShaderInputBind::DIM_UNKNOWN: res.resType = eResType_None; break;
case DXBC::ShaderInputBind::DIM_BUFFER:
case DXBC::ShaderInputBind::DIM_BUFFEREX: res.resType = eResType_Buffer; break;
case DXBC::ShaderInputBind::DIM_TEXTURE1D: res.resType = eResType_Texture1D; break;
case DXBC::ShaderInputBind::DIM_TEXTURE1DARRAY: res.resType = eResType_Texture1DArray; break;
case DXBC::ShaderInputBind::DIM_TEXTURE2D: res.resType = eResType_Texture2D; break;
case DXBC::ShaderInputBind::DIM_TEXTURE2DARRAY: res.resType = eResType_Texture2DArray; break;
case DXBC::ShaderInputBind::DIM_TEXTURE2DMS: res.resType = eResType_Texture2DMS; break;
case DXBC::ShaderInputBind::DIM_TEXTURE2DMSARRAY:
res.resType = eResType_Texture2DMSArray;
break;
case DXBC::ShaderInputBind::DIM_TEXTURE3D: res.resType = eResType_Texture3D; break;
case DXBC::ShaderInputBind::DIM_TEXTURECUBE: res.resType = eResType_TextureCube; break;
case DXBC::ShaderInputBind::DIM_TEXTURECUBEARRAY:
res.resType = eResType_TextureCubeArray;
break;
}
if(r.retType != DXBC::ShaderInputBind::RETTYPE_UNKNOWN &&
r.retType != DXBC::ShaderInputBind::RETTYPE_MIXED &&
r.retType != DXBC::ShaderInputBind::RETTYPE_CONTINUED)
{
res.variableType.descriptor.rows = 1;
res.variableType.descriptor.cols = r.numSamples;
res.variableType.descriptor.elements = 1;
string name;
switch(r.retType)
{
case DXBC::ShaderInputBind::RETTYPE_UNORM: name = "unorm float"; break;
case DXBC::ShaderInputBind::RETTYPE_SNORM: name = "snorm float"; break;
case DXBC::ShaderInputBind::RETTYPE_SINT: name = "int"; break;
case DXBC::ShaderInputBind::RETTYPE_UINT: name = "uint"; break;
case DXBC::ShaderInputBind::RETTYPE_FLOAT: name = "float"; break;
case DXBC::ShaderInputBind::RETTYPE_DOUBLE: name = "double"; break;
default: name = "unknown"; break;
}
name += ToStr::Get(r.numSamples);
res.variableType.descriptor.name = name;
}
else
{
if(dxbc->m_ResourceBinds.find(r.name) != dxbc->m_ResourceBinds.end())
{
uint32_t vecOffset = 0;
res.variableType = MakeShaderVariableType(dxbc->m_ResourceBinds[r.name], vecOffset);
}
else
{
res.variableType.descriptor.rows = 0;
res.variableType.descriptor.cols = 0;
res.variableType.descriptor.elements = 0;
res.variableType.descriptor.name = "";
}
}
res.bindPoint = IsReadWrite ? rwidx : roidx;
BindpointMap map = {};
map.arraySize = 1;
map.bind = r.bindPoint;
map.used = true;
if(IsReadWrite)
{
refl->ReadWriteResources[rwidx++] = res;
mapping->ReadWriteResources[i] = map;
}
else
{
refl->ReadOnlyResources[roidx++] = res;
mapping->ReadOnlyResources[i] = map;
}
}
uint32_t numInterfaces = 0;
for(size_t i = 0; i < dxbc->m_Interfaces.variables.size(); i++)
numInterfaces = RDCMAX(dxbc->m_Interfaces.variables[i].descriptor.offset + 1, numInterfaces);
create_array(refl->Interfaces, numInterfaces);
for(size_t i = 0; i < dxbc->m_Interfaces.variables.size(); i++)
refl->Interfaces[dxbc->m_Interfaces.variables[i].descriptor.offset] =
dxbc->m_Interfaces.variables[i].name;
}
enum D3D12ResourceBarrierSubresource
@@ -127,6 +426,21 @@ UINT GetNumSubresources(const D3D12_RESOURCE_DESC *desc)
return 1;
}
ShaderStageBits ConvertVisibility(D3D12_SHADER_VISIBILITY ShaderVisibility)
{
switch(ShaderVisibility)
{
case D3D12_SHADER_VISIBILITY_ALL: return eStageBits_All;
case D3D12_SHADER_VISIBILITY_VERTEX: return eStageBits_Vertex;
case D3D12_SHADER_VISIBILITY_HULL: return eStageBits_Hull;
case D3D12_SHADER_VISIBILITY_DOMAIN: return eStageBits_Domain;
case D3D12_SHADER_VISIBILITY_GEOMETRY: return eStageBits_Geometry;
case D3D12_SHADER_VISIBILITY_PIXEL: return eStageBits_Pixel;
}
return eStageBits_Vertex;
}
string ToStrHelper<false, D3D12ComponentMapping>::Get(const D3D12ComponentMapping &el)
{
string ret;
+16 -1
View File
@@ -57,6 +57,7 @@ void MakeShaderReflection(DXBC::DXBCFile *dxbc, ShaderReflection *refl,
// buffer replay is happening
#define VERBOSE_PARTIAL_REPLAY
ShaderStageBits ConvertVisibility(D3D12_SHADER_VISIBILITY ShaderVisibility);
UINT GetNumSubresources(const D3D12_RESOURCE_DESC *desc);
class WrappedID3D12Device;
@@ -125,7 +126,7 @@ public:
struct D3D12RootSignatureParameter : D3D12_ROOT_PARAMETER
{
void MakeFrom(const D3D12_ROOT_PARAMETER &param)
void MakeFrom(const D3D12_ROOT_PARAMETER &param, UINT &numSpaces)
{
ParameterType = param.ParameterType;
ShaderVisibility = param.ShaderVisibility;
@@ -138,11 +139,23 @@ struct D3D12RootSignatureParameter : D3D12_ROOT_PARAMETER
{
ranges.resize(param.DescriptorTable.NumDescriptorRanges);
for(size_t i = 0; i < ranges.size(); i++)
{
ranges[i] = param.DescriptorTable.pDescriptorRanges[i];
numSpaces = RDCMAX(numSpaces, ranges[i].RegisterSpace + 1);
}
DescriptorTable.NumDescriptorRanges = (UINT)ranges.size();
DescriptorTable.pDescriptorRanges = &ranges[0];
}
else if(ParameterType == D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS)
{
numSpaces = RDCMAX(numSpaces, Constants.RegisterSpace + 1);
}
else
{
numSpaces = RDCMAX(numSpaces, Descriptor.RegisterSpace + 1);
}
}
vector<D3D12_DESCRIPTOR_RANGE> ranges;
@@ -150,6 +163,8 @@ struct D3D12RootSignatureParameter : D3D12_ROOT_PARAMETER
struct D3D12RootSignature
{
D3D12RootSignature() : numSpaces(0) {}
uint32_t numSpaces;
vector<D3D12RootSignatureParameter> params;
vector<D3D12_STATIC_SAMPLER_DESC> samplers;
};
+6 -1
View File
@@ -830,11 +830,16 @@ D3D12RootSignature D3D12DebugManager::GetRootSig(const void *data, size_t dataSi
ret.params.resize(desc->NumParameters);
for(size_t i = 0; i < ret.params.size(); i++)
ret.params[i].MakeFrom(desc->pParameters[i]);
ret.params[i].MakeFrom(desc->pParameters[i], ret.numSpaces);
if(desc->NumStaticSamplers > 0)
{
ret.samplers.assign(desc->pStaticSamplers, desc->pStaticSamplers + desc->NumStaticSamplers);
for(size_t i = 0; i < ret.samplers.size(); i++)
ret.numSpaces = RDCMAX(ret.numSpaces, ret.samplers[i].RegisterSpace + 1);
}
SAFE_RELEASE(deser);
return ret;
+280 -316
View File
@@ -28,6 +28,15 @@
#include "d3d12_device.h"
#include "d3d12_resources.h"
template <class T>
T &resize_and_add(std::vector<T> &vec, size_t idx)
{
if(idx >= vec.size())
vec.resize(idx + 1);
return vec[idx];
}
D3D12Replay::D3D12Replay()
{
m_pDevice = NULL;
@@ -244,20 +253,10 @@ vector<EventUsage> D3D12Replay::GetUsage(ResourceId id)
return m_pDevice->GetQueue()->GetUsage(id);
}
void D3D12Replay::FillResourceView(D3D12PipelineState::ResourceView &view,
const PortableHandle &resHandle)
void D3D12Replay::FillResourceView(D3D12PipelineState::ResourceView &view, D3D12Descriptor *desc)
{
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");
@@ -561,7 +560,7 @@ void D3D12Replay::MakePipelineState()
// Shaders
/////////////////////////////////////////////////
ResourceId rootSig;
const D3D12RenderState::RootSignature *rootSig = NULL;
if(pipe && pipe->IsCompute())
{
@@ -570,8 +569,9 @@ void D3D12Replay::MakePipelineState()
state.m_CS.Shader = sh->GetResourceID();
state.m_CS.stage = eShaderStage_Compute;
state.m_CS.BindpointMapping = sh->GetMapping();
rootSig = rs.compute.rootsig;
rootSig = &rs.compute;
}
else if(pipe)
{
@@ -598,331 +598,281 @@ void D3D12Replay::MakePipelineState()
}
}
rootSig = rs.graphics.rootsig;
rootSig = &rs.graphics;
}
#if 0
if(rootSig)
{
D3D11PipelineState::ShaderStage &dst = *dstArr[stage];
const D3D11RenderState::shader &src = *srcArr[stage];
state.m_RootSig.obj = rm->GetOriginalID(rootSig->rootsig);
dst.stage = (ShaderStageType)stage;
WrappedID3D12RootSignature *sig =
m_pDevice->GetResourceManager()->GetCurrentAs<WrappedID3D12RootSignature>(rootSig->rootsig);
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())
struct Space
{
dst.customName = false;
str = StringFormat::Fmt("%s Shader %llu", stageNames[stage], dst.Shader);
}
vector<D3D12PipelineState::CBuffer> cbuffers;
vector<D3D12PipelineState::Sampler> samplers;
vector<D3D12PipelineState::ResourceView> srvs;
vector<D3D12PipelineState::ResourceView> uavs;
};
dst.ShaderName = str;
Space *spaces = new Space[sig->sig.numSpaces];
create_array_uninit(state.m_RootSig.Spaces, sig->sig.numSpaces);
// 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++)
for(size_t rootEl = 0; rootEl < RDCMIN(sig->sig.params.size(), rootSig->sigelems.size()); rootEl++)
{
// 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;
}
const D3D12RenderState::SignatureElement &e = rootSig->sigelems[rootEl];
const D3D12RootSignatureParameter &p = sig->sig.params[rootEl];
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())
if(p.ParameterType == D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS && e.type == eRootConst)
{
samp.SamplerName = GetDebugName(src.Samplers[s]);
samp.customSamplerName = true;
D3D12PipelineState::CBuffer &cb =
resize_and_add(spaces[p.Constants.RegisterSpace].cbuffers, p.Constants.ShaderRegister);
cb.VisibilityMask = ConvertVisibility(p.ShaderVisibility);
cb.Immediate = true;
cb.RootElement = (uint32_t)rootEl;
cb.ByteSize = uint32_t(sizeof(uint32_t) * p.Constants.Num32BitValues);
if(samp.SamplerName.count == 0)
create_array_init(cb.RootValues, e.constants.size(), &e.constants[0]);
}
else if(p.ParameterType == D3D12_ROOT_PARAMETER_TYPE_CBV && e.type == eRootCBV)
{
D3D12PipelineState::CBuffer &cb =
resize_and_add(spaces[p.Constants.RegisterSpace].cbuffers, p.Constants.ShaderRegister);
cb.VisibilityMask = ConvertVisibility(p.ShaderVisibility);
cb.Immediate = true;
cb.RootElement = (uint32_t)rootEl;
ID3D12Resource *res = rm->GetCurrentAs<ID3D12Resource>(e.id);
cb.Buffer = rm->GetOriginalID(e.id);
cb.Offset = e.offset;
cb.ByteSize = uint32_t(res->GetDesc().Width - cb.Offset);
}
else if(p.ParameterType == D3D12_ROOT_PARAMETER_TYPE_SRV && e.type == eRootSRV)
{
D3D12PipelineState::ResourceView &view =
resize_and_add(spaces[p.Constants.RegisterSpace].srvs, p.Constants.ShaderRegister);
view.VisibilityMask = ConvertVisibility(p.ShaderVisibility);
view.Immediate = true;
view.RootElement = (uint32_t)rootEl;
ID3D12Resource *res = rm->GetCurrentAs<ID3D12Resource>(e.id);
// parameters from resource/view
view.Resource = rm->GetOriginalID(e.id);
view.Type = ToStr::Get(D3D12_SRV_DIMENSION_BUFFER);
view.Format = MakeResourceFormat(DXGI_FORMAT_R32_UINT);
view.ElementSize = sizeof(uint32_t);
view.FirstElement = e.offset / sizeof(uint32_t);
view.NumElements = uint32_t((res->GetDesc().Width - e.offset) / sizeof(uint32_t));
}
else if(p.ParameterType == D3D12_ROOT_PARAMETER_TYPE_UAV && e.type == eRootUAV)
{
D3D12PipelineState::ResourceView &view =
resize_and_add(spaces[p.Constants.RegisterSpace].uavs, p.Constants.ShaderRegister);
view.VisibilityMask = ConvertVisibility(p.ShaderVisibility);
view.Immediate = true;
view.RootElement = (uint32_t)rootEl;
ID3D12Resource *res = rm->GetCurrentAs<ID3D12Resource>(e.id);
// parameters from resource/view
view.Resource = rm->GetOriginalID(e.id);
view.Type = ToStr::Get(D3D12_UAV_DIMENSION_BUFFER);
view.Format = MakeResourceFormat(DXGI_FORMAT_R32_UINT);
view.ElementSize = sizeof(uint32_t);
view.FirstElement = e.offset / sizeof(uint32_t);
view.NumElements = uint32_t((res->GetDesc().Width - e.offset) / sizeof(uint32_t));
}
else if(p.ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE && e.type == eRootTable)
{
WrappedID3D12DescriptorHeap *heap = rm->GetCurrentAs<WrappedID3D12DescriptorHeap>(e.id);
UINT prevTableOffset = 0;
for(size_t r = 0; r < p.ranges.size(); r++)
{
samp.customSamplerName = false;
samp.SamplerName = StringFormat::Fmt("Sampler %llu", samp.Samp);
const D3D12_DESCRIPTOR_RANGE &range = p.ranges[r];
UINT shaderReg = range.BaseShaderRegister;
UINT regSpace = range.RegisterSpace;
D3D12Descriptor *desc = (D3D12Descriptor *)heap->GetCPUDescriptorHandleForHeapStart().ptr;
UINT offset = range.OffsetInDescriptorsFromTableStart;
if(range.OffsetInDescriptorsFromTableStart == D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND)
offset = prevTableOffset;
desc += offset;
prevTableOffset = offset + range.NumDescriptors;
if(range.RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER)
{
UINT maxReg = shaderReg + range.NumDescriptors - 1;
if(maxReg >= spaces[regSpace].samplers.size())
spaces[regSpace].samplers.resize(maxReg + 1);
for(UINT i = 0; i < range.NumDescriptors; i++, desc++, shaderReg++)
{
D3D12PipelineState::Sampler &samp = spaces[regSpace].samplers[shaderReg];
samp.VisibilityMask = ConvertVisibility(p.ShaderVisibility);
samp.Immediate = false;
samp.RootElement = (uint32_t)rootEl;
D3D12_SAMPLER_DESC &sampDesc = desc->samp.desc;
samp.AddressU = ToStr::Get(sampDesc.AddressU);
samp.AddressV = ToStr::Get(sampDesc.AddressV);
samp.AddressW = ToStr::Get(sampDesc.AddressW);
memcpy(samp.BorderColor, sampDesc.BorderColor, sizeof(FLOAT) * 4);
samp.Comparison = ToStr::Get(sampDesc.ComparisonFunc);
samp.Filter = ToStr::Get(sampDesc.Filter);
samp.MaxAniso = 0;
if(sampDesc.Filter == D3D12_FILTER_ANISOTROPIC ||
sampDesc.Filter == D3D12_FILTER_COMPARISON_ANISOTROPIC ||
sampDesc.Filter == D3D12_FILTER_MINIMUM_ANISOTROPIC ||
sampDesc.Filter == D3D12_FILTER_MAXIMUM_ANISOTROPIC)
samp.MaxAniso = sampDesc.MaxAnisotropy;
samp.MaxLOD = sampDesc.MaxLOD;
samp.MinLOD = sampDesc.MinLOD;
samp.MipLODBias = sampDesc.MipLODBias;
samp.UseComparison = (sampDesc.Filter >= D3D12_FILTER_COMPARISON_MIN_MAG_MIP_POINT &&
sampDesc.Filter <= D3D12_FILTER_COMPARISON_ANISOTROPIC);
samp.UseBorder = (sampDesc.AddressU == D3D12_TEXTURE_ADDRESS_MODE_BORDER ||
sampDesc.AddressV == D3D12_TEXTURE_ADDRESS_MODE_BORDER ||
sampDesc.AddressW == D3D12_TEXTURE_ADDRESS_MODE_BORDER);
}
}
else if(range.RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_CBV)
{
UINT maxReg = shaderReg + range.NumDescriptors - 1;
if(maxReg >= spaces[regSpace].cbuffers.size())
spaces[regSpace].cbuffers.resize(maxReg + 1);
for(UINT i = 0; i < range.NumDescriptors; i++, desc++, shaderReg++)
{
D3D12PipelineState::CBuffer &cb = spaces[regSpace].cbuffers[shaderReg];
cb.VisibilityMask = ConvertVisibility(p.ShaderVisibility);
cb.Immediate = false;
cb.RootElement = (uint32_t)rootEl;
WrappedID3D12Resource::GetResIDFromAddr(desc->nonsamp.cbv.BufferLocation, cb.Buffer,
cb.Offset);
cb.Buffer = rm->GetOriginalID(cb.Buffer);
cb.ByteSize = desc->nonsamp.cbv.SizeInBytes;
}
}
else if(range.RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SRV)
{
UINT maxReg = shaderReg + range.NumDescriptors - 1;
if(maxReg >= spaces[regSpace].srvs.size())
spaces[regSpace].srvs.resize(maxReg + 1);
for(UINT i = 0; i < range.NumDescriptors; i++, desc++, shaderReg++)
{
D3D12PipelineState::ResourceView &view = spaces[regSpace].srvs[shaderReg];
view.VisibilityMask = ConvertVisibility(p.ShaderVisibility);
view.Immediate = false;
view.RootElement = (uint32_t)rootEl;
FillResourceView(view, desc);
}
}
else if(range.RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_UAV)
{
UINT maxReg = shaderReg + range.NumDescriptors - 1;
if(maxReg >= spaces[regSpace].uavs.size())
spaces[regSpace].uavs.resize(maxReg + 1);
for(UINT i = 0; i < range.NumDescriptors; i++, desc++, shaderReg++)
{
D3D12PipelineState::ResourceView &view = spaces[regSpace].uavs[shaderReg];
view.VisibilityMask = ConvertVisibility(p.ShaderVisibility);
view.Immediate = false;
view.RootElement = (uint32_t)rootEl;
FillResourceView(view, desc);
}
}
}
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++)
for(size_t i = 0; i < sig->sig.samplers.size(); i++)
{
D3D11PipelineState::ShaderStage::ResourceView &view = dst.SRVs[s];
D3D12_STATIC_SAMPLER_DESC &sampDesc = sig->sig.samplers[i];
view.View = rm->GetOriginalID(GetIDForResource(src.SRVs[s]));
D3D12PipelineState::Sampler &samp =
resize_and_add(spaces[sampDesc.RegisterSpace].samplers, sampDesc.ShaderRegister);
samp.VisibilityMask = ConvertVisibility(sampDesc.ShaderVisibility);
samp.Immediate = true;
samp.RootElement = (uint32_t)i;
if(view.View != ResourceId())
samp.AddressU = ToStr::Get(sampDesc.AddressU);
samp.AddressV = ToStr::Get(sampDesc.AddressV);
samp.AddressW = ToStr::Get(sampDesc.AddressW);
if(sampDesc.BorderColor == D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK)
{
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);
samp.BorderColor[0] = 0.0f;
samp.BorderColor[1] = 0.0f;
samp.BorderColor[2] = 0.0f;
samp.BorderColor[3] = 0.0f;
}
else if(sampDesc.BorderColor == D3D12_STATIC_BORDER_COLOR_OPAQUE_BLACK)
{
samp.BorderColor[0] = 0.0f;
samp.BorderColor[1] = 0.0f;
samp.BorderColor[2] = 0.0f;
samp.BorderColor[3] = 1.0f;
}
else if(sampDesc.BorderColor == D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE)
{
samp.BorderColor[0] = 1.0f;
samp.BorderColor[1] = 1.0f;
samp.BorderColor[2] = 1.0f;
samp.BorderColor[3] = 1.0f;
}
else
{
RDCERR("Unexpected static border colour: %u", sampDesc.BorderColor);
}
samp.Comparison = ToStr::Get(sampDesc.ComparisonFunc);
samp.Filter = ToStr::Get(sampDesc.Filter);
samp.MaxAniso = 0;
if(sampDesc.Filter == D3D12_FILTER_ANISOTROPIC ||
sampDesc.Filter == D3D12_FILTER_COMPARISON_ANISOTROPIC ||
sampDesc.Filter == D3D12_FILTER_MINIMUM_ANISOTROPIC ||
sampDesc.Filter == D3D12_FILTER_MAXIMUM_ANISOTROPIC)
samp.MaxAniso = sampDesc.MaxAnisotropy;
samp.MaxLOD = sampDesc.MaxLOD;
samp.MinLOD = sampDesc.MinLOD;
samp.MipLODBias = sampDesc.MipLODBias;
samp.UseComparison = (sampDesc.Filter >= D3D12_FILTER_COMPARISON_MIN_MAG_MIP_POINT &&
sampDesc.Filter <= D3D12_FILTER_COMPARISON_ANISOTROPIC);
samp.UseBorder = (sampDesc.AddressU == D3D12_TEXTURE_ADDRESS_MODE_BORDER ||
sampDesc.AddressV == D3D12_TEXTURE_ADDRESS_MODE_BORDER ||
sampDesc.AddressW == D3D12_TEXTURE_ADDRESS_MODE_BORDER);
}
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++)
for(uint32_t i = 0; i < sig->sig.numSpaces; i++)
{
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);
}
state.m_RootSig.Spaces[i].ConstantBuffers = spaces[i].cbuffers;
state.m_RootSig.Spaces[i].Samplers = spaces[i].samplers;
state.m_RootSig.Spaces[i].SRVs = spaces[i].srvs;
state.m_RootSig.Spaces[i].UAVs = spaces[i].uavs;
}
SAFE_DELETE_ARRAY(spaces);
}
#endif
if(pipe && pipe->IsGraphics())
{
@@ -994,18 +944,32 @@ void D3D12Replay::MakePipelineState()
{
D3D12PipelineState::ResourceView &view = state.m_OM.RenderTargets[i];
PortableHandle h = rs.rtSingle ? rs.rts[i] : rs.rts[i];
PortableHandle h = rs.rtSingle ? rs.rts[0] : rs.rts[i];
if(rs.rtSingle)
h.index += (uint32_t)i;
if(h.heap != ResourceId())
{
WrappedID3D12DescriptorHeap *heap = rm->GetLiveAs<WrappedID3D12DescriptorHeap>(h.heap);
D3D12Descriptor *desc =
(D3D12Descriptor *)heap->GetCPUDescriptorHandleForHeapStart().ptr + h.index;
FillResourceView(view, h);
if(rs.rtSingle)
desc += i;
FillResourceView(view, desc);
}
}
{
D3D12PipelineState::ResourceView &view = state.m_OM.DepthTarget;
FillResourceView(view, rs.dsv);
if(rs.dsv.heap != ResourceId())
{
WrappedID3D12DescriptorHeap *heap = rm->GetLiveAs<WrappedID3D12DescriptorHeap>(rs.dsv.heap);
D3D12Descriptor *desc =
(D3D12Descriptor *)heap->GetCPUDescriptorHandleForHeapStart().ptr + rs.dsv.index;
FillResourceView(view, desc);
}
}
memcpy(state.m_OM.m_BlendState.BlendFactor, rs.blendFactor, sizeof(FLOAT) * 4);
+1 -1
View File
@@ -165,7 +165,7 @@ public:
private:
void MakePipelineState();
void FillResourceView(D3D12PipelineState::ResourceView &view, const PortableHandle &resHandle);
void FillResourceView(D3D12PipelineState::ResourceView &view, D3D12Descriptor *desc);
bool m_Proxy;
+1 -1
View File
@@ -168,7 +168,7 @@ struct D3D12RenderState
};
vector<StreamOut> streamouts;
struct Pipeline
struct RootSignature
{
ResourceId rootsig;
+23 -37
View File
@@ -109,6 +109,10 @@ namespace renderdoc
[StructLayout(LayoutKind.Sequential)]
public class ResourceView
{
public ShaderStageBits VisibilityMask;
public bool Immediate;
public UInt32 RootElement;
public ResourceId Resource;
[CustomMarshalAs(CustomUnmanagedType.UTF8TemplatedString)]
public string Type;
@@ -141,6 +145,10 @@ namespace renderdoc
[StructLayout(LayoutKind.Sequential)]
public class Sampler
{
public ShaderStageBits VisibilityMask;
public bool Immediate;
public UInt32 RootElement;
[CustomMarshalAs(CustomUnmanagedType.UTF8TemplatedString)]
public string AddressU, AddressV, AddressW;
[CustomMarshalAs(CustomUnmanagedType.FixedArray, FixedLength = 4)]
@@ -160,12 +168,16 @@ namespace renderdoc
[StructLayout(LayoutKind.Sequential)]
public class CBuffer
{
public ShaderStageBits VisibilityMask;
public bool Immediate;
public UInt32 RootElement;
public ResourceId Buffer;
public UInt64 Offset;
public UInt32 ByteSize;
[CustomMarshalAs(CustomUnmanagedType.TemplatedArray)]
public UInt32[] Immediate;
public UInt32[] RootValues;
};
[StructLayout(LayoutKind.Sequential)]
@@ -174,46 +186,20 @@ namespace renderdoc
public ResourceId Obj;
[StructLayout(LayoutKind.Sequential)]
public class CBufferDescriptor
public class RegisterSpace
{
public ShaderStageBits VisibilityMask;
public bool Immediate;
public UInt32 RootElement;
[CustomMarshalAs(CustomUnmanagedType.CustomClass)]
CBuffer obj;
};
[StructLayout(LayoutKind.Sequential)]
public class ViewDescriptor
{
public ShaderStageBits VisibilityMask;
public bool Immediate;
public UInt32 RootElement;
[CustomMarshalAs(CustomUnmanagedType.CustomClass)]
ResourceView obj;
};
[StructLayout(LayoutKind.Sequential)]
public class SamplerDescriptor
{
public ShaderStageBits VisibilityMask;
public bool Immediate;
public UInt32 RootElement;
[CustomMarshalAs(CustomUnmanagedType.CustomClass)]
Sampler obj;
[CustomMarshalAs(CustomUnmanagedType.TemplatedArray)]
public CBuffer[] ConstantBuffers;
[CustomMarshalAs(CustomUnmanagedType.TemplatedArray)]
public Sampler[] Samplers;
[CustomMarshalAs(CustomUnmanagedType.TemplatedArray)]
public ResourceView[] SRVs;
[CustomMarshalAs(CustomUnmanagedType.TemplatedArray)]
public ResourceView[] UAVs;
};
[CustomMarshalAs(CustomUnmanagedType.TemplatedArray)]
public CBufferDescriptor[] ConstantBuffers;
[CustomMarshalAs(CustomUnmanagedType.TemplatedArray)]
public SamplerDescriptor[] Samplers;
[CustomMarshalAs(CustomUnmanagedType.TemplatedArray)]
public ViewDescriptor[] SRVs;
[CustomMarshalAs(CustomUnmanagedType.TemplatedArray)]
public ViewDescriptor[] UAVs;
public RegisterSpace[] Spaces;
};
[CustomMarshalAs(CustomUnmanagedType.CustomClass)]
public RootSignature m_RootSig;