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:
Steve Karolewics
2020-01-17 19:53:23 +00:00
committed by Baldur Karlsson
parent 6cd2d18d9e
commit 654acb67f5
4 changed files with 161 additions and 126 deletions
+38 -33
View File
@@ -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);
}
}
+60 -41
View File
@@ -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;
}
}
}
+31 -33
View File
@@ -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);
+32 -19
View File
@@ -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