mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-09 00:01:07 +00:00
Add register space support for shader global state UAV/SRV data
Instead of fixed arrays, the global state stores a map of UAVs and SRVs, with the key being a pair of the shader register and register space. Switched D3D12 sampler/gather to use SM5.1 and handle register spaces.
This commit is contained in:
committed by
Baldur Karlsson
parent
6cd2d18d9e
commit
654acb67f5
@@ -1069,31 +1069,33 @@ bool D3D11DebugAPIWrapper::CalculateSampleGather(
|
||||
ID3D11SamplerState *usedSamp = NULL;
|
||||
|
||||
// fetch SRV and sampler from the shader stage we're debugging that this opcode wants to load from
|
||||
UINT texSlot = resourceData.binding.shaderRegister;
|
||||
UINT samplerSlot = samplerData.binding.shaderRegister;
|
||||
switch(GetShaderType())
|
||||
{
|
||||
case DXBC::ShaderType::Vertex:
|
||||
context->VSGetShaderResources(resourceData.slot, 1, &usedSRV);
|
||||
context->VSGetSamplers(samplerData.slot, 1, &usedSamp);
|
||||
context->VSGetShaderResources(texSlot, 1, &usedSRV);
|
||||
context->VSGetSamplers(samplerSlot, 1, &usedSamp);
|
||||
break;
|
||||
case DXBC::ShaderType::Hull:
|
||||
context->HSGetShaderResources(resourceData.slot, 1, &usedSRV);
|
||||
context->HSGetSamplers(samplerData.slot, 1, &usedSamp);
|
||||
context->HSGetShaderResources(texSlot, 1, &usedSRV);
|
||||
context->HSGetSamplers(samplerSlot, 1, &usedSamp);
|
||||
break;
|
||||
case DXBC::ShaderType::Domain:
|
||||
context->DSGetShaderResources(resourceData.slot, 1, &usedSRV);
|
||||
context->DSGetSamplers(samplerData.slot, 1, &usedSamp);
|
||||
context->DSGetShaderResources(texSlot, 1, &usedSRV);
|
||||
context->DSGetSamplers(samplerSlot, 1, &usedSamp);
|
||||
break;
|
||||
case DXBC::ShaderType::Geometry:
|
||||
context->GSGetShaderResources(resourceData.slot, 1, &usedSRV);
|
||||
context->GSGetSamplers(samplerData.slot, 1, &usedSamp);
|
||||
context->GSGetShaderResources(texSlot, 1, &usedSRV);
|
||||
context->GSGetSamplers(samplerSlot, 1, &usedSamp);
|
||||
break;
|
||||
case DXBC::ShaderType::Pixel:
|
||||
context->PSGetShaderResources(resourceData.slot, 1, &usedSRV);
|
||||
context->PSGetSamplers(samplerData.slot, 1, &usedSamp);
|
||||
context->PSGetShaderResources(texSlot, 1, &usedSRV);
|
||||
context->PSGetSamplers(samplerSlot, 1, &usedSamp);
|
||||
break;
|
||||
case DXBC::ShaderType::Compute:
|
||||
context->CSGetShaderResources(resourceData.slot, 1, &usedSRV);
|
||||
context->CSGetSamplers(samplerData.slot, 1, &usedSamp);
|
||||
context->CSGetShaderResources(texSlot, 1, &usedSRV);
|
||||
context->CSGetSamplers(samplerSlot, 1, &usedSamp);
|
||||
break;
|
||||
default: RDCERR("Unhandled shader type %d", GetShaderType()); break;
|
||||
}
|
||||
@@ -1414,7 +1416,8 @@ void D3D11DebugManager::CreateShaderGlobalState(ShaderDebug::GlobalState &global
|
||||
ID3D11Resource *res = NULL;
|
||||
UAVs[i]->GetResource(&res);
|
||||
|
||||
global.uavs[dsti].hiddenCounter = GetStructCount(UAVs[i]);
|
||||
ShaderDebug::BindingSlot slot(dsti, 0);
|
||||
global.uavs[slot].hiddenCounter = GetStructCount(UAVs[i]);
|
||||
|
||||
D3D11_UNORDERED_ACCESS_VIEW_DESC udesc;
|
||||
UAVs[i]->GetDesc(&udesc);
|
||||
@@ -1450,37 +1453,37 @@ void D3D11DebugManager::CreateShaderGlobalState(ShaderDebug::GlobalState &global
|
||||
{
|
||||
ResourceFormat fmt = MakeResourceFormat(GetTypedFormat(udesc.Format));
|
||||
|
||||
global.uavs[dsti].format.byteWidth = fmt.compByteWidth;
|
||||
global.uavs[dsti].format.numComps = fmt.compCount;
|
||||
global.uavs[dsti].format.fmt = fmt.compType;
|
||||
global.uavs[slot].format.byteWidth = fmt.compByteWidth;
|
||||
global.uavs[slot].format.numComps = fmt.compCount;
|
||||
global.uavs[slot].format.fmt = fmt.compType;
|
||||
|
||||
if(udesc.Format == DXGI_FORMAT_R11G11B10_FLOAT)
|
||||
global.uavs[dsti].format.byteWidth = 11;
|
||||
global.uavs[slot].format.byteWidth = 11;
|
||||
if(udesc.Format == DXGI_FORMAT_R10G10B10A2_UINT ||
|
||||
udesc.Format == DXGI_FORMAT_R10G10B10A2_UNORM)
|
||||
global.uavs[dsti].format.byteWidth = 10;
|
||||
global.uavs[slot].format.byteWidth = 10;
|
||||
}
|
||||
|
||||
if(udesc.ViewDimension == D3D11_UAV_DIMENSION_BUFFER)
|
||||
{
|
||||
global.uavs[dsti].firstElement = udesc.Buffer.FirstElement;
|
||||
global.uavs[dsti].numElements = udesc.Buffer.NumElements;
|
||||
global.uavs[slot].firstElement = udesc.Buffer.FirstElement;
|
||||
global.uavs[slot].numElements = udesc.Buffer.NumElements;
|
||||
}
|
||||
|
||||
if(res)
|
||||
{
|
||||
if(WrappedID3D11Buffer::IsAlloc(res))
|
||||
{
|
||||
GetBufferData((ID3D11Buffer *)res, 0, 0, global.uavs[dsti].data);
|
||||
GetBufferData((ID3D11Buffer *)res, 0, 0, global.uavs[slot].data);
|
||||
}
|
||||
else
|
||||
{
|
||||
global.uavs[dsti].tex = true;
|
||||
global.uavs[slot].tex = true;
|
||||
|
||||
uint32_t &rowPitch = global.uavs[dsti].rowPitch;
|
||||
uint32_t &depthPitch = global.uavs[dsti].depthPitch;
|
||||
uint32_t &rowPitch = global.uavs[slot].rowPitch;
|
||||
uint32_t &depthPitch = global.uavs[slot].depthPitch;
|
||||
|
||||
bytebuf &data = global.uavs[dsti].data;
|
||||
bytebuf &data = global.uavs[slot].data;
|
||||
|
||||
if(udesc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE1D ||
|
||||
udesc.ViewDimension == D3D11_UAV_DIMENSION_TEXTURE1DARRAY)
|
||||
@@ -1627,9 +1630,11 @@ void D3D11DebugManager::CreateShaderGlobalState(ShaderDebug::GlobalState &global
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC sdesc;
|
||||
SRVs[i]->GetDesc(&sdesc);
|
||||
|
||||
ShaderDebug::BindingSlot slot(i, 0);
|
||||
|
||||
if(sdesc.Format != DXGI_FORMAT_UNKNOWN)
|
||||
{
|
||||
ShaderDebug::FillViewFmt(sdesc.Format, global.srvs[i].format);
|
||||
ShaderDebug::FillViewFmt(sdesc.Format, global.srvs[slot].format);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1642,11 +1647,11 @@ void D3D11DebugManager::CreateShaderGlobalState(ShaderDebug::GlobalState &global
|
||||
D3D11_BUFFER_DESC bufdesc;
|
||||
buf->GetDesc(&bufdesc);
|
||||
|
||||
global.srvs[i].format.stride = bufdesc.StructureByteStride;
|
||||
global.srvs[slot].format.stride = bufdesc.StructureByteStride;
|
||||
|
||||
// if we didn't get a type from the SRV description, try to pull it from the declaration
|
||||
ShaderDebug::LookupSRVFormatFromShaderReflection(*dxbc->GetReflection(), (uint32_t)i,
|
||||
global.srvs[i].format);
|
||||
global.srvs[slot].format);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1654,20 +1659,20 @@ void D3D11DebugManager::CreateShaderGlobalState(ShaderDebug::GlobalState &global
|
||||
{
|
||||
// I know this isn't what the docs say, but as best as I can tell
|
||||
// this is how it's used.
|
||||
global.srvs[i].firstElement = sdesc.Buffer.FirstElement;
|
||||
global.srvs[i].numElements = sdesc.Buffer.NumElements;
|
||||
global.srvs[slot].firstElement = sdesc.Buffer.FirstElement;
|
||||
global.srvs[slot].numElements = sdesc.Buffer.NumElements;
|
||||
}
|
||||
else if(sdesc.ViewDimension == D3D11_SRV_DIMENSION_BUFFEREX)
|
||||
{
|
||||
global.srvs[i].firstElement = sdesc.BufferEx.FirstElement;
|
||||
global.srvs[i].numElements = sdesc.BufferEx.NumElements;
|
||||
global.srvs[slot].firstElement = sdesc.BufferEx.FirstElement;
|
||||
global.srvs[slot].numElements = sdesc.BufferEx.NumElements;
|
||||
}
|
||||
|
||||
if(res)
|
||||
{
|
||||
if(WrappedID3D11Buffer::IsAlloc(res))
|
||||
{
|
||||
GetBufferData((ID3D11Buffer *)res, 0, 0, global.srvs[i].data);
|
||||
GetBufferData((ID3D11Buffer *)res, 0, 0, global.srvs[slot].data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -453,8 +453,10 @@ bool D3D12DebugAPIWrapper::CalculateSampleGather(
|
||||
|
||||
rdcstr sampleProgram;
|
||||
|
||||
UINT texSlot = resourceData.slot;
|
||||
UINT sampSlot = samplerData.slot;
|
||||
rdcstr strResourceBinding = StringFormat::Fmt("t%u, space%u", resourceData.binding.shaderRegister,
|
||||
resourceData.binding.registerSpace);
|
||||
rdcstr strSamplerBinding = StringFormat::Fmt("s%u, space%u", samplerData.binding.shaderRegister,
|
||||
samplerData.binding.registerSpace);
|
||||
|
||||
if(opcode == OPCODE_SAMPLE || opcode == OPCODE_SAMPLE_B || opcode == OPCODE_SAMPLE_D)
|
||||
{
|
||||
@@ -476,8 +478,9 @@ bool D3D12DebugAPIWrapper::CalculateSampleGather(
|
||||
ddy = StringFormat::Fmt(formats[offsetDim + texdimOffs - 1][ddyType], ddyCalc.value.i.x,
|
||||
ddyCalc.value.i.y, ddyCalc.value.i.z, ddyCalc.value.i.w);
|
||||
|
||||
sampleProgram = StringFormat::Fmt("%s : register(t%u);\n%s : register(s%u);\n\n",
|
||||
textureDecl.c_str(), texSlot, samplerDecl.c_str(), sampSlot);
|
||||
sampleProgram = StringFormat::Fmt("%s : register(%s);\n%s : register(%s);\n\n",
|
||||
textureDecl.c_str(), strResourceBinding.c_str(),
|
||||
samplerDecl.c_str(), strSamplerBinding.c_str());
|
||||
sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn ";
|
||||
sampleProgram += StringFormat::Fmt("t.SampleGrad(s, %s, %s, %s %s)%s;\n", texcoords.c_str(),
|
||||
ddx.c_str(), ddy.c_str(), offsets.c_str(), strSwizzle.c_str());
|
||||
@@ -486,8 +489,9 @@ bool D3D12DebugAPIWrapper::CalculateSampleGather(
|
||||
else if(opcode == OPCODE_SAMPLE_L)
|
||||
{
|
||||
// lod selection
|
||||
sampleProgram = StringFormat::Fmt("%s : register(t%u);\n%s : register(s%u);\n\n",
|
||||
textureDecl.c_str(), texSlot, samplerDecl.c_str(), sampSlot);
|
||||
sampleProgram = StringFormat::Fmt("%s : register(%s);\n%s : register(%s);\n\n",
|
||||
textureDecl.c_str(), strResourceBinding.c_str(),
|
||||
samplerDecl.c_str(), strSamplerBinding.c_str());
|
||||
sampleProgram += funcRet + " main() : SV_Target0\n{\nreturn ";
|
||||
sampleProgram += StringFormat::Fmt("t.SampleLevel(s, %s, %.10f %s)%s;\n", texcoords.c_str(),
|
||||
lodOrCompareValue, offsets.c_str(), strSwizzle.c_str());
|
||||
@@ -522,8 +526,9 @@ bool D3D12DebugAPIWrapper::CalculateSampleGather(
|
||||
if(opcode == OPCODE_SAMPLE_C)
|
||||
{
|
||||
// comparison value
|
||||
sampleProgram = StringFormat::Fmt("%s : register(t%u);\n%s : register(s%u);\n\n",
|
||||
textureDecl.c_str(), texSlot, samplerDecl.c_str(), sampSlot);
|
||||
sampleProgram = StringFormat::Fmt("%s : register(%s);\n%s : register(%s);\n\n",
|
||||
textureDecl.c_str(), strResourceBinding.c_str(),
|
||||
samplerDecl.c_str(), strSamplerBinding.c_str());
|
||||
sampleProgram +=
|
||||
funcRet + " main(float4 pos : SV_Position, " + uvdecl + ") : SV_Target0\n{\n";
|
||||
sampleProgram += StringFormat::Fmt("t.SampleCmpLevelZero(s, uv, %.10f %s).xxxx;\n",
|
||||
@@ -532,8 +537,9 @@ bool D3D12DebugAPIWrapper::CalculateSampleGather(
|
||||
}
|
||||
else if(opcode == OPCODE_LOD)
|
||||
{
|
||||
sampleProgram = StringFormat::Fmt("%s : register(t%u);\n%s : register(s%u);\n\n",
|
||||
textureDecl.c_str(), texSlot, samplerDecl.c_str(), sampSlot);
|
||||
sampleProgram = StringFormat::Fmt("%s : register(%s);\n%s : register(%s);\n\n",
|
||||
textureDecl.c_str(), strResourceBinding.c_str(),
|
||||
samplerDecl.c_str(), strSamplerBinding.c_str());
|
||||
sampleProgram +=
|
||||
funcRet + " main(float4 pos : SV_Position, " + uvdecl + ") : SV_Target0\n{\n";
|
||||
sampleProgram +=
|
||||
@@ -546,8 +552,9 @@ bool D3D12DebugAPIWrapper::CalculateSampleGather(
|
||||
else if(opcode == OPCODE_SAMPLE_C_LZ)
|
||||
{
|
||||
// comparison value
|
||||
sampleProgram = StringFormat::Fmt("%s : register(t%u);\n%s : register(s%u);\n\n",
|
||||
textureDecl.c_str(), texSlot, samplerDecl.c_str(), sampSlot);
|
||||
sampleProgram = StringFormat::Fmt("%s : register(%s);\n%s : register(%s);\n\n",
|
||||
textureDecl.c_str(), strResourceBinding.c_str(),
|
||||
samplerDecl.c_str(), strSamplerBinding.c_str());
|
||||
sampleProgram += funcRet + " main() : SV_Target0\n{\n";
|
||||
sampleProgram +=
|
||||
StringFormat::Fmt("return t.SampleCmpLevelZero(s, %s, %.10f %s)%s;\n", texcoords.c_str(),
|
||||
@@ -556,14 +563,16 @@ bool D3D12DebugAPIWrapper::CalculateSampleGather(
|
||||
}
|
||||
else if(opcode == OPCODE_LD)
|
||||
{
|
||||
sampleProgram = StringFormat::Fmt("%s : register(t%u);\n\n", textureDecl.c_str(), texSlot);
|
||||
sampleProgram =
|
||||
StringFormat::Fmt("%s : register(%s);\n\n", textureDecl.c_str(), strResourceBinding.c_str());
|
||||
sampleProgram += funcRet + " main() : SV_Target0\n{\n";
|
||||
sampleProgram += "return t.Load(" + texcoords + offsets + ")" + strSwizzle + ";";
|
||||
sampleProgram += "\n}\n";
|
||||
}
|
||||
else if(opcode == OPCODE_LD_MS)
|
||||
{
|
||||
sampleProgram = StringFormat::Fmt("%s : register(t%u);\n\n", textureDecl.c_str(), texSlot);
|
||||
sampleProgram =
|
||||
StringFormat::Fmt("%s : register(%s);\n\n", textureDecl.c_str(), strResourceBinding.c_str());
|
||||
sampleProgram += funcRet + " main() : SV_Target0\n{\n";
|
||||
sampleProgram += StringFormat::Fmt("t.Load(%s, int(%d) %s)%s;\n", texcoords.c_str(),
|
||||
multisampleIndex, offsets.c_str(), strSwizzle.c_str());
|
||||
@@ -571,8 +580,9 @@ bool D3D12DebugAPIWrapper::CalculateSampleGather(
|
||||
}
|
||||
else if(opcode == OPCODE_GATHER4 || opcode == OPCODE_GATHER4_PO)
|
||||
{
|
||||
sampleProgram = StringFormat::Fmt("%s : register(t%u);\n%s : register(s%u);\n\n",
|
||||
textureDecl.c_str(), texSlot, samplerDecl.c_str(), sampSlot);
|
||||
sampleProgram = StringFormat::Fmt("%s : register(%s);\n%s : register(%s);\n\n",
|
||||
textureDecl.c_str(), strResourceBinding.c_str(),
|
||||
samplerDecl.c_str(), strSamplerBinding.c_str());
|
||||
sampleProgram += funcRet + " main() : SV_Target0\n{\n";
|
||||
sampleProgram += StringFormat::Fmt("return t.Gather%s(s, %s %s)%s;\n", strGatherChannel.c_str(),
|
||||
texcoords.c_str(), offsets.c_str(), strSwizzle.c_str());
|
||||
@@ -581,8 +591,9 @@ bool D3D12DebugAPIWrapper::CalculateSampleGather(
|
||||
else if(opcode == OPCODE_GATHER4_C || opcode == OPCODE_GATHER4_PO_C)
|
||||
{
|
||||
// comparison value
|
||||
sampleProgram = StringFormat::Fmt("%s : register(t%u);\n%s : register(s%u);\n\n",
|
||||
textureDecl.c_str(), texSlot, samplerDecl.c_str(), sampSlot);
|
||||
sampleProgram = StringFormat::Fmt("%s : register(%s);\n%s : register(%s);\n\n",
|
||||
textureDecl.c_str(), strResourceBinding.c_str(),
|
||||
samplerDecl.c_str(), strSamplerBinding.c_str());
|
||||
sampleProgram += funcRet + " main() : SV_Target0\n{\n";
|
||||
sampleProgram += StringFormat::Fmt("return t.GatherCmp%s(s, %s, %.10f %s)%s;\n",
|
||||
strGatherChannel.c_str(), texcoords.c_str(),
|
||||
@@ -590,17 +601,19 @@ bool D3D12DebugAPIWrapper::CalculateSampleGather(
|
||||
sampleProgram += "}\n";
|
||||
}
|
||||
|
||||
// Create VS/PS to fetch the sample
|
||||
// Create VS/PS to fetch the sample. Because the program being debugged might be using SM 5.1, we
|
||||
// need to do that too, to support reusing the existing root signature that may use a non-zero
|
||||
// register space for the resource or sampler.
|
||||
ID3DBlob *vsBlob = NULL;
|
||||
ID3DBlob *psBlob = NULL;
|
||||
UINT flags = D3DCOMPILE_DEBUG | D3DCOMPILE_WARNINGS_ARE_ERRORS;
|
||||
if(m_pDevice->GetShaderCache()->GetShaderBlob(vsProgram.c_str(), "main", flags, "vs_5_0",
|
||||
if(m_pDevice->GetShaderCache()->GetShaderBlob(vsProgram.c_str(), "main", flags, "vs_5_1",
|
||||
&vsBlob) != "")
|
||||
{
|
||||
RDCERR("Failed to create shader to extract inputs");
|
||||
return false;
|
||||
}
|
||||
if(m_pDevice->GetShaderCache()->GetShaderBlob(sampleProgram.c_str(), "main", flags, "ps_5_0",
|
||||
if(m_pDevice->GetShaderCache()->GetShaderBlob(sampleProgram.c_str(), "main", flags, "ps_5_1",
|
||||
&psBlob) != "")
|
||||
{
|
||||
RDCERR("Failed to create shader to extract inputs");
|
||||
@@ -769,34 +782,36 @@ void D3D12DebugManager::CreateShaderGlobalState(ShaderDebug::GlobalState &global
|
||||
if(param.ParameterType == D3D12_ROOT_PARAMETER_TYPE_SRV && element.type == eRootSRV)
|
||||
{
|
||||
UINT shaderReg = param.Descriptor.ShaderRegister;
|
||||
ShaderDebug::BindingSlot slot(shaderReg, param.Descriptor.RegisterSpace);
|
||||
ID3D12Resource *pResource = rm->GetCurrentAs<ID3D12Resource>(element.id);
|
||||
D3D12_RESOURCE_DESC resDesc = pResource->GetDesc();
|
||||
|
||||
// TODO: Root buffers can be 32-bit UINT/SINT/FLOAT. Using UINT for now, but the
|
||||
// resource desc format or the DXBC reflection info might be more correct.
|
||||
ShaderDebug::FillViewFmt(DXGI_FORMAT_R32_UINT, global.srvs[shaderReg].format);
|
||||
global.srvs[shaderReg].firstElement = (uint32_t)(element.offset / sizeof(uint32_t));
|
||||
global.srvs[shaderReg].numElements =
|
||||
ShaderDebug::FillViewFmt(DXGI_FORMAT_R32_UINT, global.srvs[slot].format);
|
||||
global.srvs[slot].firstElement = (uint32_t)(element.offset / sizeof(uint32_t));
|
||||
global.srvs[slot].numElements =
|
||||
(uint32_t)((resDesc.Width - element.offset) / sizeof(uint32_t));
|
||||
|
||||
if(resDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
|
||||
GetBufferData(pResource, 0, 0, global.srvs[shaderReg].data);
|
||||
GetBufferData(pResource, 0, 0, global.srvs[slot].data);
|
||||
}
|
||||
else if(param.ParameterType == D3D12_ROOT_PARAMETER_TYPE_UAV && element.type == eRootUAV)
|
||||
{
|
||||
UINT shaderReg = param.Descriptor.ShaderRegister;
|
||||
ShaderDebug::BindingSlot slot(shaderReg, param.Descriptor.RegisterSpace);
|
||||
ID3D12Resource *pResource = rm->GetCurrentAs<ID3D12Resource>(element.id);
|
||||
D3D12_RESOURCE_DESC resDesc = pResource->GetDesc();
|
||||
|
||||
// TODO: Root buffers can be 32-bit UINT/SINT/FLOAT. Using UINT for now, but the
|
||||
// resource desc format or the DXBC reflection info might be more correct.
|
||||
ShaderDebug::FillViewFmt(DXGI_FORMAT_R32_UINT, global.uavs[shaderReg].format);
|
||||
global.uavs[shaderReg].firstElement = (uint32_t)(element.offset / sizeof(uint32_t));
|
||||
global.uavs[shaderReg].numElements =
|
||||
ShaderDebug::FillViewFmt(DXGI_FORMAT_R32_UINT, global.uavs[slot].format);
|
||||
global.uavs[slot].firstElement = (uint32_t)(element.offset / sizeof(uint32_t));
|
||||
global.uavs[slot].numElements =
|
||||
(uint32_t)((resDesc.Width - element.offset) / sizeof(uint32_t));
|
||||
|
||||
if(resDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
|
||||
GetBufferData(pResource, 0, 0, global.uavs[shaderReg].data);
|
||||
GetBufferData(pResource, 0, 0, global.uavs[slot].data);
|
||||
}
|
||||
else if(param.ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE &&
|
||||
element.type == eRootTable)
|
||||
@@ -838,34 +853,36 @@ void D3D12DebugManager::CreateShaderGlobalState(ShaderDebug::GlobalState &global
|
||||
{
|
||||
if(desc)
|
||||
{
|
||||
ShaderDebug::BindingSlot slot(shaderReg, range.RegisterSpace);
|
||||
|
||||
ResourceId srvId = desc->GetResResourceId();
|
||||
ID3D12Resource *pResource = rm->GetCurrentAs<ID3D12Resource>(srvId);
|
||||
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC srvDesc = desc->GetSRV();
|
||||
if(srvDesc.Format != DXGI_FORMAT_UNKNOWN)
|
||||
{
|
||||
ShaderDebug::FillViewFmt(srvDesc.Format, global.srvs[shaderReg].format);
|
||||
ShaderDebug::FillViewFmt(srvDesc.Format, global.srvs[slot].format);
|
||||
}
|
||||
else
|
||||
{
|
||||
D3D12_RESOURCE_DESC resDesc = pResource->GetDesc();
|
||||
if(resDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
|
||||
{
|
||||
global.srvs[shaderReg].format.stride = srvDesc.Buffer.StructureByteStride;
|
||||
global.srvs[slot].format.stride = srvDesc.Buffer.StructureByteStride;
|
||||
|
||||
// If we didn't get a type from the SRV description, try to pull it from the
|
||||
// shader reflection info
|
||||
ShaderDebug::LookupSRVFormatFromShaderReflection(
|
||||
*dxbc->GetReflection(), (uint32_t)shaderReg, global.srvs[shaderReg].format);
|
||||
*dxbc->GetReflection(), (uint32_t)shaderReg, global.srvs[slot].format);
|
||||
}
|
||||
}
|
||||
|
||||
if(srvDesc.ViewDimension == D3D12_SRV_DIMENSION_BUFFER)
|
||||
{
|
||||
global.srvs[shaderReg].firstElement = (uint32_t)srvDesc.Buffer.FirstElement;
|
||||
global.srvs[shaderReg].numElements = srvDesc.Buffer.NumElements;
|
||||
global.srvs[slot].firstElement = (uint32_t)srvDesc.Buffer.FirstElement;
|
||||
global.srvs[slot].numElements = srvDesc.Buffer.NumElements;
|
||||
|
||||
GetBufferData(pResource, 0, 0, global.srvs[shaderReg].data);
|
||||
GetBufferData(pResource, 0, 0, global.srvs[slot].data);
|
||||
}
|
||||
// Textures are sampled via a pixel shader, so there's no need to copy their data
|
||||
|
||||
@@ -879,6 +896,8 @@ void D3D12DebugManager::CreateShaderGlobalState(ShaderDebug::GlobalState &global
|
||||
{
|
||||
if(desc)
|
||||
{
|
||||
ShaderDebug::BindingSlot slot(shaderReg, range.RegisterSpace);
|
||||
|
||||
ResourceId uavId = desc->GetResResourceId();
|
||||
ID3D12Resource *pResource = rm->GetCurrentAs<ID3D12Resource>(uavId);
|
||||
|
||||
@@ -887,14 +906,14 @@ void D3D12DebugManager::CreateShaderGlobalState(ShaderDebug::GlobalState &global
|
||||
D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = desc->GetUAV();
|
||||
if(uavDesc.Format != DXGI_FORMAT_UNKNOWN)
|
||||
{
|
||||
ShaderDebug::FillViewFmt(uavDesc.Format, global.uavs[shaderReg].format);
|
||||
ShaderDebug::FillViewFmt(uavDesc.Format, global.uavs[slot].format);
|
||||
}
|
||||
else
|
||||
{
|
||||
D3D12_RESOURCE_DESC resDesc = pResource->GetDesc();
|
||||
if(resDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
|
||||
{
|
||||
global.uavs[shaderReg].format.stride = uavDesc.Buffer.StructureByteStride;
|
||||
global.uavs[slot].format.stride = uavDesc.Buffer.StructureByteStride;
|
||||
|
||||
// TODO: Try looking up UAV from shader reflection info?
|
||||
}
|
||||
@@ -902,15 +921,15 @@ void D3D12DebugManager::CreateShaderGlobalState(ShaderDebug::GlobalState &global
|
||||
|
||||
if(uavDesc.ViewDimension == D3D12_UAV_DIMENSION_BUFFER)
|
||||
{
|
||||
global.uavs[shaderReg].firstElement = (uint32_t)uavDesc.Buffer.FirstElement;
|
||||
global.uavs[shaderReg].numElements = uavDesc.Buffer.NumElements;
|
||||
global.uavs[slot].firstElement = (uint32_t)uavDesc.Buffer.FirstElement;
|
||||
global.uavs[slot].numElements = uavDesc.Buffer.NumElements;
|
||||
|
||||
GetBufferData(pResource, 0, 0, global.uavs[shaderReg].data);
|
||||
GetBufferData(pResource, 0, 0, global.uavs[slot].data);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Handle texture resources in UAVs - need to copy/map to fetch the data
|
||||
global.uavs[shaderReg].tex = true;
|
||||
global.uavs[slot].tex = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2673,14 +2673,16 @@ State State::GetNext(GlobalState &global, DebugAPIWrapper *apiWrapper, State qua
|
||||
|
||||
case OPCODE_IMM_ATOMIC_ALLOC:
|
||||
{
|
||||
uint32_t count = global.uavs[srcOpers[0].value.u.x].hiddenCounter++;
|
||||
ShaderDebug::BindingSlot slot(srcOpers[0].value.u.x, 0);
|
||||
uint32_t count = global.uavs[slot].hiddenCounter++;
|
||||
s.SetDst(op.operands[0], op, ShaderVariable("", count, count, count, count));
|
||||
break;
|
||||
}
|
||||
|
||||
case OPCODE_IMM_ATOMIC_CONSUME:
|
||||
{
|
||||
uint32_t count = --global.uavs[srcOpers[0].value.u.x].hiddenCounter;
|
||||
ShaderDebug::BindingSlot slot(srcOpers[0].value.u.x, 0);
|
||||
uint32_t count = --global.uavs[slot].hiddenCounter;
|
||||
s.SetDst(op.operands[0], op, ShaderVariable("", count, count, count, count));
|
||||
break;
|
||||
}
|
||||
@@ -2794,9 +2796,10 @@ State State::GetNext(GlobalState &global, DebugAPIWrapper *apiWrapper, State qua
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = global.uavs[resIndex].firstElement;
|
||||
numElems = global.uavs[resIndex].numElements;
|
||||
data = &global.uavs[resIndex].data[0];
|
||||
ShaderDebug::BindingSlot slot(resIndex, 0);
|
||||
offset = global.uavs[slot].firstElement;
|
||||
numElems = global.uavs[slot].numElements;
|
||||
data = &global.uavs[slot].data[0];
|
||||
|
||||
for(size_t i = 0; i < s.program->GetNumDeclarations(); i++)
|
||||
{
|
||||
@@ -3019,9 +3022,10 @@ State State::GetNext(GlobalState &global, DebugAPIWrapper *apiWrapper, State qua
|
||||
|
||||
RDCASSERT(stride != 0);
|
||||
|
||||
uint32_t offset = srv ? global.srvs[resIndex].firstElement : global.uavs[resIndex].firstElement;
|
||||
uint32_t numElems = srv ? global.srvs[resIndex].numElements : global.uavs[resIndex].numElements;
|
||||
GlobalState::ViewFmt fmt = srv ? global.srvs[resIndex].format : global.uavs[resIndex].format;
|
||||
ShaderDebug::BindingSlot slot(resIndex, 0);
|
||||
uint32_t offset = srv ? global.srvs[slot].firstElement : global.uavs[slot].firstElement;
|
||||
uint32_t numElems = srv ? global.srvs[slot].numElements : global.uavs[slot].numElements;
|
||||
GlobalState::ViewFmt fmt = srv ? global.srvs[slot].format : global.uavs[slot].format;
|
||||
|
||||
// indexing for raw views is in bytes, but firstElement/numElements is in format-sized
|
||||
// units. Multiply up by stride
|
||||
@@ -3031,10 +3035,10 @@ State State::GetNext(GlobalState &global, DebugAPIWrapper *apiWrapper, State qua
|
||||
numElems *= RDCMIN(4, fmt.byteWidth);
|
||||
}
|
||||
|
||||
byte *data = srv ? &global.srvs[resIndex].data[0] : &global.uavs[resIndex].data[0];
|
||||
bool texData = srv ? false : global.uavs[resIndex].tex;
|
||||
uint32_t rowPitch = srv ? 0 : global.uavs[resIndex].rowPitch;
|
||||
uint32_t depthPitch = srv ? 0 : global.uavs[resIndex].depthPitch;
|
||||
byte *data = srv ? &global.srvs[slot].data[0] : &global.uavs[slot].data[0];
|
||||
bool texData = srv ? false : global.uavs[slot].tex;
|
||||
uint32_t rowPitch = srv ? 0 : global.uavs[slot].rowPitch;
|
||||
uint32_t depthPitch = srv ? 0 : global.uavs[slot].depthPitch;
|
||||
|
||||
if(gsm)
|
||||
{
|
||||
@@ -3070,7 +3074,7 @@ State State::GetNext(GlobalState &global, DebugAPIWrapper *apiWrapper, State qua
|
||||
}
|
||||
|
||||
if(!data || (!texData && elemIdx >= numElems) ||
|
||||
(texData && texOffset >= global.uavs[resIndex].data.size()))
|
||||
(texData && texOffset >= global.uavs[slot].data.size()))
|
||||
{
|
||||
if(load)
|
||||
s.SetDst(op.operands[0], op, ShaderVariable("", 0U, 0U, 0U, 0U));
|
||||
@@ -3560,6 +3564,10 @@ State State::GetNext(GlobalState &global, DebugAPIWrapper *apiWrapper, State qua
|
||||
DXBC::ResourceRetType resourceRetType = DXBC::RETURN_TYPE_UNKNOWN;
|
||||
int sampleCount = 0;
|
||||
|
||||
// Default assumptions for bindings
|
||||
ShaderDebug::BindingSlot resourceBinding((uint32_t)op.operands[2].indices[0].index, 0);
|
||||
ShaderDebug::BindingSlot samplerBinding(0, 0);
|
||||
|
||||
for(size_t i = 0; i < program->GetNumDeclarations(); i++)
|
||||
{
|
||||
const Declaration &decl = program->GetDeclaration(i);
|
||||
@@ -3568,6 +3576,7 @@ State State::GetNext(GlobalState &global, DebugAPIWrapper *apiWrapper, State qua
|
||||
decl.operand.indices == op.operands[3].indices)
|
||||
{
|
||||
samplerMode = decl.samplerMode;
|
||||
samplerBinding.shaderRegister = (uint32_t)op.operands[3].indices[0].index;
|
||||
}
|
||||
if(decl.dim == RESOURCE_DIMENSION_BUFFER && op.operation == OPCODE_LD &&
|
||||
decl.declaration == OPCODE_DCL_RESOURCE && decl.operand.type == TYPE_RESOURCE &&
|
||||
@@ -3575,13 +3584,13 @@ State State::GetNext(GlobalState &global, DebugAPIWrapper *apiWrapper, State qua
|
||||
{
|
||||
resourceDim = decl.dim;
|
||||
|
||||
uint32_t resIndex = (uint32_t)decl.operand.indices[0].index;
|
||||
resourceBinding.shaderRegister = (uint32_t)decl.operand.indices[0].index;
|
||||
|
||||
const byte *data = &global.srvs[resIndex].data[0];
|
||||
uint32_t offset = global.srvs[resIndex].firstElement;
|
||||
uint32_t numElems = global.srvs[resIndex].numElements;
|
||||
const byte *data = &global.srvs[resourceBinding].data[0];
|
||||
uint32_t offset = global.srvs[resourceBinding].firstElement;
|
||||
uint32_t numElems = global.srvs[resourceBinding].numElements;
|
||||
|
||||
GlobalState::ViewFmt fmt = global.srvs[resIndex].format;
|
||||
GlobalState::ViewFmt fmt = global.srvs[resourceBinding].format;
|
||||
|
||||
data += fmt.Stride() * offset;
|
||||
|
||||
@@ -3623,6 +3632,8 @@ State State::GetNext(GlobalState &global, DebugAPIWrapper *apiWrapper, State qua
|
||||
resourceRetType = decl.resType[0];
|
||||
sampleCount = decl.sampleCount;
|
||||
|
||||
resourceBinding.shaderRegister = (uint32_t)decl.operand.indices[0].index;
|
||||
|
||||
// doesn't seem like these are ever less than four components, even if the texture is
|
||||
// declared <float3> for example.
|
||||
// shouldn't matter though is it just comes out in the wash.
|
||||
@@ -3675,16 +3686,6 @@ State State::GetNext(GlobalState &global, DebugAPIWrapper *apiWrapper, State qua
|
||||
ddyCalc = srcOpers[4];
|
||||
}
|
||||
|
||||
UINT texSlot = (UINT)op.operands[2].indices[0].index;
|
||||
UINT samplerSlot = 0;
|
||||
|
||||
for(size_t i = 0; i < op.operands.size(); i++)
|
||||
{
|
||||
const Operand &operand = op.operands[i];
|
||||
if(operand.type == OperandType::TYPE_SAMPLER)
|
||||
samplerSlot = (UINT)operand.indices[0].index;
|
||||
}
|
||||
|
||||
int multisampleIndex = srcOpers[2].value.i.x;
|
||||
float lodOrCompareValue = srcOpers[3].value.f.x;
|
||||
if(op.operation == OPCODE_GATHER4_PO_C)
|
||||
@@ -3709,20 +3710,17 @@ State State::GetNext(GlobalState &global, DebugAPIWrapper *apiWrapper, State qua
|
||||
// for bias instruction we can't do a SampleGradBias, so add the bias into the sampler state.
|
||||
float samplerBias = 0.0f;
|
||||
if(op.operation == OPCODE_SAMPLE_B)
|
||||
{
|
||||
samplerSlot = (UINT)srcOpers[2].value.u.x;
|
||||
samplerBias = srcOpers[3].value.f.x;
|
||||
}
|
||||
|
||||
SampleGatherResourceData resourceData;
|
||||
resourceData.dim = resourceDim;
|
||||
resourceData.retType = resourceRetType;
|
||||
resourceData.sampleCount = sampleCount;
|
||||
resourceData.slot = texSlot;
|
||||
resourceData.binding = resourceBinding;
|
||||
|
||||
SampleGatherSamplerData samplerData;
|
||||
samplerData.mode = samplerMode;
|
||||
samplerData.slot = samplerSlot;
|
||||
samplerData.binding = samplerBinding;
|
||||
samplerData.bias = samplerBias;
|
||||
|
||||
ShaderVariable lookupResult("tex", 0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
@@ -40,22 +40,27 @@ enum DXGI_FORMAT;
|
||||
|
||||
namespace ShaderDebug
|
||||
{
|
||||
struct BindingSlot
|
||||
{
|
||||
BindingSlot() : shaderRegister(UINT32_MAX), registerSpace(UINT32_MAX) {}
|
||||
BindingSlot(uint32_t shaderReg, uint32_t regSpace)
|
||||
: shaderRegister(shaderReg), registerSpace(regSpace)
|
||||
{
|
||||
}
|
||||
bool operator<(const BindingSlot &o) const
|
||||
{
|
||||
if(registerSpace != o.registerSpace)
|
||||
return registerSpace < o.registerSpace;
|
||||
return shaderRegister < o.shaderRegister;
|
||||
}
|
||||
uint32_t shaderRegister;
|
||||
uint32_t registerSpace;
|
||||
};
|
||||
|
||||
struct GlobalState
|
||||
{
|
||||
public:
|
||||
GlobalState()
|
||||
{
|
||||
for(int i = 0; i < 8; i++)
|
||||
{
|
||||
uavs[i].firstElement = uavs[i].numElements = uavs[i].hiddenCounter = 0;
|
||||
uavs[i].rowPitch = uavs[i].depthPitch = 0;
|
||||
uavs[i].tex = false;
|
||||
}
|
||||
|
||||
for(int i = 0; i < 128; i++)
|
||||
srvs[i].firstElement = srvs[i].numElements = 0;
|
||||
}
|
||||
|
||||
GlobalState() {}
|
||||
void PopulateGroupshared(const DXBCBytecode::Program *pBytecode);
|
||||
|
||||
struct ViewFmt
|
||||
@@ -77,8 +82,13 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
struct
|
||||
struct UAVData
|
||||
{
|
||||
UAVData()
|
||||
: firstElement(0), numElements(0), tex(false), rowPitch(0), depthPitch(0), hiddenCounter(0)
|
||||
{
|
||||
}
|
||||
|
||||
bytebuf data;
|
||||
uint32_t firstElement;
|
||||
uint32_t numElements;
|
||||
@@ -89,16 +99,19 @@ public:
|
||||
ViewFmt format;
|
||||
|
||||
uint32_t hiddenCounter;
|
||||
} uavs[64];
|
||||
};
|
||||
std::map<BindingSlot, UAVData> uavs;
|
||||
|
||||
struct
|
||||
struct SRVData
|
||||
{
|
||||
SRVData() : firstElement(0), numElements(0) {}
|
||||
bytebuf data;
|
||||
uint32_t firstElement;
|
||||
uint32_t numElements;
|
||||
|
||||
ViewFmt format;
|
||||
} srvs[128];
|
||||
};
|
||||
std::map<BindingSlot, SRVData> srvs;
|
||||
|
||||
struct groupsharedMem
|
||||
{
|
||||
@@ -203,14 +216,14 @@ struct SampleGatherResourceData
|
||||
DXBCBytecode::ResourceDimension dim;
|
||||
DXBC::ResourceRetType retType;
|
||||
int sampleCount;
|
||||
UINT slot;
|
||||
ShaderDebug::BindingSlot binding;
|
||||
};
|
||||
|
||||
struct SampleGatherSamplerData
|
||||
{
|
||||
DXBCBytecode::SamplerMode mode;
|
||||
UINT slot;
|
||||
float bias;
|
||||
ShaderDebug::BindingSlot binding;
|
||||
};
|
||||
|
||||
enum class GatherChannel : uint8_t
|
||||
|
||||
Reference in New Issue
Block a user