Extended existing shader model coverage to include 6.0, and 6.6

Added Compute shader test for SM 6.0 and SM 6.6
Added very basic vertex shader test to the triangle rendering for each SM
This commit is contained in:
Jake Turner
2024-06-06 17:54:14 +01:00
parent de07e66728
commit 8745c399ad
2 changed files with 261 additions and 60 deletions
+161 -15
View File
@@ -776,6 +776,30 @@ float4 main(v2f IN, uint samp : SV_SampleIndex) : SV_Target0
return float4(x + pos.x, y + pos.y, z + (float)numSamples, w);
}
)EOSHADER";
std::string compute = R"EOSHADER(
cbuffer consts : register(b0)
{
bool boolX;
uint intY;
float floatZ;
double doubleX;
};
RWStructuredBuffer<uint4> bufIn : register(u0);
RWStructuredBuffer<uint4> bufOut : register(u1);
[numthreads(3,2,1)]
void main()
{
bufOut[0].x += bufIn[0].x * (uint)boolX;
bufOut[0].y += bufIn[0].y * (uint)intY;
bufOut[0].z += bufIn[0].z * (uint)floatZ;
bufOut[0].w += bufIn[0].w * (uint)doubleX;
}
)EOSHADER";
int main()
@@ -912,6 +936,24 @@ float4 main(v2f IN, uint samp : SV_SampleIndex) : SV_Target0
.VS(vsblob)
.PS(psblob)
.RTVs({DXGI_FORMAT_R32G32B32A32_FLOAT});
// Recompile with SM 6.0 and SM 6.6
vsblob = Compile(common + vertex, "main", "vs_6_0");
psblob = Compile(common + "\n#define SM_6_0 1\n" + pixel, "main", "ps_6_0");
ID3D12PipelineStatePtr pso_6_0 = MakePSO()
.RootSig(sig)
.InputLayout(inputLayout)
.VS(vsblob)
.PS(psblob)
.RTVs({DXGI_FORMAT_R32G32B32A32_FLOAT});
vsblob = Compile(common + vertex, "main", "vs_6_6");
psblob = Compile(common + "\n#define SM_6_6 1\n" + pixel, "main", "ps_6_6");
ID3D12PipelineStatePtr pso_6_6 = MakePSO()
.RootSig(sig)
.InputLayout(inputLayout)
.VS(vsblob)
.PS(psblob)
.RTVs({DXGI_FORMAT_R32G32B32A32_FLOAT});
static const uint32_t texDim = AlignUp(numTests, 64U) * 4;
@@ -1136,14 +1178,26 @@ float4 main(v2f IN, uint samp : SV_SampleIndex) : SV_Target0
});
ID3D12PipelineStatePtr blitpso = MakePSO().RootSig(blitSig).VS(vsblob).PS(psblob);
vsblob = Compile(vertexSampleVS, "main", "vs_5_0");
psblob = Compile(vertexSamplePS, "main", "ps_5_0");
ID3D12RootSignaturePtr vertexSampleSig = MakeSig(
{
tableParam(D3D12_SHADER_VISIBILITY_VERTEX, D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 0, 0, 1, 8),
},
D3D12_ROOT_SIGNATURE_FLAG_DENY_PIXEL_SHADER_ROOT_ACCESS);
ID3D12PipelineStatePtr vertexSamplePSO = MakePSO().RootSig(vertexSampleSig).VS(vsblob).PS(psblob);
vsblob = Compile(vertexSampleVS, "main", "vs_5_0");
psblob = Compile(vertexSamplePS, "main", "ps_5_0");
ID3D12PipelineStatePtr vertexSamplePSO_5_0 =
MakePSO().RootSig(vertexSampleSig).VS(vsblob).PS(psblob);
vsblob = Compile(vertexSampleVS, "main", "vs_6_0");
psblob = Compile(vertexSamplePS, "main", "ps_6_0");
ID3D12PipelineStatePtr vertexSamplePSO_6_0 =
MakePSO().RootSig(vertexSampleSig).VS(vsblob).PS(psblob);
vsblob = Compile(vertexSampleVS, "main", "vs_6_6");
psblob = Compile(vertexSamplePS, "main", "ps_6_6");
ID3D12PipelineStatePtr vertexSamplePSO_6_6 =
MakePSO().RootSig(vertexSampleSig).VS(vsblob).PS(psblob);
// set the NULL descriptors
UINT inc = dev->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
@@ -1202,6 +1256,56 @@ float4 main(v2f IN, uint samp : SV_SampleIndex) : SV_Target0
ID3D12PipelineStatePtr bannedPSO =
MakePSO().InputLayout().RootSig(bannedSig).VS(vsblob).PS(psblob);
const uint32_t renderDataSize = sizeof(float) * 22;
// Create resources for compute shader
const uint32_t computeDataStart = AlignUp(renderDataSize, 1024U);
ID3D12RootSignaturePtr sigCompute = MakeSig({
uavParam(D3D12_SHADER_VISIBILITY_ALL, 0, 0),
uavParam(D3D12_SHADER_VISIBILITY_ALL, 0, 1),
constParam(D3D12_SHADER_VISIBILITY_ALL, 0, 0, 4),
tableParam(D3D12_SHADER_VISIBILITY_ALL, D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 0, 2, 1, 3),
});
const uint32_t countSMs = 2;
ID3DBlobPtr computeBlobs[countSMs];
ID3D12PipelineStatePtr computePSOs[countSMs];
std::string computeSMs[countSMs] = {"cs_6_0", "cs_6_6"};
for(uint32_t i = 0; i < countSMs; ++i)
{
computeBlobs[i] = Compile(compute, "main", computeSMs[i], false);
computePSOs[i] = MakePSO().RootSig(sigCompute).CS(computeBlobs[i]);
}
const uint32_t uavSize = 1024;
ID3D12ResourcePtr bufIn = MakeBuffer().Size(uavSize).UAV();
ID3D12ResourcePtr bufOut = MakeBuffer().Size(uavSize).UAV();
bufIn->SetName(L"bufIn");
bufOut->SetName(L"bufOut");
D3D12_GPU_DESCRIPTOR_HANDLE bufInGPU =
MakeUAV(bufIn).Format(DXGI_FORMAT_R32G32B32A32_UINT).CreateGPU(computeDataStart);
D3D12_CPU_DESCRIPTOR_HANDLE bufInClearCPU =
MakeUAV(bufIn).Format(DXGI_FORMAT_R32G32B32A32_UINT).CreateClearCPU(computeDataStart);
D3D12_GPU_DESCRIPTOR_HANDLE bufOutGPU =
MakeUAV(bufOut).Format(DXGI_FORMAT_R32G32B32A32_UINT).CreateGPU(computeDataStart + 1);
D3D12_CPU_DESCRIPTOR_HANDLE bufOutClearCPU =
MakeUAV(bufOut).Format(DXGI_FORMAT_R32G32B32A32_UINT).CreateClearCPU(computeDataStart + 1);
D3D12_GPU_VIRTUAL_ADDRESS bufInVA = bufIn->GetGPUVirtualAddress();
D3D12_GPU_VIRTUAL_ADDRESS bufOutVA = bufOut->GetGPUVirtualAddress();
uint32_t bufInInitData[uavSize];
uint32_t bufOutInitData[uavSize];
for(uint32_t i = 0; i < uavSize; ++i)
{
bufInInitData[i] = 111 + i / 4;
bufOutInitData[i] = 222 + i / 4;
}
D3D12_RECT uavClearRect = {};
uavClearRect.right = uavSize;
uavClearRect.bottom = 1;
while(Running())
{
ID3D12GraphicsCommandListPtr cmd = GetCommandBuffer();
@@ -1215,13 +1319,18 @@ float4 main(v2f IN, uint samp : SV_SampleIndex) : SV_Target0
setMarker(cmd, undefined_tests);
ID3D12PipelineStatePtr psos[2] = {pso_5_0, pso_5_1};
float blitOffsets[2] = {0.0f, 4.0f};
D3D12_RECT scissors[2] = {{0, 0, (int)texDim, 4}, {0, 4, (int)texDim, 8}};
const char *markers[2] = {"sm_5_0", "sm_5_1"};
ID3D12PipelineStatePtr psos[4] = {pso_5_0, pso_5_1, pso_6_0, pso_6_6};
float blitOffsets[4] = {0.0f, 4.0f, 8.0f, 12.0f};
D3D12_RECT scissors[4] = {
{0, 0, (int)texDim, 4},
{0, 4, (int)texDim, 8},
{0, 8, (int)texDim, 12},
{0, 12, (int)texDim, 16},
};
const char *markers[4] = {"sm_5_0", "sm_5_1", "sm_6_0", "sm_6_6"};
// Clear, draw, and blit to backbuffer twice - once for SM 5.0 and again for SM 5.1
for(int i = 0; i < 2; ++i)
// Clear, draw, and blit to backbuffer twice - once for each SM 5.0, 5.1, 6.0, 6.6
for(int i = 0; i < ARRAY_COUNT(psos); ++i)
{
OMSetRenderTargets(cmd, {fltRTV}, {});
ClearRenderTargetView(cmd, fltRTV, {0.2f, 0.2f, 0.2f, 1.0f});
@@ -1237,8 +1346,8 @@ float4 main(v2f IN, uint samp : SV_SampleIndex) : SV_Target0
cmd->SetGraphicsRootDescriptorTable(3, m_CBVUAVSRV->GetGPUDescriptorHandleForHeapStart());
cmd->SetGraphicsRootDescriptorTable(4, m_CBVUAVSRV->GetGPUDescriptorHandleForHeapStart());
cmd->SetGraphicsRootUnorderedAccessView(5, rootDummy->GetGPUVirtualAddress());
cmd->SetGraphicsRootShaderResourceView(
6, rootStruct->GetGPUVirtualAddress() + sizeof(float) * 22);
cmd->SetGraphicsRootShaderResourceView(6,
rootStruct->GetGPUVirtualAddress() + renderDataSize);
cmd->SetPipelineState(psos[i]);
@@ -1298,10 +1407,22 @@ float4 main(v2f IN, uint samp : SV_SampleIndex) : SV_Target0
cmd->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
cmd->SetGraphicsRootSignature(vertexSampleSig);
cmd->SetPipelineState(vertexSamplePSO);
cmd->SetGraphicsRootDescriptorTable(0, m_CBVUAVSRV->GetGPUDescriptorHandleForHeapStart());
setMarker(cmd, "VertexSample");
cmd->DrawInstanced(4, 1, 0, 0);
ID3D12PipelineStatePtr vertexSamplePSOs[3] = {vertexSamplePSO_5_0, vertexSamplePSO_6_0,
vertexSamplePSO_6_6};
const char *vs_markers[3] = {
"VertexSample sm_5_0",
"VertexSample sm_6_0",
"VertexSample sm_6_6",
};
for(int i = 0; i < ARRAY_COUNT(vertexSamplePSOs); ++i)
{
cmd->SetPipelineState(vertexSamplePSOs[i]);
cmd->SetGraphicsRootDescriptorTable(0, m_CBVUAVSRV->GetGPUDescriptorHandleForHeapStart());
setMarker(cmd, vs_markers[i]);
cmd->DrawInstanced(4, 1, 0, 0);
}
setMarker(cmd, "BannedSig");
RSSetViewport(cmd, {60.0f, 60.0f, 10.0f, 10.0f, 0.0f, 1.0f});
@@ -1315,6 +1436,31 @@ float4 main(v2f IN, uint samp : SV_SampleIndex) : SV_Target0
FinishUsingBackbuffer(cmd, D3D12_RESOURCE_STATE_RENDER_TARGET);
pushMarker(cmd, "Compute");
for(uint32_t i = 0; i < countSMs; ++i)
{
cmd->SetDescriptorHeaps(1, &m_CBVUAVSRV.GetInterfacePtr());
cmd->ClearUnorderedAccessViewUint(bufInGPU, bufInClearCPU, bufIn, bufInInitData, 1,
&uavClearRect);
cmd->ClearUnorderedAccessViewUint(bufOutGPU, bufOutClearCPU, bufOut, bufOutInitData, 1,
&uavClearRect);
cmd->SetComputeRootSignature(sigCompute);
cmd->SetComputeRootUnorderedAccessView(0, bufInVA);
cmd->SetComputeRootUnorderedAccessView(1, bufOutVA);
cmd->SetComputeRoot32BitConstant(2, 5, 0);
cmd->SetComputeRoot32BitConstant(2, 6, 1);
cmd->SetComputeRoot32BitConstant(2, 7, 2);
cmd->SetComputeRoot32BitConstant(2, 8, 3);
cmd->SetComputeRootDescriptorTable(3, m_CBVUAVSRV->GetGPUDescriptorHandleForHeapStart());
cmd->SetPipelineState(computePSOs[i]);
setMarker(cmd, computeSMs[i]);
cmd->Dispatch(3, 2, 1);
}
popMarker(cmd);
cmd->Close();
Submit({cmd});
Present();
+100 -45
View File
@@ -15,7 +15,7 @@ class D3D12_Shader_Debug_Zoo(rdtest.TestCase):
failed = False
shaderModels = ["sm_5_0", "sm_5_1"]
shaderModels = ["sm_5_0", "sm_5_1", "sm_6_0", "sm_6_6"]
for sm in range(len(shaderModels)):
rdtest.log.begin_section(shaderModels[sm] + " tests")
@@ -26,9 +26,28 @@ class D3D12_Shader_Debug_Zoo(rdtest.TestCase):
pipe: rd.PipeState = self.controller.GetPipelineState()
if pipe.GetShaderReflection(rd.ShaderStage.Vertex).debugInfo.debuggable:
# Debug the vertex shader
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)
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}.")
if not pipe.GetShaderReflection(rd.ShaderStage.Pixel).debugInfo.debuggable:
rdtest.log.print("Skipping undebuggable shader at {}.".format(action.eventId))
return
rdtest.log.print("Skipping undebuggable Pixel shader at {}.".format(action.eventId))
rdtest.log.end_section(shaderModels[sm] + " tests")
continue
# Loop over every test
for test in range(action.numInstances):
@@ -90,50 +109,57 @@ class D3D12_Shader_Debug_Zoo(rdtest.TestCase):
rdtest.log.end_section("MSAA tests")
test_marker: rd.ActionDescription = self.find_action("VertexSample")
action = test_marker.next
self.controller.SetFrameEvent(action.eventId, False)
pipe: rd.PipeState = self.controller.GetPipelineState()
rdtest.log.begin_section("VertexSample tests")
shaderModels = ["sm_5_0", "sm_6_0", "sm_6_6"]
for sm in range(len(shaderModels)):
test_marker: rd.ActionDescription = self.find_action("VertexSample " + shaderModels[sm])
action = test_marker.next
self.controller.SetFrameEvent(action.eventId, False)
pipe: rd.PipeState = self.controller.GetPipelineState()
# Debug the vertex shader
trace: rd.ShaderDebugTrace = self.controller.DebugVertex(0, 0, 0, 0)
if pipe.GetShaderReflection(rd.ShaderStage.Vertex).debugInfo.debuggable:
# Debug the vertex shader
trace: rd.ShaderDebugTrace = self.controller.DebugVertex(0, 0, 0, 0)
cycles, variables = self.process_trace(trace)
output = self.find_output_source_var(trace, rd.ShaderBuiltin.Undefined, 1)
debugged = self.evaluate_source_var(output, variables)
cycles, variables = self.process_trace(trace)
actual = debugged.value.f32v[0:4]
expected = [0.3, 0.5, 0.8, 1.0]
if not rdtest.value_compare(actual, expected):
failed = True
rdtest.log.error(
f"{shaderModels[sm]} Vertex shader color output did not match expectation {actual} != {expected}")
output = self.find_output_source_var(trace, rd.ShaderBuiltin.Undefined, 1)
if not failed:
rdtest.log.success(shaderModels[sm] + " VertexSample VS was debugged correctly")
else:
rdtest.log.print("Skipping undebuggable Vertex shader at {}.".format(action.eventId))
debugged = self.evaluate_source_var(output, variables)
if pipe.GetShaderReflection(rd.ShaderStage.Pixel).debugInfo.debuggable:
# Debug the pixel shader
inputs = rd.DebugPixelInputs()
inputs.sample = 0
trace: rd.ShaderDebugTrace = self.controller.DebugPixel(51, 51, inputs)
cycles, variables = self.process_trace(trace)
output = self.find_output_source_var(trace, rd.ShaderBuiltin.ColorOutput, 0)
debugged = self.evaluate_source_var(output, variables)
if not rdtest.value_compare(debugged.value.f32v[0:4], [0.3, 0.5, 0.8, 1.0]):
failed = True
rdtest.log.error(
"Vertex shader color output did not match expectation ({}). {}".format(str(debugged.value.f32v[0:4]),
str([0.3, 0.5, 0.8, 1.0])))
# Validate the debug output result
try:
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, 51, 51, debugged.value.f32v[0:4])
except rdtest.TestFailureException as ex:
failed = True
rdtest.log.error("Vertex sample pixel shader output did not match. {}".format(str(ex)))
rdtest.log.success("VertexSample VS was debugged correctly")
rdtest.log.success("VertexSample PS was debugged correctly")
else:
rdtest.log.print("Skipping undebuggable Pixel shader at {}.".format(action.eventId))
# Debug the pixel shader
inputs = rd.DebugPixelInputs()
inputs.sample = 0
trace: rd.ShaderDebugTrace = self.controller.DebugPixel(51, 51, inputs)
if failed:
raise rdtest.TestFailureException("Some tests were not as expected")
cycles, variables = self.process_trace(trace)
output = self.find_output_source_var(trace, rd.ShaderBuiltin.ColorOutput, 0)
debugged = self.evaluate_source_var(output, variables)
# Validate the debug output result
try:
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, 51, 51, debugged.value.f32v[0:4])
except rdtest.TestFailureException as ex:
failed = True
rdtest.log.error("Vertex sample pixel shader output did not match. {}".format(str(ex)))
rdtest.log.success("VertexSample PS was debugged correctly")
if failed:
raise rdtest.TestFailureException("Some tests were not as expected")
rdtest.log.end_section("VertexSample tests")
test_marker: rd.ActionDescription = self.find_action("Banned")
action = test_marker.next
@@ -149,14 +175,14 @@ class D3D12_Shader_Debug_Zoo(rdtest.TestCase):
debugged = self.evaluate_source_var(output, variables)
if not rdtest.value_compare(debugged.value.f32v[0:4], [-0.5, -0.5, 0.0, 1.0]):
actual = debugged.value.f32v[0:4]
expected = [-0.5, -0.5, 0.0, 1.0]
if not rdtest.value_compare(actual, expected):
failed = True
rdtest.log.error(
"Banned signature vertex shader position did not match expectation ({}). {}".format(
str(debugged.value.f32v[0:4]),
str([-0.5, -0.5, 0.0, 1.0])))
rdtest.log.error(f"Banned signature vertex shader position did not match expectation {actual} != {expected}")
rdtest.log.success("Banned signature VS was debugged correctly")
if not failed:
rdtest.log.success("Banned signature VS was debugged correctly")
# Debug the pixel shader
inputs = rd.DebugPixelInputs()
@@ -178,6 +204,35 @@ class D3D12_Shader_Debug_Zoo(rdtest.TestCase):
rdtest.log.success("Banned signature PS was debugged correctly")
csShaderModels = ["cs_6_0", "cs_6_6"]
for sm in range(len(csShaderModels)):
test = csShaderModels[sm]
section = test + " tests"
rdtest.log.begin_section(section)
# Jump to the action
test_marker: rd.ActionDescription = self.find_action(test)
action = test_marker.next
self.controller.SetFrameEvent(action.eventId, False)
pipe: rd.PipeState = self.controller.GetPipelineState()
if not pipe.GetShaderReflection(rd.ShaderStage.Compute).debugInfo.debuggable:
rdtest.log.print("Skipping undebuggable shader at {}.".format(action.eventId))
continue
# Debug the shader
trace: rd.ShaderDebugTrace = self.controller.DebugThread([0,0,0], [0,0,0])
cycles, variables = self.process_trace(trace)
# Check for non-zero cycles
# TODO: Check source variables have expected values (bit like output variables in Vertex and Pixel Shaders)
self.controller.FreeTrace(trace)
if cycles == 0:
rdtest.log.error("Shader debug cycle count was zero")
failed = True
continue
rdtest.log.success("Test {} matched as expected".format(test))
rdtest.log.end_section(section)
if failed:
raise rdtest.TestFailureException("Some tests were not as expected")