mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-06 01:50:38 +00:00
DXIL Debugger extended support for GPU Sampling instructions
DXOp::Sample DXOp::SampleBias DXOp::SampleLevel DXOp::SampleGrad DXOp::SampleCmp DXOp::SampleCmpBias DXOp::SampleCmpLevel DXOp::SampleCmpGrad DXOp::SampleCmpLevelZero DXOp::TextureGather DXOp::TextureGatherCmp
This commit is contained in:
@@ -397,13 +397,17 @@ cbuffer DebugSampleOperation REG(b0)
|
||||
#define DEBUG_SAMPLE_TEX_SAMPLE_GRAD 103
|
||||
#define DEBUG_SAMPLE_TEX_SAMPLE_CMP 104
|
||||
#define DEBUG_SAMPLE_TEX_SAMPLE_CMP_LEVEL_ZERO 105
|
||||
#define DEBUG_SAMPLE_TEX_GATHER4 106
|
||||
#define DEBUG_SAMPLE_TEX_GATHER4_CMP 107
|
||||
#define DEBUG_SAMPLE_TEX_GATHER4_PO 108
|
||||
#define DEBUG_SAMPLE_TEX_GATHER4_PO_CMP 109
|
||||
#define DEBUG_SAMPLE_TEX_LOD 110
|
||||
#define DEBUG_SAMPLE_TEX_LOAD 111
|
||||
#define DEBUG_SAMPLE_TEX_LOAD_MS 112
|
||||
#define DEBUG_SAMPLE_TEX_SAMPLE_CMP_LEVEL 106 // SM 6.7
|
||||
#define DEBUG_SAMPLE_TEX_SAMPLE_CMP_BIAS 107 // SM 6.8
|
||||
#define DEBUG_SAMPLE_TEX_SAMPLE_CMP_GRAD 108 // SM 6.8
|
||||
|
||||
#define DEBUG_SAMPLE_TEX_GATHER4 109
|
||||
#define DEBUG_SAMPLE_TEX_GATHER4_CMP 110
|
||||
#define DEBUG_SAMPLE_TEX_GATHER4_PO 111
|
||||
#define DEBUG_SAMPLE_TEX_GATHER4_PO_CMP 112
|
||||
#define DEBUG_SAMPLE_TEX_LOD 113
|
||||
#define DEBUG_SAMPLE_TEX_LOAD 114
|
||||
#define DEBUG_SAMPLE_TEX_LOAD_MS 115
|
||||
|
||||
#define DEBUG_SAMPLE_TEX1D 1
|
||||
#define DEBUG_SAMPLE_TEX2D 2
|
||||
|
||||
@@ -269,7 +269,7 @@ float4 DoFloatOpcode(float4 uv)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(opcode == DEBUG_SAMPLE_TEX_SAMPLE_CMP)
|
||||
else if(opcode == DEBUG_SAMPLE_TEX_SAMPLE_CMP || opcode == DEBUG_SAMPLE_TEX_SAMPLE_CMP_BIAS)
|
||||
{
|
||||
switch(debugSampleTexDim)
|
||||
{
|
||||
@@ -660,6 +660,102 @@ float4 DoFloatOpcode(float4 uv)
|
||||
}
|
||||
}
|
||||
}
|
||||
#if __SHADER_TARGET_MAJOR >= 6
|
||||
#if __SHADER_TARGET_MINOR >= 7
|
||||
else if(opcode == DEBUG_SAMPLE_TEX_SAMPLE_CMP_LEVEL) // SM6.7
|
||||
{
|
||||
switch(debugSampleTexDim)
|
||||
{
|
||||
default:
|
||||
case DEBUG_SAMPLE_TEX1D:
|
||||
{
|
||||
switch(debugSampleRetType)
|
||||
{
|
||||
case DEBUG_SAMPLE_UNORM:
|
||||
return t1D_unorm.SampleCmpLevel(sc, uv.xy, compare, lod, offsets.x);
|
||||
case DEBUG_SAMPLE_SNORM:
|
||||
return t1D_snorm.SampleCmpLevel(sc, uv.xy, compare, lod, offsets.x);
|
||||
default: return t1D_float.SampleCmpLevel(sc, uv.xy, compare, lod, offsets.x);
|
||||
}
|
||||
}
|
||||
case DEBUG_SAMPLE_TEX2D:
|
||||
{
|
||||
switch(debugSampleRetType)
|
||||
{
|
||||
case DEBUG_SAMPLE_UNORM:
|
||||
return t2D_unorm.SampleCmpLevel(sc, uv.xyz, compare, lod, offsets.xy);
|
||||
case DEBUG_SAMPLE_SNORM:
|
||||
return t2D_snorm.SampleCmpLevel(sc, uv.xyz, compare, lod, offsets.xy);
|
||||
default: return t2D_float.SampleCmpLevel(sc, uv.xyz, compare, lod, offsets.xy);
|
||||
}
|
||||
}
|
||||
case DEBUG_SAMPLE_TEXCUBE:
|
||||
{
|
||||
switch(debugSampleRetType)
|
||||
{
|
||||
case DEBUG_SAMPLE_UNORM: return tCube_unorm.SampleCmpLevel(sc, uv, compare, lod);
|
||||
case DEBUG_SAMPLE_SNORM: return tCube_snorm.SampleCmpLevel(sc, uv, compare, lod);
|
||||
default: return tCube_float.SampleCmpLevel(sc, uv, compare, lod);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // #if __SHADER_TARGET_MINOR >= 7
|
||||
#if __SHADER_TARGET_MINOR >= 8
|
||||
else if(opcode == DEBUG_SAMPLE_TEX_SAMPLE_CMP_GRAD) // SM6.8
|
||||
{
|
||||
switch(debugSampleTexDim)
|
||||
{
|
||||
default:
|
||||
case DEBUG_SAMPLE_TEX1D:
|
||||
{
|
||||
switch(debugSampleRetType)
|
||||
{
|
||||
case DEBUG_SAMPLE_UNORM:
|
||||
return t1D_unorm.SampleCmpGrad(s, uv.xy, compare, ddx_.x, ddy_.x, offsets.x);
|
||||
case DEBUG_SAMPLE_SNORM:
|
||||
return t1D_snorm.SampleCmpGrad(s, uv.xy, compare, ddx_.x, ddy_.x, offsets.x);
|
||||
default: return t1D_float.SampleCmpGrad(s, uv.xy, compare, ddx_.x, ddy_.x, offsets.x);
|
||||
}
|
||||
}
|
||||
case DEBUG_SAMPLE_TEX2D:
|
||||
{
|
||||
switch(debugSampleRetType)
|
||||
{
|
||||
case DEBUG_SAMPLE_UNORM:
|
||||
return t2D_unorm.SampleCmpGrad(s, uv.xyz, compare, ddx_.xy, ddy_.xy, offsets.xy);
|
||||
case DEBUG_SAMPLE_SNORM:
|
||||
return t2D_snorm.SampleCmpGrad(s, uv.xyz, compare, ddx_.xy, ddy_.xy, offsets.xy);
|
||||
default: return t2D_float.SampleCmpGrad(s, uv.xyz, compare, ddx_.xy, ddy_.xy, offsets.xy);
|
||||
}
|
||||
}
|
||||
case DEBUG_SAMPLE_TEX3D:
|
||||
{
|
||||
switch(debugSampleRetType)
|
||||
{
|
||||
case DEBUG_SAMPLE_UNORM:
|
||||
return t3D_unorm.SampleCmpGrad(s, uv.xyz, compare, ddx_.xyz, ddy_.xyz, offsets.xyz);
|
||||
case DEBUG_SAMPLE_SNORM:
|
||||
return t3D_snorm.SampleCmpGrad(s, uv.xyz, compare, ddx_.xyz, ddy_.xyz, offsets.xyz);
|
||||
default:
|
||||
return t3D_float.SampleCmpGrad(s, uv.xyz, compare, ddx_.xyz, ddy_.xyz, offsets.xyz);
|
||||
}
|
||||
}
|
||||
case DEBUG_SAMPLE_TEXCUBE:
|
||||
{
|
||||
switch(debugSampleRetType)
|
||||
{
|
||||
case DEBUG_SAMPLE_UNORM:
|
||||
return tCube_unorm.SampleCmpGrad(s, uv, compare, ddx_.xyz, ddy_.xyz);
|
||||
case DEBUG_SAMPLE_SNORM:
|
||||
return tCube_snorm.SampleCmpGrad(s, uv, compare, ddx_.xyz, ddy_.xyz);
|
||||
default: return tCube_float.SampleCmpGrad(s, uv, compare, ddx_.xyz, ddy_.xyz);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // #if __SHADER_TARGET_MINOR >= 8
|
||||
#endif // #if __SHADER_TARGET_MAJOR >= 6
|
||||
else
|
||||
{
|
||||
return float4(0, 0, 0, 0);
|
||||
|
||||
@@ -836,8 +836,12 @@ bool D3D12DebugManager::CreateShaderDebugResources()
|
||||
return false;
|
||||
}
|
||||
ID3DBlob *dxilPsBlob = NULL;
|
||||
D3D12_FEATURE_DATA_SHADER_MODEL smMaxSupport = {D3D_SHADER_MODEL_6_8};
|
||||
m_pDevice->CheckFeatureSupport(D3D12_FEATURE_SHADER_MODEL, &smMaxSupport, sizeof(smMaxSupport));
|
||||
D3D_SHADER_MODEL smModel = smMaxSupport.HighestShaderModel;
|
||||
rdcstr psSM = StringFormat::Fmt("ps_%d_%d", (smModel >> 4), (smModel & 0xf));
|
||||
if(m_pDevice->GetShaderCache()->GetShaderBlob(hlsl.c_str(), "RENDERDOC_DebugSamplePS",
|
||||
D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, "ps_6_0",
|
||||
D3DCOMPILE_WARNINGS_ARE_ERRORS, {}, psSM.c_str(),
|
||||
&dxilPsBlob) != "")
|
||||
{
|
||||
RDCASSERT(!dxilPsBlob);
|
||||
|
||||
@@ -1118,23 +1118,23 @@ bool D3D12APIWrapper::CalculateSampleGather(
|
||||
switch(dxOp)
|
||||
{
|
||||
case DXOp::Sample: sampleOp = DEBUG_SAMPLE_TEX_SAMPLE; break;
|
||||
case DXOp::SampleLevel: sampleOp = DEBUG_SAMPLE_TEX_SAMPLE_LEVEL; break;
|
||||
case DXOp::SampleBias: sampleOp = DEBUG_SAMPLE_TEX_SAMPLE_BIAS; break;
|
||||
case DXOp::SampleCmp: sampleOp = DEBUG_SAMPLE_TEX_SAMPLE_CMP; break;
|
||||
case DXOp::SampleLevel: sampleOp = DEBUG_SAMPLE_TEX_SAMPLE_LEVEL; break;
|
||||
case DXOp::SampleGrad: sampleOp = DEBUG_SAMPLE_TEX_SAMPLE_GRAD; break;
|
||||
case DXOp::SampleCmp: sampleOp = DEBUG_SAMPLE_TEX_SAMPLE_CMP; break;
|
||||
case DXOp::SampleCmpBias: sampleOp = DEBUG_SAMPLE_TEX_SAMPLE_CMP_BIAS; break;
|
||||
case DXOp::SampleCmpLevel: sampleOp = DEBUG_SAMPLE_TEX_SAMPLE_CMP_LEVEL; break;
|
||||
case DXOp::SampleCmpGrad: sampleOp = DEBUG_SAMPLE_TEX_SAMPLE_CMP_GRAD; break;
|
||||
case DXOp::SampleCmpLevelZero: sampleOp = DEBUG_SAMPLE_TEX_SAMPLE_CMP_LEVEL_ZERO; break;
|
||||
case DXOp::TextureGather: sampleOp = DEBUG_SAMPLE_TEX_GATHER4; break;
|
||||
case DXOp::TextureGatherCmp: sampleOp = DEBUG_SAMPLE_TEX_GATHER4_CMP; break;
|
||||
case DXOp::CalculateLOD: sampleOp = DEBUG_SAMPLE_TEX_LOD; break;
|
||||
// In the shader DEBUG_SAMPLE_TEX_LOAD and DEBUG_SAMPLE_TEX_LOAD_MS behave equivalently
|
||||
case DXOp::TextureLoad: sampleOp = DEBUG_SAMPLE_TEX_LOAD; break;
|
||||
// TODO: consider these DXIL opcode operations
|
||||
// DXOp::SampleCmpBias
|
||||
// DXOp::SampleCmpGrad
|
||||
// DXOp::SampleCmpLevel
|
||||
// DXOp::TextureGatherRaw
|
||||
// TODO: consider these DXBC opcode operations
|
||||
// DEBUG_SAMPLE_TEX_GATHER4_PARAM_OFFSET_CMP
|
||||
// DEBUG_SAMPLE_TEX_LOAD_MS
|
||||
default:
|
||||
// To support a new instruction, the shader created in
|
||||
// D3D12DebugManager::CreateShaderDebugResources will need updating
|
||||
|
||||
@@ -1389,16 +1389,17 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
|
||||
break;
|
||||
}
|
||||
case DXOp::Sample:
|
||||
case DXOp::SampleBias:
|
||||
case DXOp::SampleLevel:
|
||||
case DXOp::SampleGrad:
|
||||
case DXOp::SampleCmp:
|
||||
case DXOp::SampleCmpBias:
|
||||
case DXOp::SampleCmpLevel:
|
||||
case DXOp::SampleCmpGrad:
|
||||
case DXOp::SampleCmpLevelZero:
|
||||
case DXOp::TextureGather:
|
||||
case DXOp::TextureGatherCmp:
|
||||
{
|
||||
// TODO
|
||||
// case DXOp::SampleBias:
|
||||
// case DXOp::SampleGrad:
|
||||
// case DXOp::SampleCmp:
|
||||
// case DXOp::SampleCmpLevel:
|
||||
// case DXOp::SampleCmpGrad:
|
||||
// case DXOp::SampleCmpBias:
|
||||
rdcstr handleId = GetArgumentName(1);
|
||||
const ResourceReference *resRef = GetResource(handleId);
|
||||
if(!resRef)
|
||||
@@ -2067,13 +2068,8 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
|
||||
case DXOp::Ubfe:
|
||||
case DXOp::Bfi:
|
||||
case DXOp::CBufferLoad:
|
||||
case DXOp::SampleBias:
|
||||
case DXOp::SampleGrad:
|
||||
case DXOp::SampleCmp:
|
||||
case DXOp::BufferUpdateCounter:
|
||||
case DXOp::CheckAccessFullyMapped:
|
||||
case DXOp::TextureGather:
|
||||
case DXOp::TextureGatherCmp:
|
||||
case DXOp::AtomicBinOp:
|
||||
case DXOp::AtomicCompareExchange:
|
||||
case DXOp::Barrier:
|
||||
@@ -2210,7 +2206,6 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
|
||||
case DXOp::IsHelperLane:
|
||||
case DXOp::QuadVote:
|
||||
case DXOp::TextureGatherRaw:
|
||||
case DXOp::SampleCmpLevel:
|
||||
case DXOp::TextureStoreSample:
|
||||
case DXOp::WaveMatrix_Annotate:
|
||||
case DXOp::WaveMatrix_Depth:
|
||||
@@ -2240,8 +2235,6 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
|
||||
case DXOp::AnnotateNodeRecordHandle:
|
||||
case DXOp::NodeOutputIsValid:
|
||||
case DXOp::GetRemainingRecursionLevels:
|
||||
case DXOp::SampleCmpGrad:
|
||||
case DXOp::SampleCmpBias:
|
||||
case DXOp::StartVertexLocation:
|
||||
case DXOp::StartInstanceLocation:
|
||||
case DXOp::NumOpCodes:
|
||||
@@ -2439,7 +2432,7 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
|
||||
}
|
||||
RDCASSERT((resultType->type == DXIL::Type::TypeKind::Scalar) ||
|
||||
(resultType->type == DXIL::Type::TypeKind::Struct));
|
||||
// TODO: NEED TO DEMANGLE THE NAME TO DEMANGLE TO MATCH DISASSEMBLY
|
||||
// TODO: NEED TO DEMANGLE THE NAME TO MATCH DISASSEMBLY
|
||||
result.type = baseType;
|
||||
result.rows = (uint8_t)countElems;
|
||||
result.members.resize(countElems);
|
||||
@@ -3334,7 +3327,7 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
|
||||
case Operation::AtomicUMax:
|
||||
case Operation::AtomicUMin:
|
||||
{
|
||||
// JAKE TODO: full proper load and store from/to memory i.e. group shared
|
||||
// TODO: full proper load and store from/to memory i.e. group shared
|
||||
// Currently only supporting Stack allocated pointers
|
||||
size_t allocSize = 0;
|
||||
void *allocMemoryBackingPtr = NULL;
|
||||
@@ -3810,16 +3803,18 @@ void ThreadState::PerformGPUResourceOp(const rdcarray<ThreadState> &workgroups,
|
||||
{
|
||||
// TextureLoad(srv,mipLevelOrSampleCount,coord0,coord1,coord2,offset0,offset1,offset2)
|
||||
// Sample(srv,sampler,coord0,coord1,coord2,coord3,offset0,offset1,offset2,clamp)
|
||||
// SampleLevel(srv,sampler,coord0,coord1,coord2,coord3,offset0,offset1,offset2,LOD)
|
||||
// SampleCmpLevelZero(srv,sampler,coord0,coord1,coord2,coord3,offset0,offset1,offset2,compareValue)
|
||||
|
||||
// TODO
|
||||
// SampleBias(srv,sampler,coord0,coord1,coord2,coord3,offset0,offset1,offset2,bias,clamp)
|
||||
// SampleLevel(srv,sampler,coord0,coord1,coord2,coord3,offset0,offset1,offset2,LOD)
|
||||
// SampleGrad(srv,sampler,coord0,coord1,coord2,coord3,offset0,offset1,offset2,ddx0,ddx1,ddx2,ddy0,ddy1,ddy2,clamp)
|
||||
// SampleCmp(srv,sampler,coord0,coord1,coord2,coord3,offset0,offset1,offset2,compareValue,clamp)
|
||||
// SampleCmpBias(srv,sampler,coord0,coord1,coord2,coord3,offset0,offset1,offset2,compareValue,bias,clamp)
|
||||
// SampleCmpLevel(srv,sampler,coord0,coord1,coord2,coord3,offset0,offset1,offset2,compareValue,lod)
|
||||
// SampleCmpGrad(srv,sampler,coord0,coord1,coord2,coord3,offset0,offset1,offset2,compareValue,ddx0,ddx1,ddx2,ddy0,ddy1,ddy2,clamp)
|
||||
// SampleCmpBias(srv,sampler,coord0,coord1,coord2,coord3,offset0,offset1,offset2,compareValue,bias,clamp)
|
||||
// SampleCmpLevelZero(srv,sampler,coord0,coord1,coord2,coord3,offset0,offset1,offset2,compareValue)
|
||||
// CalculateLOD(handle,sampler,coord0,coord1,coord2,clamped)
|
||||
|
||||
// TextureGather(srv,sampler,coord0,coord1,coord2,coord3,offset0,offset1,channel)
|
||||
// TextureGatherCmp(srv,sampler,coord0,coord1,coord2,coord3,offset0,offset1,channel,compareValue)
|
||||
|
||||
// DXIL reports the vector result as a struct of N members of Element type, plus an int.
|
||||
const Type *retType = inst.type;
|
||||
@@ -3855,8 +3850,39 @@ void ThreadState::PerformGPUResourceOp(const rdcarray<ThreadState> &workgroups,
|
||||
samplerData.mode = SamplerMode::NUM_SAMPLERS;
|
||||
|
||||
bool uvDDXY[4] = {false, false, false, false};
|
||||
GatherChannel gatherChannel = GatherChannel::Red;
|
||||
|
||||
if(dxOpCode != DXOp::TextureLoad)
|
||||
if(dxOpCode == DXOp::TextureLoad)
|
||||
{
|
||||
ShaderVariable arg;
|
||||
// mipLevelOrSampleCount is in arg 2
|
||||
if(GetShaderVariable(inst.args[2], opCode, dxOpCode, arg, false))
|
||||
{
|
||||
uint32_t mipLevelOrSampleCount = arg.value.u32v[0];
|
||||
// The debug shader uses arrays of resources for 1D, 2D textures
|
||||
// mipLevel goes into UV[N] : N = 1D: 2, 2D: 3, 3D: 3
|
||||
switch(srv.shape)
|
||||
{
|
||||
case DXIL::ResourceKind::Texture1D: uv.value.u32v[2] = mipLevelOrSampleCount; break;
|
||||
case DXIL::ResourceKind::Texture2D: uv.value.u32v[3] = mipLevelOrSampleCount; break;
|
||||
case DXIL::ResourceKind::Texture3D: uv.value.u32v[3] = mipLevelOrSampleCount; break;
|
||||
case DXIL::ResourceKind::Texture2DMS: msIndex = mipLevelOrSampleCount; break;
|
||||
case DXIL::ResourceKind::Texture2DMSArray: msIndex = mipLevelOrSampleCount; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
// UV is int data in args 3,4,5
|
||||
// Offset is int data in args 6,7,8
|
||||
for(uint32_t i = 0; i < 3; ++i)
|
||||
{
|
||||
if(GetShaderVariable(inst.args[3 + i], opCode, dxOpCode, arg, false))
|
||||
uv.value.s32v[i] = arg.value.s32v[0];
|
||||
if(GetShaderVariable(inst.args[6 + i], opCode, dxOpCode, arg, false))
|
||||
texelOffsets[i] = (int8_t)arg.value.s32v[0];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Sampler is in arg 2
|
||||
rdcstr samplerId = GetArgumentName(2);
|
||||
@@ -3867,15 +3893,63 @@ void ThreadState::PerformGPUResourceOp(const rdcarray<ThreadState> &workgroups,
|
||||
RDCASSERTEQUAL(samplerRef->resourceBase.resClass, ResourceClass::Sampler);
|
||||
// samplerRef->resourceBase must be a Sampler
|
||||
const DXIL::EntryPointInterface::Sampler &sampler = resRef->resourceBase.samplerData;
|
||||
// TODO: BIAS COMES FROM THE Sample*Bias arguments
|
||||
samplerData.bias = 0.0f;
|
||||
samplerData.binding.registerSpace = samplerRef->resourceBase.space;
|
||||
samplerData.binding.shaderRegister = samplerRef->resourceBase.regBase;
|
||||
samplerData.mode = ConvertSamplerKindToSamplerMode(sampler.samplerType);
|
||||
|
||||
int32_t biasArg = -1;
|
||||
int32_t lodArg = -1;
|
||||
int32_t compareArg = -1;
|
||||
int32_t gatherArg = -1;
|
||||
uint32_t countOffset = 3;
|
||||
uint32_t countUV = 4;
|
||||
// TODO: Sample*: Clamp is in arg 10
|
||||
// TODO: CalculateLOD: clamped is in arg 6
|
||||
// CalculateSampleGather returns {CalculateLevelOfDetail(), CalculateLevelOfDetailUnclamped()}
|
||||
|
||||
// SampleBias : bias is arg 10
|
||||
// SampleLevel: lod is in arg 10
|
||||
// SampleCmp: compare is in arg 10
|
||||
// SampleCmpBias: compare is in arg 10, bias is in arg 11
|
||||
// SampleCmpLevel: compare is in arg 10, LOD is in arg 11
|
||||
// SampleCmpGrad: compare is in arg 10
|
||||
// SampleCmpLevelZero: compare is in arg 10
|
||||
// TextureGather: compare is in arg 10, gather is in 9
|
||||
// TextureGatherCmp: compare is in arg 10, gather is in 9
|
||||
switch(dxOpCode)
|
||||
{
|
||||
case DXOp::Sample: break;
|
||||
case DXOp::SampleBias: biasArg = 10; break;
|
||||
case DXOp::SampleLevel: lodArg = 10; break;
|
||||
case DXOp::SampleGrad: break;
|
||||
case DXOp::SampleCmp: compareArg = 10; break;
|
||||
case DXOp::SampleCmpBias:
|
||||
compareArg = 10;
|
||||
biasArg = 11;
|
||||
break;
|
||||
case DXOp::SampleCmpLevel:
|
||||
compareArg = 10;
|
||||
lodArg = 11;
|
||||
break;
|
||||
case DXOp::SampleCmpGrad: compareArg = 10; break;
|
||||
case DXOp::SampleCmpLevelZero: compareArg = 10; break;
|
||||
case DXOp::TextureGather:
|
||||
countOffset = 2;
|
||||
gatherArg = 9;
|
||||
break;
|
||||
case DXOp::CalculateLOD: countUV = 3; break;
|
||||
case DXOp::TextureGatherCmp:
|
||||
countOffset = 2;
|
||||
gatherArg = 9;
|
||||
compareArg = 10;
|
||||
break;
|
||||
default: RDCERR("Unhandled DX Operation %s", ToStr(dxOpCode).c_str()); break;
|
||||
}
|
||||
|
||||
ShaderVariable arg;
|
||||
// UV is float data in args 3,4,5,6
|
||||
for(uint32_t i = 0; i < 4; ++i)
|
||||
// UV is float data in args: Sample* 3,4,5,6 ; CalculateLOD 3,4,5
|
||||
for(uint32_t i = 0; i < countUV; ++i)
|
||||
{
|
||||
if(GetShaderVariable(inst.args[3 + i], opCode, dxOpCode, arg))
|
||||
{
|
||||
@@ -3886,62 +3960,54 @@ void ThreadState::PerformGPUResourceOp(const rdcarray<ThreadState> &workgroups,
|
||||
}
|
||||
}
|
||||
|
||||
// Offset is int data in args 7,8,9
|
||||
if(GetShaderVariable(inst.args[7], opCode, dxOpCode, arg, false))
|
||||
texelOffsets[0] = (int8_t)arg.value.s32v[0];
|
||||
if(GetShaderVariable(inst.args[8], opCode, dxOpCode, arg, false))
|
||||
texelOffsets[1] = (int8_t)arg.value.s32v[0];
|
||||
if(GetShaderVariable(inst.args[9], opCode, dxOpCode, arg, false))
|
||||
texelOffsets[2] = (int8_t)arg.value.s32v[0];
|
||||
|
||||
// TODO: Sample: Clamp is in arg 10
|
||||
|
||||
// SampleLevel: LOD is in arg 10
|
||||
// SampleCmpLevelZero: compare is in arg 10
|
||||
if((dxOpCode == DXOp::SampleLevel) || (dxOpCode == DXOp::SampleCmpLevelZero))
|
||||
// Offset is int data in args: Sample* 7,8,9 ; Gather* 7,8
|
||||
for(uint32_t i = 0; i < countOffset; ++i)
|
||||
{
|
||||
if(GetShaderVariable(inst.args[10], opCode, dxOpCode, arg))
|
||||
if(GetShaderVariable(inst.args[7 + i], opCode, dxOpCode, arg, false))
|
||||
texelOffsets[i] = (int8_t)arg.value.s32v[0];
|
||||
}
|
||||
|
||||
if((lodArg > 0))
|
||||
{
|
||||
if(GetShaderVariable(inst.args[lodArg], opCode, dxOpCode, arg))
|
||||
{
|
||||
RDCASSERTEQUAL(arg.type, VarType::Float);
|
||||
lodValue = arg.value.f32v[0];
|
||||
}
|
||||
}
|
||||
if((compareArg > 0))
|
||||
{
|
||||
if(GetShaderVariable(inst.args[compareArg], opCode, dxOpCode, arg))
|
||||
{
|
||||
RDCASSERTEQUAL(arg.type, VarType::Float);
|
||||
compareValue = arg.value.f32v[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ShaderVariable arg;
|
||||
// TODO : mipLevelOrSampleCount is in arg 2
|
||||
if(GetShaderVariable(inst.args[2], opCode, dxOpCode, arg))
|
||||
|
||||
if(biasArg > 0)
|
||||
{
|
||||
msIndex = arg.value.u32v[0];
|
||||
lodValue = arg.value.f32v[0];
|
||||
compareValue = arg.value.f32v[0];
|
||||
if(GetShaderVariable(inst.args[biasArg], opCode, dxOpCode, arg))
|
||||
{
|
||||
RDCASSERTEQUAL(arg.type, VarType::Float);
|
||||
samplerData.bias = arg.value.f32v[0];
|
||||
}
|
||||
}
|
||||
|
||||
// UV is int data in args 3,4,5
|
||||
if(GetShaderVariable(inst.args[3], opCode, dxOpCode, arg))
|
||||
uv.value.s32v[0] = arg.value.s32v[0];
|
||||
if(GetShaderVariable(inst.args[4], opCode, dxOpCode, arg))
|
||||
uv.value.s32v[1] = arg.value.s32v[0];
|
||||
if(GetShaderVariable(inst.args[5], opCode, dxOpCode, arg))
|
||||
uv.value.s32v[2] = arg.value.s32v[0];
|
||||
|
||||
// Offset is int data in args 6,7,8
|
||||
if(GetShaderVariable(inst.args[6], opCode, dxOpCode, arg))
|
||||
texelOffsets[0] = (int8_t)arg.value.s32v[0];
|
||||
if(GetShaderVariable(inst.args[7], opCode, dxOpCode, arg))
|
||||
texelOffsets[1] = (int8_t)arg.value.s32v[0];
|
||||
if(GetShaderVariable(inst.args[8], opCode, dxOpCode, arg))
|
||||
texelOffsets[2] = (int8_t)arg.value.s32v[0];
|
||||
if(gatherArg > 0)
|
||||
{
|
||||
if(GetShaderVariable(inst.args[gatherArg], opCode, dxOpCode, arg))
|
||||
{
|
||||
RDCASSERTEQUAL(arg.type, VarType::SInt);
|
||||
// Red = 0, Green = 1, Blue = 2, Alpha = 3
|
||||
gatherChannel = (DXILDebug::GatherChannel)arg.value.s32v[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: DDX & DDY
|
||||
ShaderVariable ddx;
|
||||
ShaderVariable ddy;
|
||||
// Sample, SampleBias, SampleCmp, CalculateLOD need DDX, DDY
|
||||
if((dxOpCode == DXOp::Sample) || (dxOpCode == DXOp::SampleBias) ||
|
||||
(dxOpCode == DXOp::SampleCmp) || (dxOpCode == DXOp::CalculateLOD))
|
||||
// Sample, SampleBias, CalculateLOD need DDX, DDY
|
||||
if((dxOpCode == DXOp::Sample) || (dxOpCode == DXOp::SampleBias) || (dxOpCode == DXOp::CalculateLOD))
|
||||
{
|
||||
if(m_ShaderType != DXBC::ShaderType::Pixel || workgroups.size() != 4)
|
||||
{
|
||||
@@ -3950,7 +4016,6 @@ void ThreadState::PerformGPUResourceOp(const rdcarray<ThreadState> &workgroups,
|
||||
else
|
||||
{
|
||||
// texture samples use coarse derivatives
|
||||
// TODO: the UV should be the ID per UV compponent
|
||||
ShaderValue delta;
|
||||
for(uint32_t i = 0; i < 4; i++)
|
||||
{
|
||||
@@ -3964,19 +4029,37 @@ void ThreadState::PerformGPUResourceOp(const rdcarray<ThreadState> &workgroups,
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(dxOpCode == DXOp::SampleGrad)
|
||||
else if((dxOpCode == DXOp::SampleGrad) || (dxOpCode == DXOp::SampleCmpGrad))
|
||||
{
|
||||
// TODO: get from arguments
|
||||
// SampleGrad DDX is argument 10, DDY is argument 14
|
||||
// SampleCmpGrad DDX is argument 11, DDY is argument 15
|
||||
uint32_t ddx0 = dxOpCode == DXOp::SampleGrad ? 10 : 11;
|
||||
uint32_t ddy0 = ddx0 + 4;
|
||||
ShaderVariable arg;
|
||||
for(uint32_t i = 0; i < 4; i++)
|
||||
{
|
||||
if(uvDDXY[i])
|
||||
{
|
||||
RDCASSERT(GetShaderVariable(inst.args[ddx0 + i], opCode, dxOpCode, arg));
|
||||
ddx.value.f32v[i] = arg.value.f32v[0];
|
||||
RDCASSERT(GetShaderVariable(inst.args[ddy0 + i], opCode, dxOpCode, arg));
|
||||
ddy.value.f32v[i] = arg.value.f32v[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t swizzle[4] = {0, 1, 2, 3};
|
||||
|
||||
// TODO: GATHER CHANNEL
|
||||
GatherChannel gatherChannel = GatherChannel::Red;
|
||||
uint32_t instructionIdx = m_FunctionInstructionIdx - 1;
|
||||
const char *opString = ToStr(dxOpCode).c_str();
|
||||
ShaderVariable data;
|
||||
|
||||
// TODO: TextureGatherRaw // SM 6.7
|
||||
// Return types for TextureGatherRaw
|
||||
// DXGI_FORMAT_R16_UINT : u16
|
||||
// DXGI_FORMAT_R32_UINT : u32
|
||||
// DXGI_FORMAT_R32G32_UINT : u32x2
|
||||
|
||||
ShaderVariable data;
|
||||
apiWrapper->CalculateSampleGather(dxOpCode, resourceData, samplerData, uv, ddx, ddy, texelOffsets,
|
||||
msIndex, lodValue, compareValue, swizzle, gatherChannel,
|
||||
m_ShaderType, instructionIdx, opString, data);
|
||||
|
||||
@@ -1806,13 +1806,8 @@ rdcstr Program::GetDebugStatus()
|
||||
case DXOp::Ubfe:
|
||||
case DXOp::Bfi:
|
||||
case DXOp::CBufferLoad:
|
||||
case DXOp::SampleBias:
|
||||
case DXOp::SampleGrad:
|
||||
case DXOp::SampleCmp:
|
||||
case DXOp::BufferUpdateCounter:
|
||||
case DXOp::CheckAccessFullyMapped:
|
||||
case DXOp::TextureGather:
|
||||
case DXOp::TextureGatherCmp:
|
||||
case DXOp::AtomicBinOp:
|
||||
case DXOp::AtomicCompareExchange:
|
||||
case DXOp::Barrier:
|
||||
@@ -1949,7 +1944,6 @@ rdcstr Program::GetDebugStatus()
|
||||
case DXOp::IsHelperLane:
|
||||
case DXOp::QuadVote:
|
||||
case DXOp::TextureGatherRaw:
|
||||
case DXOp::SampleCmpLevel:
|
||||
case DXOp::TextureStoreSample:
|
||||
case DXOp::WaveMatrix_Annotate:
|
||||
case DXOp::WaveMatrix_Depth:
|
||||
@@ -1979,8 +1973,6 @@ rdcstr Program::GetDebugStatus()
|
||||
case DXOp::AnnotateNodeRecordHandle:
|
||||
case DXOp::NodeOutputIsValid:
|
||||
case DXOp::GetRemainingRecursionLevels:
|
||||
case DXOp::SampleCmpGrad:
|
||||
case DXOp::SampleCmpBias:
|
||||
case DXOp::StartVertexLocation:
|
||||
case DXOp::StartInstanceLocation:
|
||||
case DXOp::NumOpCodes:
|
||||
|
||||
Reference in New Issue
Block a user