Extend D3D12_Shader_Debug_Zoo tests

New pixel shader for testing which does not contain resource references
Added new tests for ddx, ddy and discard
This commit is contained in:
Jake Turner
2025-03-20 13:52:20 +00:00
parent 025a6bbf86
commit e444aff7cf
2 changed files with 312 additions and 110 deletions
+250 -55
View File
@@ -34,6 +34,7 @@ RD_TEST(D3D12_Shader_Debug_Zoo, D3D12GraphicsTest)
float zero;
float one;
float negone;
float texDim;
};
std::string vertexSampleVS = R"EOSHADER(
@@ -94,11 +95,13 @@ struct consts
float zeroVal : ZERO;
float oneVal : ONE;
float negoneVal : NEGONE;
float texDim : TEXDIM;
};
struct v2f
{
float4 pos : SV_POSITION;
float4 s : S;
float2 zeroVal : ZERO;
float tinyVal : TINY;
float oneVal : ONE;
@@ -116,6 +119,18 @@ v2f main(consts IN, uint tri : SV_InstanceID)
v2f OUT = (v2f)0;
OUT.pos = float4(IN.pos.x + IN.pos.z * float(tri), IN.pos.y, 0.0f, 1);
// OUT.s.xy : 0 -> 2 : across the triangle x & y, changes per pixel
OUT.s.x = IN.pos.x + 1.0;
OUT.s.x *= IN.texDim;
OUT.s.x -= 1.0;
OUT.s.x /= 2.0;
OUT.s.y = IN.pos.y;
OUT.s.y *= 2.0;
OUT.s.y += 0.5;
OUT.s.y = 2.0 - OUT.s.y;
// OUT.s.zw : large variation in x & y
OUT.s.zw = (IN.pos.xy + float2(543.0, 213.0)) * (IN.pos.yx + float2(100.0, -113.0));
OUT.zeroVal = IN.zeroVal.xx;
OUT.oneVal = IN.oneVal;
@@ -1000,6 +1015,49 @@ float4 main(v2f IN) : SV_Target0
return float4(0.4f, 0.4f, 0.4f, 0.4f);
}
)EOSHADER";
std::string noResourcesPixel = R"EOSHADER(
float4 main(v2f IN) : SV_Target0
{
float posinf = IN.oneVal/IN.zeroVal.x;
float neginf = IN.negoneVal/IN.zeroVal.x;
float nan = IN.zeroVal.x/IN.zeroVal.y;
float negone = IN.negoneVal;
float posone = IN.oneVal;
float zero = IN.zeroVal.x;
float tiny = IN.tinyVal;
int intval = IN.intval;
if(IN.tri == 0)
{
// IN.s.xy : 0/1/2 : across the triangle in x & y
float2 s = IN.s.xy;
return float4(ddx(s.x), ddy(s.y), s.x, s.y);
}
if(IN.tri == 1)
{
// IN.s.wz : large variation across the triangle in x & y
float2 s = IN.s.zw;
return float4(ddx(s.x), ddy(s.y), s.x, s.y);
}
if(IN.tri == 2)
{
// IN.s : 0/1/2 : across the triangle in x & y
float2 s = IN.s.xy;
if (s.x > 0.5)
discard;
if (s.y > 0.5)
discard;
s *= posone * float2(0.55f, 0.48f);
return float4(ddx(s.x), ddy(s.y), s.x, s.y);
}
return float4(0.4f, 0.4f, 0.4f, 0.4f);
};
)EOSHADER";
std::string msaaPixel = R"EOSHADER(
@@ -1093,7 +1151,7 @@ void main(int3 inTestIndex : SV_GroupID)
size_t lastTest = pixel.rfind("IN.tri == ");
lastTest += sizeof("IN.tri == ") - 1;
const uint32_t numTests = atoi(pixel.c_str() + lastTest) + 1;
const uint32_t numResTests = atoi(pixel.c_str() + lastTest) + 1;
std::string undefined_tests = "Undefined tests:";
@@ -1110,6 +1168,10 @@ void main(int3 inTestIndex : SV_GroupID)
undef = pixel.find("undefined-test", undef + 1);
}
lastTest = noResourcesPixel.rfind("IN.tri == ");
lastTest += sizeof("IN.tri == ") - 1;
const uint32_t numNoResTests = atoi(noResourcesPixel.c_str() + lastTest) + 1;
std::vector<D3D12_INPUT_ELEMENT_DESC> inputLayout;
inputLayout.reserve(4);
inputLayout.push_back({
@@ -1148,6 +1210,15 @@ void main(int3 inTestIndex : SV_GroupID)
D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,
0,
});
inputLayout.push_back({
"TEXDIM",
0,
DXGI_FORMAT_R32_FLOAT,
0,
D3D12_APPEND_ALIGNED_ELEMENT,
D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA,
0,
});
D3D12_STATIC_SAMPLER_DESC staticSamp = {};
staticSamp.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
@@ -1250,9 +1321,9 @@ void main(int3 inTestIndex : SV_GroupID)
psos[3]->SetName(L"ps_5_1_opt");
// Recompile with SM 6.0, SM 6.2 and SM 6.6
uint32_t compileOptions = CompileOptionFlags::None;
if(opts4.Native16BitShaderOpsSupported)
compileOptions |= CompileOptionFlags::Enable16BitTypes;
const uint32_t compileOptions = (opts4.Native16BitShaderOpsSupported)
? CompileOptionFlags::Enable16BitTypes
: CompileOptionFlags::None;
if(supportSM60)
{
ID3DBlobPtr vsblob = Compile(common + vertex, "main", "vs_6_0");
@@ -1314,7 +1385,113 @@ void main(int3 inTestIndex : SV_GroupID)
psos[9]->SetName(L"ps_6_6_opt");
}
static const uint32_t texDim = AlignUp(numTests, 64U) * 4;
ID3D12PipelineStatePtr noResPSOs[numShaderModels * 2] = {};
noResPSOs[0] = MakePSO()
.RootSig(sig)
.InputLayout(inputLayout)
.VS(vs5blob)
.PS(Compile(common + noResourcesPixel, "main", "ps_5_0",
CompileOptionFlags::SkipOptimise))
.RTVs({DXGI_FORMAT_R32G32B32A32_FLOAT});
noResPSOs[0]->SetName(L"ps_5_0");
noResPSOs[1] =
MakePSO()
.RootSig(sig)
.InputLayout(inputLayout)
.VS(vs5blob)
.PS(Compile(common + noResourcesPixel, "main", "ps_5_0", CompileOptionFlags::None))
.RTVs({DXGI_FORMAT_R32G32B32A32_FLOAT});
noResPSOs[1]->SetName(L"ps_5_0_opt");
// Recompile the same PS with SM 5.1 to test shader debugging with the different bytecode
noResPSOs[2] = MakePSO()
.RootSig(sig)
.InputLayout(inputLayout)
.VS(vs5blob)
.PS(Compile(common + "\n#define SM_5_1 1\n" + noResourcesPixel, "main",
"ps_5_1", CompileOptionFlags::SkipOptimise))
.RTVs({DXGI_FORMAT_R32G32B32A32_FLOAT});
noResPSOs[2]->SetName(L"ps_5_1");
noResPSOs[3] = MakePSO()
.RootSig(sig)
.InputLayout(inputLayout)
.VS(vs5blob)
.PS(Compile(common + "\n#define SM_5_1 1\n" + noResourcesPixel, "main",
"ps_5_1", CompileOptionFlags::None))
.RTVs({DXGI_FORMAT_R32G32B32A32_FLOAT});
noResPSOs[3]->SetName(L"ps_5_1_opt");
// Recompile with SM 6.0, SM 6.2 and SM 6.6
if(supportSM60)
{
ID3DBlobPtr vsblob = Compile(common + vertex, "main", "vs_6_0");
noResPSOs[4] =
MakePSO()
.RootSig(sig)
.InputLayout(inputLayout)
.VS(vsblob)
.PS(Compile(common + "\n#define SM_6_0 1\n" + shaderDefines + noResourcesPixel,
"main", "ps_6_0", CompileOptionFlags::SkipOptimise))
.RTVs({DXGI_FORMAT_R32G32B32A32_FLOAT});
noResPSOs[4]->SetName(L"ps_6_0");
noResPSOs[5] =
MakePSO()
.RootSig(sig)
.InputLayout(inputLayout)
.VS(vsblob)
.PS(Compile(common + "\n#define SM_6_0 1\n" + shaderDefines + noResourcesPixel,
"main", "ps_6_0", CompileOptionFlags::None))
.RTVs({DXGI_FORMAT_R32G32B32A32_FLOAT});
noResPSOs[5]->SetName(L"ps_6_0_opt");
}
if(supportSM62)
{
ID3DBlobPtr vsblob = Compile(common + vertex, "main", "vs_6_2");
noResPSOs[6] =
MakePSO()
.RootSig(sig)
.InputLayout(inputLayout)
.VS(vsblob)
.PS(Compile(common + "\n#define SM_6_2 1\n" + shaderDefines + noResourcesPixel,
"main", "ps_6_2", compileOptions | CompileOptionFlags::SkipOptimise))
.RTVs({DXGI_FORMAT_R32G32B32A32_FLOAT});
noResPSOs[6]->SetName(L"ps_6_2");
noResPSOs[7] =
MakePSO()
.RootSig(sig)
.InputLayout(inputLayout)
.VS(vsblob)
.PS(Compile(common + "\n#define SM_6_2 1\n" + shaderDefines + noResourcesPixel,
"main", "ps_6_2", compileOptions))
.RTVs({DXGI_FORMAT_R32G32B32A32_FLOAT});
noResPSOs[7]->SetName(L"ps_6_2_opt");
}
if(supportSM66)
{
ID3DBlobPtr vsblob = Compile(common + vertex, "main", "vs_6_6");
noResPSOs[8] =
MakePSO()
.RootSig(sig)
.InputLayout(inputLayout)
.VS(vsblob)
.PS(Compile(common + "\n#define SM_6_6 1\n" + shaderDefines + noResourcesPixel,
"main", "ps_6_6", compileOptions | CompileOptionFlags::SkipOptimise))
.RTVs({DXGI_FORMAT_R32G32B32A32_FLOAT});
noResPSOs[8]->SetName(L"ps_6_6");
noResPSOs[9] =
MakePSO()
.RootSig(sig)
.InputLayout(inputLayout)
.VS(vsblob)
.PS(Compile(common + "\n#define SM_6_6 1\n" + shaderDefines + noResourcesPixel,
"main", "ps_6_6", compileOptions))
.RTVs({DXGI_FORMAT_R32G32B32A32_FLOAT});
noResPSOs[9]->SetName(L"ps_6_6_opt");
}
static_assert(ARRAY_COUNT(psos) == ARRAY_COUNT(noResPSOs), "Mismatched PSO counts");
static const uint32_t texDim = AlignUp(std::max(numResTests, numNoResTests), 64U) * 4;
ID3D12ResourcePtr fltTex = MakeTexture(DXGI_FORMAT_R32G32B32A32_FLOAT, texDim, 4)
.RTV()
@@ -1325,9 +1502,9 @@ void main(int3 inTestIndex : SV_GroupID)
float triWidth = 8.0f / float(texDim);
ConstsA2V triangle[] = {
{Vec3f(-1.0f, -1.0f, triWidth), 0.0f, 1.0f, -1.0f},
{Vec3f(-1.0f, 1.0f, triWidth), 0.0f, 1.0f, -1.0f},
{Vec3f(-1.0f + triWidth, 1.0f, triWidth), 0.0f, 1.0f, -1.0f},
{Vec3f(-1.0f, -1.0f, triWidth), 0.0f, 1.0f, -1.0f, (float)texDim},
{Vec3f(-1.0f, 1.0f, triWidth), 0.0f, 1.0f, -1.0f, (float)texDim},
{Vec3f(-1.0f + triWidth, 1.0f, triWidth), 0.0f, 1.0f, -1.0f, (float)texDim},
};
ID3D12ResourcePtr vb = MakeBuffer().Data(triangle);
@@ -1748,19 +1925,10 @@ void main(int3 inTestIndex : SV_GroupID)
setMarker(cmd, undefined_tests);
float blitOffsets[] = {0.0f, 4.0f, 8.0f, 12.0f, 16.0f, 20.0f, 24.0f, 28.0f, 32.0f, 36.0f};
D3D12_RECT scissors[] = {
{0, 0, (int)texDim, 4}, {0, 4, (int)texDim, 8}, {0, 8, (int)texDim, 12},
{0, 12, (int)texDim, 16}, {0, 16, (int)texDim, 20}, {0, 20, (int)texDim, 24},
{0, 24, (int)texDim, 28}, {0, 28, (int)texDim, 32}, {0, 32, (int)texDim, 36},
{0, 36, (int)texDim, 40},
};
const char *markers[] = {
"sm_5_0", "sm_5_0_opt", "sm_5_1", "sm_5_1_opt", "sm_6_0",
"sm_6_0_opt", "sm_6_2", "sm_6_2_opt", "sm_6_6", "sm_6_6_opt",
};
static_assert(ARRAY_COUNT(blitOffsets) == ARRAY_COUNT(psos), "mismatched array dimension");
static_assert(ARRAY_COUNT(scissors) == ARRAY_COUNT(psos), "mismatched array dimension");
static_assert(ARRAY_COUNT(markers) == ARRAY_COUNT(psos), "mismatched array dimension");
// Clear, draw, and blit to backbuffer - once for each SM 5.0, 5.1, 6.0, 6.2, 6.6
@@ -1774,54 +1942,81 @@ void main(int3 inTestIndex : SV_GroupID)
TEST_ASSERT(countGraphicsPasses <= ARRAY_COUNT(psos), "More graphic passes than psos");
for(size_t i = 0; i < countGraphicsPasses; ++i)
{
OMSetRenderTargets(cmd, {fltRTV}, {});
ClearRenderTargetView(cmd, fltRTV, {0.2f, 0.2f, 0.2f, 1.0f});
float blitOffset = 8.0f * i;
D3D12_RECT scissor = {};
scissor.left = 0;
scissor.top = (int)(8 * i);
scissor.right = (int)texDim;
IASetVertexBuffer(cmd, vb, sizeof(ConstsA2V), 0);
cmd->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
for(size_t j = 0; j < 2; ++j)
{
OMSetRenderTargets(cmd, {fltRTV}, {});
ClearRenderTargetView(cmd, fltRTV, {0.2f, 0.2f, 0.2f, 1.0f});
cmd->SetGraphicsRootSignature(sig);
cmd->SetDescriptorHeaps(1, &m_CBVUAVSRV.GetInterfacePtr());
cmd->SetGraphicsRootDescriptorTable(0, m_CBVUAVSRV->GetGPUDescriptorHandleForHeapStart());
cmd->SetGraphicsRootDescriptorTable(1, m_CBVUAVSRV->GetGPUDescriptorHandleForHeapStart());
cmd->SetGraphicsRootDescriptorTable(2, m_CBVUAVSRV->GetGPUDescriptorHandleForHeapStart());
cmd->SetGraphicsRootDescriptorTable(3, m_CBVUAVSRV->GetGPUDescriptorHandleForHeapStart());
cmd->SetGraphicsRootDescriptorTable(4, m_CBVUAVSRV->GetGPUDescriptorHandleForHeapStart());
cmd->SetGraphicsRootUnorderedAccessView(5, rootDummy->GetGPUVirtualAddress());
cmd->SetGraphicsRootShaderResourceView(6,
rootStruct->GetGPUVirtualAddress() + renderDataSize);
cmd->SetGraphicsRootDescriptorTable(7, m_CBVUAVSRV->GetGPUDescriptorHandleForHeapStart());
IASetVertexBuffer(cmd, vb, sizeof(ConstsA2V), 0);
cmd->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
cmd->SetPipelineState(psos[i]);
cmd->SetGraphicsRootSignature(sig);
cmd->SetDescriptorHeaps(1, &m_CBVUAVSRV.GetInterfacePtr());
cmd->SetGraphicsRootDescriptorTable(0, m_CBVUAVSRV->GetGPUDescriptorHandleForHeapStart());
cmd->SetGraphicsRootDescriptorTable(1, m_CBVUAVSRV->GetGPUDescriptorHandleForHeapStart());
cmd->SetGraphicsRootDescriptorTable(2, m_CBVUAVSRV->GetGPUDescriptorHandleForHeapStart());
cmd->SetGraphicsRootDescriptorTable(3, m_CBVUAVSRV->GetGPUDescriptorHandleForHeapStart());
cmd->SetGraphicsRootDescriptorTable(4, m_CBVUAVSRV->GetGPUDescriptorHandleForHeapStart());
cmd->SetGraphicsRootUnorderedAccessView(5, rootDummy->GetGPUVirtualAddress());
cmd->SetGraphicsRootShaderResourceView(
6, rootStruct->GetGPUVirtualAddress() + renderDataSize);
cmd->SetGraphicsRootDescriptorTable(7, m_CBVUAVSRV->GetGPUDescriptorHandleForHeapStart());
RSSetViewport(cmd, {0.0f, 0.0f, (float)texDim, 4.0f, 0.0f, 1.0f});
RSSetScissorRect(cmd, {0, 0, (int)texDim, 4});
// Add a marker so we can easily locate this draw
std::string markerName = markers[i];
uint32_t numTests = 0;
ID3D12PipelineStatePtr pso = NULL;
if(j == 0)
{
pso = psos[i];
numTests = numResTests;
}
else
{
markerName = "NoResources " + markerName;
pso = noResPSOs[i];
numTests = numNoResTests;
}
cmd->SetPipelineState(pso);
UINT zero[4] = {};
cmd->ClearUnorderedAccessViewUint(uav1gpu, uav1cpu, rawBuf2, zero, 0, NULL);
cmd->ClearUnorderedAccessViewUint(uav2gpu, uav2cpu, structBuf2, zero, 0, NULL);
cmd->ClearUnorderedAccessViewUint(uav3gpu, uav3cpu, rawBuf2, zero, 0, NULL);
RSSetViewport(cmd, {0.0f, 0.0f, (float)texDim, 4.0f, 0.0f, 1.0f});
RSSetScissorRect(cmd, {0, 0, (int)texDim, 4});
// Add a marker so we can easily locate this draw
setMarker(cmd, markers[i]);
cmd->DrawInstanced(3, numTests, 0, 0);
UINT zero[4] = {};
cmd->ClearUnorderedAccessViewUint(uav1gpu, uav1cpu, rawBuf2, zero, 0, NULL);
cmd->ClearUnorderedAccessViewUint(uav2gpu, uav2cpu, structBuf2, zero, 0, NULL);
cmd->ClearUnorderedAccessViewUint(uav3gpu, uav3cpu, rawBuf2, zero, 0, NULL);
ResourceBarrier(cmd, fltTex, D3D12_RESOURCE_STATE_RENDER_TARGET,
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
setMarker(cmd, markerName.c_str());
cmd->DrawInstanced(3, numTests, 0, 0);
OMSetRenderTargets(cmd, {rtv}, {});
RSSetViewport(cmd, {0.0f, 0.0f, (float)screenWidth, (float)screenHeight, 0.0f, 1.0f});
RSSetScissorRect(cmd, scissors[i]);
ResourceBarrier(cmd, fltTex, D3D12_RESOURCE_STATE_RENDER_TARGET,
D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE);
cmd->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
cmd->SetGraphicsRootSignature(blitSig);
cmd->SetPipelineState(blitpso);
cmd->SetGraphicsRoot32BitConstant(0, *(UINT *)&blitOffsets[i], 0);
cmd->SetGraphicsRootDescriptorTable(1, m_CBVUAVSRV->GetGPUDescriptorHandleForHeapStart());
cmd->DrawInstanced(4, 1, 0, 0);
scissor.bottom = scissor.top + 4;
OMSetRenderTargets(cmd, {rtv}, {});
RSSetViewport(cmd, {0.0f, 0.0f, (float)screenWidth, (float)screenHeight, 0.0f, 1.0f});
RSSetScissorRect(cmd, scissor);
ResourceBarrier(cmd, fltTex, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
D3D12_RESOURCE_STATE_RENDER_TARGET);
cmd->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
cmd->SetGraphicsRootSignature(blitSig);
cmd->SetPipelineState(blitpso);
cmd->SetGraphicsRoot32BitConstant(0, *(UINT *)&blitOffset, 0);
cmd->SetGraphicsRootDescriptorTable(1, m_CBVUAVSRV->GetGPUDescriptorHandleForHeapStart());
cmd->DrawInstanced(4, 1, 0, 0);
ResourceBarrier(cmd, fltTex, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE,
D3D12_RESOURCE_STATE_RENDER_TARGET);
scissor.top += 4;
blitOffset += 4.0f;
}
}
// Render MSAA test
+62 -55
View File
@@ -18,69 +18,76 @@ class D3D12_Shader_Debug_Zoo(rdtest.TestCase):
"sm_5_0", "sm_5_1", "sm_6_0", "sm_6_2", "sm_6_6",
"sm_5_0_opt", "sm_5_1_opt", "sm_6_0_opt", "sm_6_2_opt", "sm_6_6_opt",
]
for sm in range(len(shaderModels)):
rdtest.log.begin_section(shaderModels[sm] + " tests")
for j in range(2):
for sm in range(len(shaderModels)):
sectionName = shaderModels[sm] + " tests"
rdtest.log.begin_section(sectionName)
# Jump to the action
test_marker: rd.ActionDescription = self.find_action(shaderModels[sm])
if (test_marker is None):
rdtest.log.print(f"Skipping Graphics tests for {shaderModels[sm]}")
rdtest.log.end_section(shaderModels[sm] + " tests")
continue
action = test_marker.next
self.controller.SetFrameEvent(action.eventId, False)
pipe: rd.PipeState = self.controller.GetPipelineState()
if pipe.GetShaderReflection(rd.ShaderStage.Vertex).debugInfo.debuggable:
# Debug the vertex shader
# Jump to the action
markerName = shaderModels[sm]
instId = 10
trace: rd.ShaderDebugTrace = self.controller.DebugVertex(0, instId, 0, 0)
cycles, variables = self.process_trace(trace)
output = self.find_output_source_var(trace, rd.ShaderBuiltin.Undefined, 3)
debugged = self.evaluate_source_var(output, variables)
self.controller.FreeTrace(trace)
actual = debugged.value.u32v[0]
expected = instId
if not rdtest.value_compare(actual, expected):
failed = True
rdtest.log.error(
f"Vertex shader TRIANGLE output did not match expectation {actual} != {expected}")
if not failed:
rdtest.log.success("Basic VS debugging was successful")
else:
rdtest.log.print(f"Ignoring undebuggable Vertex shader at {action.eventId} for {shaderModels[sm]}.")
if j == 0:
markerName = "NoResources " + markerName
instId = 2
if not pipe.GetShaderReflection(rd.ShaderStage.Pixel).debugInfo.debuggable:
rdtest.log.print(f"Skipping undebuggable Pixel shader at {action.eventId} for {shaderModels[sm]}.")
rdtest.log.end_section(shaderModels[sm] + " tests")
continue
test_marker: rd.ActionDescription = self.find_action(markerName)
if (test_marker is None):
rdtest.log.print(f"Skipping Graphics tests for {sectionName}")
rdtest.log.end_section(sectionName)
continue
action = test_marker.next
self.controller.SetFrameEvent(action.eventId, False)
# Loop over every test
for test in range(action.numInstances):
# Debug the shader
trace: rd.ShaderDebugTrace = self.controller.DebugPixel(4 * test, 0, rd.DebugPixelInputs())
pipe: rd.PipeState = self.controller.GetPipelineState()
cycles, variables = self.process_trace(trace)
output = self.find_output_source_var(trace, rd.ShaderBuiltin.ColorOutput, 0)
debugged = self.evaluate_source_var(output, variables)
self.controller.FreeTrace(trace)
try:
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, 4 * test, 0, debugged.value.f32v[0:4])
except rdtest.TestFailureException as ex:
if test in undefined_tests:
rdtest.log.comment("Undefined test {} did not match. {}".format(test, str(ex)))
else:
rdtest.log.error("Test {} did not match. {}".format(test, str(ex)))
if pipe.GetShaderReflection(rd.ShaderStage.Vertex).debugInfo.debuggable:
# Debug the vertex shader
trace: rd.ShaderDebugTrace = self.controller.DebugVertex(0, instId, 0, 0)
cycles, variables = self.process_trace(trace)
output = self.find_output_source_var(trace, rd.ShaderBuiltin.Undefined, 4)
debugged = self.evaluate_source_var(output, variables)
self.controller.FreeTrace(trace)
actual = debugged.value.u32v[0]
expected = instId
if not rdtest.value_compare(actual, expected):
failed = True
rdtest.log.error(
f"Vertex shader TRIANGLE output did not match expectation {actual} != {expected}")
if not failed:
rdtest.log.success("Basic VS debugging was successful")
else:
rdtest.log.print(f"Ignoring undebuggable Vertex shader at {action.eventId} for {shaderModels[sm]}.")
if not pipe.GetShaderReflection(rd.ShaderStage.Pixel).debugInfo.debuggable:
rdtest.log.print(f"Skipping undebuggable Pixel shader at {action.eventId} for {shaderModels[sm]}.")
rdtest.log.end_section(sectionName)
continue
rdtest.log.success("Test {} matched as expected".format(test))
rdtest.log.end_section(shaderModels[sm] + " tests")
# Loop over every test
for test in range(action.numInstances):
# Debug the shader
trace: rd.ShaderDebugTrace = self.controller.DebugPixel(4 * test, 0, rd.DebugPixelInputs())
cycles, variables = self.process_trace(trace)
output = self.find_output_source_var(trace, rd.ShaderBuiltin.ColorOutput, 0)
debugged = self.evaluate_source_var(output, variables)
self.controller.FreeTrace(trace)
try:
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, 4 * test, 0, debugged.value.f32v[0:4])
except rdtest.TestFailureException as ex:
if test in undefined_tests:
rdtest.log.comment("Undefined test {} did not match. {}".format(test, str(ex)))
else:
rdtest.log.error("Test {} did not match. {}".format(test, str(ex)))
failed = True
continue
rdtest.log.success("Test {} matched as expected".format(test))
rdtest.log.end_section(sectionName)
rdtest.log.begin_section("MSAA tests")
test_marker: rd.ActionDescription = self.find_action("MSAA")