Use context helpers for pixel debugging

This commit is contained in:
baldurk
2026-09-11 21:17:17 +01:00
parent 3452ba8ffd
commit ca682d6d34
26 changed files with 458 additions and 530 deletions
+23 -26
View File
@@ -120,38 +120,35 @@ class Buffer_Truncation(rdtest.TestCase):
if not rdtest.value_compare(outcol.value.f32v[0:4], [0.0, 0.0, 0.0, 0.0]):
raise rdtest.TestFailureException(f"expected outcol to be 0s, but got {outcol.value.f32v[0:4]}")
x, y = self.get_view_centre()
# Debug the shader
trace = self.controller.DebugPixel(
int(pipe.GetViewport(0).width / 2),
int(pipe.GetViewport(0).height / 2),
rd.DebugPixelInputs(),
)
with self.debug_pixel(x, y, rd.DebugPixelInputs()) as debug:
cycles, variables = self.process_trace(debug.trace)
cycles, variables = self.process_trace(trace)
cbuf_sourceVars = [s for s in debug.trace.sourceVars if s.variables[0].type == rd.DebugVariableType.Constant and s.rows > 0]
cbuf_sourceVars = [s for s in trace.sourceVars if s.variables[0].type == rd.DebugVariableType.Constant and s.rows > 0]
# Vulkan style, one source var for the cbuffer
if len(cbuf_sourceVars) == 1:
debugged_cb = debug.trace.constantBlocks[0]
# Vulkan style, one source var for the cbuffer
if len(cbuf_sourceVars) == 1:
debugged_cb = trace.constantBlocks[0]
assert debugged_cb.members[0].name == 'padding'
assert debugged_cb.members[1].name == 'outcol'
assert debugged_cb.members[0].name == 'padding'
assert debugged_cb.members[1].name == 'outcol'
if not rdtest.value_compare(debugged_cb.members[1].value.f32v[0:4], [0.0, 0.0, 0.0, 0.0]):
raise rdtest.TestFailureException(f"expected outcol to be 0s, but got {debugged_cb.members[1].value.f32v[0:4]}")
# D3D style, one source var for each member mapping to a register
elif len(cbuf_sourceVars) == 17:
debugged_cb = debug.trace.constantBlocks[0].members[16]
if not rdtest.value_compare(debugged_cb.members[1].value.f32v[0:4], [0.0, 0.0, 0.0, 0.0]):
raise rdtest.TestFailureException(f"expected outcol to be 0s, but got {debugged_cb.members[1].value.f32v[0:4]}")
# D3D style, one source var for each member mapping to a register
elif len(cbuf_sourceVars) == 17:
debugged_cb = trace.constantBlocks[0].members[16]
assert all(['consts.padding[' in c.name for c in cbuf_sourceVars[0:16]])
assert cbuf_sourceVars[16].name == 'consts.outcol'
assert all(['consts.padding[' in c.name for c in cbuf_sourceVars[0:16]])
assert cbuf_sourceVars[16].name == 'consts.outcol'
assert cbuf_sourceVars[16].variables[0].name == 'cb0[16]' or cbuf_sourceVars[16].variables[0].name == 'consts[16]'
assert cbuf_sourceVars[16].variables[0].name == 'cb0[16]' or cbuf_sourceVars[16].variables[0].name == 'consts[16]'
if not rdtest.value_compare(debugged_cb.value.f32v[0:4], [0.0, 0.0, 0.0, 0.0]):
raise rdtest.TestFailureException(f"expected outcol to be 0s, but got {debugged_cb.members[1].value.f32v[0:4]}")
else:
raise rdtest.TestFailureException(f"Unexpected number of constant buffer source vars {len(cbuf_sourceVars)}")
if not rdtest.value_compare(debugged_cb.value.f32v[0:4], [0.0, 0.0, 0.0, 0.0]):
raise rdtest.TestFailureException(f"expected outcol to be 0s, but got {debugged_cb.members[1].value.f32v[0:4]}")
else:
raise rdtest.TestFailureException(f"Unexpected number of constant buffer source vars {len(cbuf_sourceVars)}")
rdtest.log.success("CBuffer value was truncated as expected")
rdtest.log.success("CBuffer value was truncated as expected")
+10 -14
View File
@@ -179,24 +179,20 @@ class Subgroup_Zoo(rdtest.TestCase):
inputs.sample = 0
inputs.primitive = rd.ReplayController.NoPreference
inputs.view = view
trace = self.controller.DebugPixel(x, y, inputs)
with self.debug_pixel(x, y, inputs) as debug:
_, variables = self.process_trace(debug.trace)
_, variables = self.process_trace(trace)
output_sourcevar = self.find_output_source_var(
debug.trace, rd.ShaderBuiltin.ColorOutput, 0)
output_sourcevar = self.find_output_source_var(
trace, rd.ShaderBuiltin.ColorOutput, 0)
debugged = self.evaluate_source_var(output_sourcevar, variables)
debugged = self.evaluate_source_var(
output_sourcevar, variables)
debuggedValue = list(debugged.value.f32v[0:4])
self.controller.FreeTrace(trace)
debuggedValue = list(debugged.value.f32v[0:4])
if not rdtest.value_compare(real, debuggedValue, eps=5.0E-06):
rdtest.log.error(
f"Test {idx} at {action.eventId} debugged pixel value {debuggedValue} at {x},{y} in {view} does not match output {real}")
failed = True
if not rdtest.value_compare(real, debuggedValue, eps=5.0E-06):
rdtest.log.error(
f"Test {idx} at {action.eventId} debugged pixel value {debuggedValue} at {x},{y} in {view} does not match output {real}")
failed = True
overallFailed |= failed
if not failed:
+3 -3
View File
@@ -366,12 +366,12 @@ class Texture_Zoo():
# in the test captures pick the output texture, it should be identical to the
# (0,0) pixel in slice 0, mip 0, sample 0
view = pipe.GetViewport(0)
x, y = self.test.get_view_centre()
val = self.pick(
pipe.GetOutputTargets()[0].resource,
int(view.x + view.width / 2),
int(view.y + view.height / 2),
x,
y,
rd.Subresource(),
rd.CompType.Typeless,
)
+22 -14
View File
@@ -188,7 +188,7 @@ class PixelDebugContext(ScopedDebugContext):
def get_trace(self):
return self.test.controller.DebugPixel(self.x, self.y, self.inputs)
class ComputeDebugContext(ScopedDebugContext):
def __init__(self, test: TestCase, group: Tuple[int,int,int], thread: Tuple[int,int,int]):
self.test = test
@@ -199,7 +199,7 @@ class ComputeDebugContext(ScopedDebugContext):
def get_trace(self):
return self.test.controller.DebugThread(self.group, self.thread)
class HistoryContext(ScopedContext):
def __init__(self, test: TestCase, tex: rd.ResourceId, x: int, y: int, sub: rd.Subresource, cast: rd.CompType):
self.tex = tex
@@ -787,6 +787,13 @@ class TestCase:
return last_action
def get_view_centre(self):
pipe = self.controller.GetPipelineState()
vp = pipe.GetViewport(0)
return (int(vp.x + vp.width * 0.5), int(vp.y + vp.height * 0.5))
def check_final_backbuffer(self):
img_path = util.get_tmp_path('backbuffer.png')
ref_path = self.get_ref_path('backbuffer.png')
@@ -1172,23 +1179,24 @@ class TestCase:
log.success("Recompressed and re-imported capture files are identical")
def check_debug_pixel(self, x: int, y: int):
def check_debug_pixel(self, x = -1, y = -1):
pipe = self.controller.GetPipelineState()
if x < 0 or y < 0:
x, y = self.get_view_centre()
# Debug the shader
trace = self.controller.DebugPixel(x, y, rd.DebugPixelInputs())
with self.debug_pixel(x, y, rd.DebugPixelInputs()) as debug:
_, variables = self.process_trace(debug.trace)
output = self.find_output_source_var(debug.trace, rd.ShaderBuiltin.ColorOutput, 0)
debugged = self.evaluate_source_var(output, variables)
_, 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, x, y, debugged.value.f32v[0:4])
except TestFailureException as ex:
raise TestFailureException(f"Pixel shader did not debug correctly at {x},{y}. {ex}")
try:
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, x, y, debugged.value.f32v[0:4])
except TestFailureException as ex:
raise TestFailureException(f"Pixel shader did not debug correctly at {x},{y}. {ex}")
log.success(f"Pixel shader debugging at {x},{y} was successful")
log.success(f"Pixel shader debugging at {x},{y} was successful")
def decode_task_payload(self, controller: rd.ReplayController, mesh: rd.MeshFormat, payload: rd.ConstantBlock, task: int = 0):
begin = mesh.vertexByteOffset + mesh.vertexByteStride * task
+27 -32
View File
@@ -34,51 +34,46 @@ class D3D11_CBuffer_Zoo(rdtest.TestCase):
rdtest.log.success("CBuffer variables are as expected")
trace = self.controller.DebugPixel(
int(pipe.GetViewport(0).width / 2.0),
int(pipe.GetViewport(0).height / 2.0),
rd.DebugPixelInputs(),
)
x, y = self.get_view_centre()
debugVars: Dict[str, rd.ShaderVariable] = dict()
with self.debug_pixel(x, y, rd.DebugPixelInputs()) as debug:
debugVars: Dict[str, rd.ShaderVariable] = dict()
for base in trace.constantBlocks:
for var in base.members:
debugVars[base.name + var.name] = var
for base in debug.trace.constantBlocks:
for var in base.members:
debugVars[base.name + var.name] = var
cbufferVars: List[rd.ShaderVariable] = []
cbufferVars: List[rd.ShaderVariable] = []
for sourceVar in trace.sourceVars:
if sourceVar.variables[0].name not in debugVars.keys():
continue
for sourceVar in debug.trace.sourceVars:
if sourceVar.variables[0].name not in debugVars.keys():
continue
eval = self.evaluate_source_var(sourceVar, debugVars)
cbufferVars.append(eval)
eval = self.evaluate_source_var(sourceVar, debugVars)
cbufferVars.append(eval)
cbufferVars = self.combine_source_vars(cbufferVars)
cbufferVars = self.combine_source_vars(cbufferVars)
assert len(cbufferVars) == 2
assert cbufferVars[0].name == 'consts'
assert cbufferVars[1].name == 'packed_consts'
var_check = rdtest.ConstantBufferChecker(cbufferVars[0].members)
packed_check = rdtest.ConstantBufferChecker(cbufferVars[1].members)
self.check_cbuffer(var_check, packed_check)
assert len(cbufferVars) == 2
assert cbufferVars[0].name == 'consts'
assert cbufferVars[1].name == 'packed_consts'
var_check = rdtest.ConstantBufferChecker(cbufferVars[0].members)
packed_check = rdtest.ConstantBufferChecker(cbufferVars[1].members)
self.check_cbuffer(var_check, packed_check)
rdtest.log.success("Debugged CBuffer variables are as expected")
rdtest.log.success("Debugged CBuffer variables are as expected")
cycles, variables = self.process_trace(trace)
cycles, variables = self.process_trace(debug.trace)
output = self.find_output_source_var(trace, rd.ShaderBuiltin.ColorOutput, 0)
output = self.find_output_source_var(debug.trace, rd.ShaderBuiltin.ColorOutput, 0)
debugged = self.evaluate_source_var(output, variables)
debugged = self.evaluate_source_var(output, variables)
if not rdtest.util.value_compare(debugged.value.f32v[0:4], [542.1, 543.0, 544.0, 545.0]):
raise rdtest.TestFailureException(
f"Debugged output {debugged.value.f32v[0:4]} did not match expected {[542.1, 543.0, 544.0, 545.0]}")
if not rdtest.util.value_compare(debugged.value.f32v[0:4], [542.1, 543.0, 544.0, 545.0]):
raise rdtest.TestFailureException(
f"Debugged output {debugged.value.f32v[0:4]} did not match expected {[542.1, 543.0, 544.0, 545.0]}")
rdtest.log.success("Debugged output matched as expected")
self.controller.FreeTrace(trace)
rdtest.log.success("Debugged output matched as expected")
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, 0.5, 0.5, [542.1, 543.0, 544.0, 545.0])
+4 -5
View File
@@ -16,8 +16,6 @@ class D3D11_Parameter_Zoo(rdtest.TestCase):
pipe = self.controller.GetPipelineState()
v = pipe.GetViewport(0)
stage = rd.ShaderStage.Pixel
cbuf = pipe.GetConstantBlock(stage, 0, 0).descriptor
@@ -25,7 +23,7 @@ class D3D11_Parameter_Zoo(rdtest.TestCase):
self.check_triangle()
self.check_debug_pixel(int(0.5 * v.width), int(0.5 * v.height))
self.check_debug_pixel()
var_check = rdtest.ConstantBufferChecker(
self.controller.GetCBufferVariableContents(pipe.GetGraphicsPipelineObject(),
@@ -49,8 +47,9 @@ class D3D11_Parameter_Zoo(rdtest.TestCase):
overlay_id = out.GetDebugOverlayTexID()
self.check_pixel_value(overlay_id, int(0.5 * v.width), int(0.5 * v.height), [0.8, 0.1, 0.8, 1.0],
eps=1.0 / 256.0)
x, y = self.get_view_centre()
self.check_pixel_value(overlay_id, x, y, [0.8, 0.1, 0.8, 1.0], eps=1.0 / 256.0)
expected_markers = [
"Features1: D3D11_TILED_RESOURCES_NOT_SUPPORTED",
+25 -28
View File
@@ -20,39 +20,36 @@ class D3D11_PrimitiveID(rdtest.TestCase):
pixel_inputs = rd.DebugPixelInputs()
pixel_inputs.primitive = prim
trace = self.controller.DebugPixel(x, y, pixel_inputs)
with self.debug_pixel(x, y, pixel_inputs) as debug:
_, variables = self.process_trace(debug.trace)
_, variables = self.process_trace(trace)
# Find the SV_PrimitiveID variable
if not self.has_input_source_var(debug.trace, rd.ShaderBuiltin.PrimitiveIndex):
# If we didn't find it, then we should be expecting a 0
if len(expected_prim) != 1 or expected_prim[0] != 0:
rdtest.log.error(f"Expected prim {expected_prim!s} at {x},{y} did not match actual prim {prim}.")
return False
else:
primInput = self.find_input_source_var(debug.trace, rd.ShaderBuiltin.PrimitiveIndex)
# Find the SV_PrimitiveID variable
if not self.has_input_source_var(trace, rd.ShaderBuiltin.PrimitiveIndex):
# If we didn't find it, then we should be expecting a 0
if len(expected_prim) != 1 or expected_prim[0] != 0:
rdtest.log.error(f"Expected prim {expected_prim!s} at {x},{y} did not match actual prim {prim}.")
return False
else:
primInput = self.find_input_source_var(trace, rd.ShaderBuiltin.PrimitiveIndex)
# Look up the matching register in the inputs, and see if the expected value matches
inputs = list(debug.trace.inputs)
primValue = [var for var in inputs if var.name == primInput.variables[0].name][0]
if primValue.value.u32v[0] not in expected_prim:
rdtest.log.error(f"Expected prim {expected_prim!s} at {x},{y} did not match actual prim {primValue.value.u32v[0]}.")
return False
# Look up the matching register in the inputs, and see if the expected value matches
inputs = list(trace.inputs)
primValue = [var for var in inputs if var.name == primInput.variables[0].name][0]
if primValue.value.u32v[0] not in expected_prim:
rdtest.log.error(f"Expected prim {expected_prim!s} at {x},{y} did not match actual prim {primValue.value.u32v[0]}.")
return False
# Compare shader debug output against an expected value instead of the RT's output,
# since we're testing overlapping primitives in a single action
if expected_output is not None:
output = self.find_output_source_var(debug.trace, rd.ShaderBuiltin.ColorOutput, 0)
# Compare shader debug output against an expected value instead of the RT's output,
# since we're testing overlapping primitives in a single action
if expected_output is not None:
output = self.find_output_source_var(trace, rd.ShaderBuiltin.ColorOutput, 0)
debugged = self.evaluate_source_var(output, variables)
if list(debugged.value.f32v[0:4]) != expected_output:
rdtest.log.error(f"Expected value {expected_output} at {x},{y} did not match actual {debugged.value.f32v[0:4]}.")
return False
debugged = self.evaluate_source_var(output, variables)
if list(debugged.value.f32v[0:4]) != expected_output:
rdtest.log.error(f"Expected value {expected_output} at {x},{y} did not match actual {debugged.value.f32v[0:4]}.")
return False
self.controller.FreeTrace(trace)
rdtest.log.success(f"Test at {x},{y} matched as expected")
rdtest.log.success(f"Test at {x},{y} matched as expected")
return True
def check_capture(self):
+40 -47
View File
@@ -25,27 +25,24 @@ class D3D11_Shader_Debug_Zoo(rdtest.TestCase):
rdtest.log.begin_section(name)
for test in range(action.numInstances):
# Debug the shader
trace = self.controller.DebugPixel(4 * test, 4 * idx, rd.DebugPixelInputs())
with self.debug_pixel(4 * test, 4 * idx, rd.DebugPixelInputs()) as debug:
cycles, variables = self.process_trace(debug.trace)
cycles, variables = self.process_trace(trace)
output = self.find_output_source_var(debug.trace, rd.ShaderBuiltin.ColorOutput, 0)
output = self.find_output_source_var(trace, rd.ShaderBuiltin.ColorOutput, 0)
debugged = self.evaluate_source_var(output, variables)
debugged = self.evaluate_source_var(output, variables)
try:
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, 4 * test, 4 * idx, debugged.value.f32v[0:4])
except rdtest.TestFailureException as ex:
if test in undefined_tests:
rdtest.log.comment(f"Undefined test {test} did not match. {ex!s}")
else:
rdtest.log.error(f"Test {test} did not match. {ex!s}")
failed = True
continue
try:
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, 4 * test, 4 * idx, debugged.value.f32v[0:4])
except rdtest.TestFailureException as ex:
if test in undefined_tests:
rdtest.log.comment(f"Undefined test {test} did not match. {ex!s}")
else:
rdtest.log.error(f"Test {test} did not match. {ex!s}")
failed = True
continue
finally:
self.controller.FreeTrace(trace)
rdtest.log.success(f"Test {test} matched as expected")
rdtest.log.success(f"Test {test} matched as expected")
rdtest.log.end_section(name)
rdtest.log.begin_section("Flow tests")
@@ -54,23 +51,20 @@ class D3D11_Shader_Debug_Zoo(rdtest.TestCase):
pipe = self.controller.GetPipelineState()
# Debug the shader
trace = self.controller.DebugPixel(0, 8, rd.DebugPixelInputs())
with self.debug_pixel(0, 8, rd.DebugPixelInputs()) as debug:
cycles, variables = self.process_trace(debug.trace)
cycles, variables = self.process_trace(trace)
output = self.find_output_source_var(debug.trace, rd.ShaderBuiltin.ColorOutput, 0)
output = self.find_output_source_var(trace, rd.ShaderBuiltin.ColorOutput, 0)
debugged = self.evaluate_source_var(output, variables)
debugged = self.evaluate_source_var(output, variables)
try:
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, 0, 8, debugged.value.f32v[0:4])
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, 0, 8, [9.0, 66.0, 4.0, 18.0])
except rdtest.TestFailureException as ex:
raise rdtest.TestFailureException(f"Flow test did not match. {ex!s}")
try:
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, 0, 8, debugged.value.f32v[0:4])
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, 0, 8, [9.0, 66.0, 4.0, 18.0])
except rdtest.TestFailureException as ex:
raise rdtest.TestFailureException(f"Flow test did not match. {ex!s}")
finally:
self.controller.FreeTrace(trace)
rdtest.log.success("Flow test matched as expected")
rdtest.log.success("Flow test matched as expected")
rdtest.log.end_section("Flow tests")
@@ -83,27 +77,26 @@ class D3D11_Shader_Debug_Zoo(rdtest.TestCase):
# Debug the shader
inputs = rd.DebugPixelInputs()
inputs.sample = test
trace = self.controller.DebugPixel(x, y, inputs)
with self.debug_pixel(x, y, inputs) as debug:
# Validate that the correct sample index was debugged
sampRegister = self.find_input_source_var(debug.trace, rd.ShaderBuiltin.MSAASampleIndex)
sampInput = [var for var in debug.trace.inputs if var.name == sampRegister.variables[0].name][0]
if sampInput.value.u32v[0] != test:
rdtest.log.error(f"Test {test} did not pick the correct sample.")
# Validate that the correct sample index was debugged
sampRegister = self.find_input_source_var(trace, rd.ShaderBuiltin.MSAASampleIndex)
sampInput = [var for var in trace.inputs if var.name == sampRegister.variables[0].name][0]
if sampInput.value.u32v[0] != test:
rdtest.log.error(f"Test {test} did not pick the correct sample.")
cycles, variables = self.process_trace(debug.trace)
cycles, variables = self.process_trace(trace)
output = self.find_output_source_var(debug.trace, rd.ShaderBuiltin.ColorOutput, 0)
output = self.find_output_source_var(trace, rd.ShaderBuiltin.ColorOutput, 0)
debugged = self.evaluate_source_var(output, variables)
debugged = self.evaluate_source_var(output, variables)
# Validate the debug output result
try:
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, x, y, debugged.value.f32v[0:4], sub=rd.Subresource(0, 0, test))
except rdtest.TestFailureException as ex:
failed = True
rdtest.log.error(f"Test {test} did not match. {ex!s}")
continue
# Validate the debug output result
try:
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, x, y, debugged.value.f32v[0:4], sub=rd.Subresource(0, 0, test))
except rdtest.TestFailureException as ex:
failed = True
rdtest.log.error(f"Test {test} did not match. {ex!s}")
continue
rdtest.log.end_section("MSAA tests")
@@ -18,24 +18,21 @@ class D3D11_Shader_Linkage_Zoo(rdtest.TestCase):
pipe = self.controller.GetPipelineState()
# Debug the shader
trace = self.controller.DebugPixel(200, 150, rd.DebugPixelInputs())
with self.debug_pixel(200, 150, rd.DebugPixelInputs()) as debug:
cycles, variables = self.process_trace(debug.trace)
cycles, variables = self.process_trace(trace)
output = self.find_output_source_var(debug.trace, rd.ShaderBuiltin.ColorOutput, 0)
output = self.find_output_source_var(trace, rd.ShaderBuiltin.ColorOutput, 0)
debugged = self.evaluate_source_var(output, variables)
debugged = self.evaluate_source_var(output, variables)
try:
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, 200, 150, debugged.value.f32v[0:4])
except rdtest.TestFailureException as ex:
failed = True
rdtest.log.error(f"Test {event_name} did not match. {ex!s}")
continue
try:
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, 200, 150, debugged.value.f32v[0:4])
except rdtest.TestFailureException as ex:
failed = True
rdtest.log.error(f"Test {event_name} did not match. {ex!s}")
continue
finally:
self.controller.FreeTrace(trace)
rdtest.log.success(f"Test {event_name} matched as expected")
rdtest.log.success(f"Test {event_name} matched as expected")
if failed:
raise rdtest.TestFailureException("Some tests were not as expected")
@@ -17,14 +17,12 @@ class D3D12_AMD_Shader_Extensions(rdtest.TestCase):
pipe = self.controller.GetPipelineState()
tex = pipe.GetOutputTargets()[0].resource
vp = pipe.GetViewport(0)
# Should have barycentrics showing the closest vertex for each pixel in the triangle
# Without relying on barycentric order, ensure that the three pixels are red, green, and blue
pixels: List[rdtest.VectorValue] = []
x = int(vp.x + vp.width * 0.5)
y = int(vp.y + vp.height * 0.5)
x, y = self.get_view_centre()
picked = self.controller.PickPixel(tex, x+ 0, y+ 0, rd.Subresource(), rd.CompType.UNorm)
pixels.append(picked.floatValue[0:4])
+39 -44
View File
@@ -154,65 +154,60 @@ class D3D12_CBuffer_Zoo(rdtest.TestCase):
rdtest.log.success("Array cbuffer variables are as expected")
trace = self.controller.DebugPixel(
int(pipe.GetViewport(0).width / 2.0),
int(pipe.GetViewport(0).height / 2.0),
rd.DebugPixelInputs(),
)
x, y = self.get_view_centre()
debugVars: Dict[str, rd.ShaderVariable] = dict()
with self.debug_pixel(x, y, rd.DebugPixelInputs()) as debug:
debugVars: Dict[str, rd.ShaderVariable] = dict()
for base in trace.constantBlocks:
for var in base.members:
debugVars[base.name + var.name] = var
for base in debug.trace.constantBlocks:
for var in base.members:
debugVars[base.name + var.name] = var
cbufferVars: List[rd.ShaderVariable] = []
cbufferVars: List[rd.ShaderVariable] = []
for sourceVar in trace.sourceVars:
if sourceVar.variables[0].name not in debugVars.keys():
continue
for sourceVar in debug.trace.sourceVars:
if sourceVar.variables[0].name not in debugVars.keys():
continue
eval = self.evaluate_source_var(sourceVar, debugVars)
cbufferVars.append(eval)
eval = self.evaluate_source_var(sourceVar, debugVars)
cbufferVars.append(eval)
cbufferVars = self.combine_source_vars(cbufferVars)
cbufferVars = self.combine_source_vars(cbufferVars)
assert len(cbufferVars) == 5
assert cbufferVars[0].name == 'consts'
assert cbufferVars[1].name == 'rootconsts'
assert cbufferVars[2].name == 'packed_consts'
assert cbufferVars[3].name == 'array_consts'
assert cbufferVars[4].name == 'hugespace'
assert len(cbufferVars) == 5
assert cbufferVars[0].name == 'consts'
assert cbufferVars[1].name == 'rootconsts'
assert cbufferVars[2].name == 'packed_consts'
assert cbufferVars[3].name == 'array_consts'
assert cbufferVars[4].name == 'hugespace'
var_check = rdtest.ConstantBufferChecker(cbufferVars[0].members)
root_check = rdtest.ConstantBufferChecker(cbufferVars[1].members)
packed_check = rdtest.ConstantBufferChecker(cbufferVars[2].members)
arrays_check = rdtest.ConstantBufferChecker(cbufferVars[3].members)
huge_check = rdtest.ConstantBufferChecker(cbufferVars[4].members)
var_check = rdtest.ConstantBufferChecker(cbufferVars[0].members)
root_check = rdtest.ConstantBufferChecker(cbufferVars[1].members)
packed_check = rdtest.ConstantBufferChecker(cbufferVars[2].members)
arrays_check = rdtest.ConstantBufferChecker(cbufferVars[3].members)
huge_check = rdtest.ConstantBufferChecker(cbufferVars[4].members)
self.check_cbuffers(var_check, root_check, huge_check, packed_check)
rdtest.log.success("Debugged CBuffer variables are as expected")
self.check_cbuffers(var_check, root_check, huge_check, packed_check)
rdtest.log.success("Debugged CBuffer variables are as expected")
arrays_check.check('[0]').rows(0).cols(0).members({
'a' : lambda y : y.rows(1).cols(4).value([0.0, 1.0, 0.5, 0.5])})
arrays_check.check('[1]').rows(0).cols(0).members({
'a' : lambda y : y.rows(1).cols(4).value([1.0, 2.0, 0.5, 0.5])})
arrays_check.done()
rdtest.log.success("Array cbuffer variables are as expected")
arrays_check.check('[0]').rows(0).cols(0).members({
'a' : lambda y : y.rows(1).cols(4).value([0.0, 1.0, 0.5, 0.5])})
arrays_check.check('[1]').rows(0).cols(0).members({
'a' : lambda y : y.rows(1).cols(4).value([1.0, 2.0, 0.5, 0.5])})
arrays_check.done()
rdtest.log.success("Array cbuffer variables are as expected")
cycles, variables = self.process_trace(trace)
cycles, variables = self.process_trace(debug.trace)
output = self.find_output_source_var(trace, rd.ShaderBuiltin.ColorOutput, 0)
output = self.find_output_source_var(debug.trace, rd.ShaderBuiltin.ColorOutput, 0)
debugged = self.evaluate_source_var(output, variables)
debugged = self.evaluate_source_var(output, variables)
if not rdtest.util.value_compare(debugged.value.f32v[0:4], [543.1, 546.0, 545.0, 546.0]):
raise rdtest.TestFailureException(
f"Debugged output {debugged.value.f32v[0:4]} did not match expected {[543.1, 546.0, 545.0, 546.0]}")
if not rdtest.util.value_compare(debugged.value.f32v[0:4], [543.1, 546.0, 545.0, 546.0]):
raise rdtest.TestFailureException(
f"Debugged output {debugged.value.f32v[0:4]} did not match expected {[543.1, 546.0, 545.0, 546.0]}")
rdtest.log.success("Debugged output matched as expected")
self.controller.FreeTrace(trace)
rdtest.log.success("Debugged output matched as expected")
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, 0.5, 0.5, [543.1, 546.0, 545.0, 546.0])
@@ -150,10 +150,7 @@ class D3D12_Descriptor_Indexing(rdtest.TestCase):
rdtest.log.success(f"Dynamic usage is as expected for {sm}")
v = pipe.GetViewport(0)
x = int(v.x) + int(v.width / 2)
y = int(v.y) + int(v.height // 2)
self.check_debug_pixel(x, y)
self.check_debug_pixel()
for sm in ["sm_6_6_heap"]:
base = self.find_action("Tests " + sm)
@@ -250,7 +247,5 @@ class D3D12_Descriptor_Indexing(rdtest.TestCase):
f"Bind {loc.logicalBindName} not expected for descriptor access SamplerDescriptorHeap[{a.access.byteOffset}]")
rdtest.log.success(f"Dynamic usage is as expected for {sm}")
v = pipe.GetViewport(0)
x = int(v.x) + int(v.width / 2)
y = int(v.y) + int(v.height // 2)
self.check_debug_pixel(x, y)
self.check_debug_pixel()
+33 -36
View File
@@ -20,50 +20,47 @@ class D3D12_PrimitiveID(rdtest.TestCase):
pixel_inputs = rd.DebugPixelInputs()
pixel_inputs.primitive = prim
trace = self.controller.DebugPixel(x, y, pixel_inputs)
with self.debug_pixel(x, y, pixel_inputs) as debug:
cycles, variables = self.process_trace(debug.trace)
cycles, variables = self.process_trace(trace)
# Find the SV_PrimitiveID variable, optionally
if not self.has_input_source_var(trace, rd.ShaderBuiltin.PrimitiveIndex):
# If we didn't find it, then we should be expecting a 0
if len(expected_prim) != 1 or expected_prim[0] != 0:
rdtest.log.error(f"Expected prim {expected_prim!s} at {x},{y} did not match actual prim {prim}.")
return False
else:
primInput = self.find_input_source_var(trace, rd.ShaderBuiltin.PrimitiveIndex)
# Look up the matching register in the inputs, and see if the expected value matches
inputs = list(trace.inputs)
primInputName = primInput.variables[0].name
if inputs[0].name.startswith('_IN') and primInputName.startswith('_IN.'):
# Walk the DXIL input structure
inputVars = inputs[0].members
# Remove the input name prefix
primInputName = primInputName[4:]
# Find the SV_PrimitiveID variable, optionally
if not self.has_input_source_var(debug.trace, rd.ShaderBuiltin.PrimitiveIndex):
# If we didn't find it, then we should be expecting a 0
if len(expected_prim) != 1 or expected_prim[0] != 0:
rdtest.log.error(f"Expected prim {expected_prim!s} at {x},{y} did not match actual prim {prim}.")
return False
else:
inputVars = inputs
primInput = self.find_input_source_var(debug.trace, rd.ShaderBuiltin.PrimitiveIndex)
primVars = [var for var in inputVars if var.name == primInputName]
# Look up the matching register in the inputs, and see if the expected value matches
inputs = list(debug.trace.inputs)
primInputName = primInput.variables[0].name
if inputs[0].name.startswith('_IN') and primInputName.startswith('_IN.'):
# Walk the DXIL input structure
inputVars = inputs[0].members
# Remove the input name prefix
primInputName = primInputName[4:]
else:
inputVars = inputs
primValue = primVars[0]
if primValue.value.u32v[0] not in expected_prim:
rdtest.log.error(f"Expected prim {expected_prim!s} at {x},{y} did not match actual prim {primValue.value.u32v[0]}.")
return False
primVars = [var for var in inputVars if var.name == primInputName]
# Compare shader debug output against an expected value instead of the RT's output,
# since we're testing overlapping primitives in a single action
if expected_output is not None:
output = self.find_output_source_var(trace, rd.ShaderBuiltin.ColorOutput, 0)
primValue = primVars[0]
if primValue.value.u32v[0] not in expected_prim:
rdtest.log.error(f"Expected prim {expected_prim!s} at {x},{y} did not match actual prim {primValue.value.u32v[0]}.")
return False
debugged = self.evaluate_source_var(output, variables)
if list(debugged.value.f32v[0:4]) != expected_output:
rdtest.log.error(f"Expected value {expected_output} at {x},{y} did not match actual {debugged.value.f32v[0:4]}.")
return False
# Compare shader debug output against an expected value instead of the RT's output,
# since we're testing overlapping primitives in a single action
if expected_output is not None:
output = self.find_output_source_var(debug.trace, rd.ShaderBuiltin.ColorOutput, 0)
self.controller.FreeTrace(trace)
debugged = self.evaluate_source_var(output, variables)
if list(debugged.value.f32v[0:4]) != expected_output:
rdtest.log.error(f"Expected value {expected_output} at {x},{y} did not match actual {debugged.value.f32v[0:4]}.")
return False
rdtest.log.success(f"Test at {x},{y} matched as expected")
rdtest.log.success(f"Test at {x},{y} matched as expected")
return True
def check_capture(self):
@@ -9,24 +9,21 @@ class D3D12_Resource_Mapping_Zoo(rdtest.TestCase):
pipe = self.controller.GetPipelineState()
# Debug the shader
trace = self.controller.DebugPixel(x, y, rd.DebugPixelInputs())
with self.debug_pixel(x, y, rd.DebugPixelInputs()) as debug:
cycles, variables = self.process_trace(debug.trace)
cycles, variables = self.process_trace(trace)
output = self.find_output_source_var(debug.trace, rd.ShaderBuiltin.ColorOutput, 0)
output = self.find_output_source_var(trace, rd.ShaderBuiltin.ColorOutput, 0)
debugged = self.evaluate_source_var(output, variables)
debugged = self.evaluate_source_var(output, variables)
try:
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, x, y, debugged.value.f32v[0:4])
except rdtest.TestFailureException as ex:
rdtest.log.error(f"Test {test_name} did not match. {ex!s}")
return False
try:
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, x, y, debugged.value.f32v[0:4])
except rdtest.TestFailureException as ex:
rdtest.log.error(f"Test {test_name} did not match. {ex!s}")
return False
finally:
self.controller.FreeTrace(trace)
rdtest.log.success(f"Test {test_name} matched as expected")
return True
rdtest.log.success(f"Test {test_name} matched as expected")
return True
def check_capture(self):
if not self.check_capture_internal():
+51 -58
View File
@@ -135,26 +135,24 @@ class D3D12_Shader_Debug_Zoo(rdtest.TestCase):
# Loop over every test
for test in range(action.numInstances):
# Debug the shader
trace = self.controller.DebugPixel(4 * test, 0, rd.DebugPixelInputs())
with self.debug_pixel(4 * test, 0, rd.DebugPixelInputs()) as debug:
cycles, variables = self.process_trace(debug.trace)
cycles, variables = self.process_trace(trace)
output = self.find_output_source_var(debug.trace, rd.ShaderBuiltin.ColorOutput, 0)
output = self.find_output_source_var(trace, rd.ShaderBuiltin.ColorOutput, 0)
debugged = self.evaluate_source_var(output, variables)
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(f"Undefined test {test} did not match. {ex!s}")
else:
rdtest.log.error(f"Test {test} did not match. {ex!s}")
failed = True
continue
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(f"Undefined test {test} did not match. {ex!s}")
else:
rdtest.log.error(f"Test {test} did not match. {ex!s}")
failed = True
continue
rdtest.log.success(f"Test {test} matched as expected")
rdtest.log.success(f"Test {test} matched as expected")
rdtest.log.begin_section("MSAA tests")
@@ -178,27 +176,25 @@ class D3D12_Shader_Debug_Zoo(rdtest.TestCase):
# Debug the shader
inputs = rd.DebugPixelInputs()
inputs.sample = test
trace = self.controller.DebugPixel(x, y, inputs)
with self.debug_pixel(x, y, inputs) as debug:
# Validate that the correct sample index was debugged
sampRegister = self.find_input_source_var(debug.trace, rd.ShaderBuiltin.MSAASampleIndex)
sampInput = [var for var in debug.trace.inputs if var.name == sampRegister.variables[0].name][0]
if sampInput.value.u32v[0] != test:
rdtest.log.error(f"Test {test} did not pick the correct sample.")
# Validate that the correct sample index was debugged
sampRegister = self.find_input_source_var(trace, rd.ShaderBuiltin.MSAASampleIndex)
sampInput = [var for var in trace.inputs if var.name == sampRegister.variables[0].name][0]
if sampInput.value.u32v[0] != test:
rdtest.log.error(f"Test {test} did not pick the correct sample.")
cycles, variables = self.process_trace(debug.trace)
cycles, variables = self.process_trace(trace)
output = self.find_output_source_var(debug.trace, rd.ShaderBuiltin.ColorOutput, 0)
output = self.find_output_source_var(trace, rd.ShaderBuiltin.ColorOutput, 0)
debugged = self.evaluate_source_var(output, variables)
debugged = self.evaluate_source_var(output, variables)
self.controller.FreeTrace(trace)
# Validate the debug output result
try:
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, x, y, debugged.value.f32v[0:4], sub=rd.Subresource(0, 0, test))
except rdtest.TestFailureException as ex:
failed = True
rdtest.log.error(f"Test {test} did not match. {ex!s}")
# Validate the debug output result
try:
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, x, y, debugged.value.f32v[0:4], sub=rd.Subresource(0, 0, test))
except rdtest.TestFailureException as ex:
failed = True
rdtest.log.error(f"Test {test} did not match. {ex!s}")
rdtest.log.end_section(marker)
@@ -229,21 +225,20 @@ class D3D12_Shader_Debug_Zoo(rdtest.TestCase):
# Debug the pixel shader
inputs = rd.DebugPixelInputs()
inputs.sample = 0
trace = self.controller.DebugPixel(51, 51, inputs)
cycles, variables = self.process_trace(trace)
output = self.find_output_source_var(trace, rd.ShaderBuiltin.ColorOutput, 0)
with self.debug_pixel(51, 51, inputs) as debug:
cycles, variables = self.process_trace(debug.trace)
output = self.find_output_source_var(debug.trace, rd.ShaderBuiltin.ColorOutput, 0)
debugged = self.evaluate_source_var(output, variables)
self.controller.FreeTrace(trace)
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(f"Vertex sample pixel shader output did not match. {ex!s}")
# 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(f"Vertex sample pixel shader output did not match. {ex!s}")
rdtest.log.success("VertexSample PS was debugged correctly")
rdtest.log.success("VertexSample PS was debugged correctly")
rdtest.log.end_section("VertexSample tests")
@@ -259,23 +254,21 @@ class D3D12_Shader_Debug_Zoo(rdtest.TestCase):
# Debug the pixel shader
inputs = rd.DebugPixelInputs()
inputs.sample = 0
trace = self.controller.DebugPixel(64, 64, inputs)
with self.debug_pixel(64, 64, inputs) as debug:
cycles, variables = self.process_trace(debug.trace)
cycles, variables = self.process_trace(trace)
output = self.find_output_source_var(debug.trace, rd.ShaderBuiltin.ColorOutput, 0)
output = self.find_output_source_var(trace, rd.ShaderBuiltin.ColorOutput, 0)
debugged = self.evaluate_source_var(output, variables)
debugged = self.evaluate_source_var(output, variables)
self.controller.FreeTrace(trace)
# Validate the debug output result
try:
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, 64, 64, debugged.value.f32v[0:4])
except rdtest.TestFailureException as ex:
failed = True
rdtest.log.error(f"Vertex sample pixel shader output did not match. {ex!s}")
# Validate the debug output result
try:
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, 64, 64, debugged.value.f32v[0:4])
except rdtest.TestFailureException as ex:
failed = True
rdtest.log.error(f"Vertex sample pixel shader output did not match. {ex!s}")
rdtest.log.success("Banned signature PS was debugged correctly")
rdtest.log.success("Banned signature PS was debugged correctly")
csShaderModels = ["cs_5_0", "cs_6_0", "cs_6_6"]
for sm in range(len(csShaderModels)):
@@ -18,24 +18,21 @@ class D3D12_Shader_Linkage_Zoo(rdtest.TestCase):
pipe = self.controller.GetPipelineState()
# Debug the shader
trace = self.controller.DebugPixel(200, 150, rd.DebugPixelInputs())
with self.debug_pixel(200, 150, rd.DebugPixelInputs()) as debug:
cycles, variables = self.process_trace(debug.trace)
cycles, variables = self.process_trace(trace)
output = self.find_output_source_var(debug.trace, rd.ShaderBuiltin.ColorOutput, 0)
debugged = self.evaluate_source_var(output, variables)
output = self.find_output_source_var(trace, rd.ShaderBuiltin.ColorOutput, 0)
debugged = self.evaluate_source_var(output, variables)
try:
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, 200, 150, debugged.value.f32v[0:4])
except rdtest.TestFailureException as ex:
failed = True
rdtest.log.error(f"Test {event_name} did not match. {ex!s}")
continue
try:
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, 200, 150, debugged.value.f32v[0:4])
except rdtest.TestFailureException as ex:
failed = True
rdtest.log.error(f"Test {event_name} did not match. {ex!s}")
continue
finally:
self.controller.FreeTrace(trace)
rdtest.log.success(f"Test {event_name} matched as expected")
rdtest.log.success(f"Test {event_name} matched as expected")
if failed:
raise rdtest.TestFailureException("Some tests were not as expected")
+7 -10
View File
@@ -46,20 +46,17 @@ class D3D12_Vertex_UAV(rdtest.TestCase):
rdtest.log.success(f"Quad overdraw is good on {name}")
# Debug the shader
trace = self.controller.DebugPixel(50, 50, rd.DebugPixelInputs())
with self.debug_pixel(50, 50, rd.DebugPixelInputs()) as debug:
cycles, variables = self.process_trace(debug.trace)
cycles, variables = self.process_trace(trace)
output = self.find_output_source_var(debug.trace, rd.ShaderBuiltin.ColorOutput, 0)
output = self.find_output_source_var(trace, rd.ShaderBuiltin.ColorOutput, 0)
debugged = self.evaluate_source_var(output, variables)
debugged = self.evaluate_source_var(output, variables)
if not rdtest.value_compare(debugged.value.f32v[0:4], [1.0, 1.0, 0.0, 1.0]):
raise rdtest.TestFailureException(f"Pixel shader at {name} did not debug correctly.")
self.controller.FreeTrace(trace)
if not rdtest.value_compare(debugged.value.f32v[0:4], [1.0, 1.0, 0.0, 1.0]):
raise rdtest.TestFailureException(f"Pixel shader at {name} did not debug correctly.")
rdtest.log.success(f"Shader debugging at {name} was successful")
rdtest.log.success(f"Shader debugging at {name} was successful")
quad_seen = sorted(quad_seen)
if quad_seen != [float(a) for a in range(1, len(quad_seen) + 1)]:
+2 -3
View File
@@ -130,10 +130,9 @@ class GL_Parameter_Zoo(rdtest.TestCase):
overlay_id = out.GetDebugOverlayTexID()
v = pipe.GetViewport(0)
x, y = self.get_view_centre()
self.check_pixel_value(overlay_id, int(0.5 * v.width), int(0.5 * v.height), [0.8, 0.1, 0.8, 1.0],
eps=1.0 / 256.0)
self.check_pixel_value(overlay_id, x, y, [0.8, 0.1, 0.8, 1.0], eps=1.0 / 256.0)
out.Shutdown()
+3 -2
View File
@@ -17,7 +17,8 @@ class GL_Renderbuffer_Zoo(rdtest.TestCase):
pipe = self.controller.GetPipelineState()
depth = pipe.GetDepthTarget()
vp = pipe.GetViewport(0)
x, y = self.get_view_centre()
id = pipe.GetOutputTargets()[0].resource
@@ -41,7 +42,7 @@ class GL_Renderbuffer_Zoo(rdtest.TestCase):
rdtest.log.success(f'Color Renderbuffer at action {action.eventId} is working as expected')
if depth.resource != rd.ResourceId():
val = self.controller.PickPixel(depth.resource, int(0.5 * vp.width), int(0.5 * vp.height),
val = self.controller.PickPixel(depth.resource, x, y,
rd.Subresource(), rd.CompType.Typeless)
if not rdtest.value_compare(val.floatValue[0], 0.75):
+12 -15
View File
@@ -37,26 +37,23 @@ class GL_Shader_Debug_Zoo(rdtest.TestCase):
inputs.primitive = 1
# Debug the shader
trace = self.controller.DebugPixel(x, y, inputs)
with self.debug_pixel(x, y, inputs) as debug:
rdtest.log.print(f"debugging {x},{y}")
rdtest.log.print(f"debugging {x},{y}")
_, variables = self.process_trace(debug.trace)
_, variables = self.process_trace(trace)
output = self.find_output_source_var(debug.trace, rd.ShaderBuiltin.ColorOutput, 0)
output = self.find_output_source_var(trace, rd.ShaderBuiltin.ColorOutput, 0)
debugged = self.evaluate_source_var(output, variables)
debugged = self.evaluate_source_var(output, variables)
try:
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, x, y, debugged.value.f32v[0:4])
except rdtest.TestFailureException as ex:
failed = True
rdtest.log.error(f"Test {test} in sub-section {child} did not match pixel. {ex!s}")
continue
try:
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, x, y, debugged.value.f32v[0:4])
except rdtest.TestFailureException as ex:
failed = True
rdtest.log.error(f"Test {test} in sub-section {child} did not match pixel. {ex!s}")
continue
finally:
self.controller.FreeTrace(trace)
rdtest.log.success(f"Test {test} pixel in sub-section {child} matched as expected")
rdtest.log.success(f"Test {test} pixel in sub-section {child} matched as expected")
vtx = 1
inst = 0
+40 -46
View File
@@ -272,62 +272,56 @@ class Iter_Test(rdtest.TestCase):
inputs = rd.DebugPixelInputs()
inputs.sample = 0
inputs.primitive = lastmod.primitiveID;
trace = self.controller.DebugPixel(x, y, inputs)
try:
cycles, variables = self.process_trace(trace)
except rdtest.TestFailureException as err:
rdtest.log.error(f"Error debugging: {err.message}")
return
output_index = [o.resource for o in pipe.GetOutputTargets()].index(target)
if action.outputs[0] == rd.ResourceId.Null():
rdtest.log.success(f'Successfully debugged pixel in {cycles} cycles, skipping result check due to no output')
self.controller.FreeTrace(trace)
elif (action.flags & rd.ActionFlags.Instanced) and action.numInstances > 1:
rdtest.log.success(f'Successfully debugged pixel in {cycles} cycles, skipping result check due to instancing')
self.controller.FreeTrace(trace)
elif pipe.GetColorBlends()[output_index].writeMask == 0:
rdtest.log.success(f'Successfully debugged pixel in {cycles} cycles, skipping result check due to write mask')
self.controller.FreeTrace(trace)
else:
rdtest.log.print(f"At event {lastmod.eventId} the target is index {output_index}")
with self.debug_pixel(x, y, inputs) as debug:
try:
output_sourcevar = self.find_output_source_var(trace, rd.ShaderBuiltin.ColorOutput, output_index)
cycles, variables = self.process_trace(debug.trace)
except rdtest.TestFailureException as err:
rdtest.log.error(f"Error debugging: {err.message}")
return
debugged = self.evaluate_source_var(output_sourcevar, variables)
output_index = [o.resource for o in pipe.GetOutputTargets()].index(target)
self.controller.FreeTrace(trace)
if action.outputs[0] == rd.ResourceId.Null():
rdtest.log.success(f'Successfully debugged pixel in {cycles} cycles, skipping result check due to no output')
elif (action.flags & rd.ActionFlags.Instanced) and action.numInstances > 1:
rdtest.log.success(f'Successfully debugged pixel in {cycles} cycles, skipping result check due to instancing')
elif pipe.GetColorBlends()[output_index].writeMask == 0:
rdtest.log.success(f'Successfully debugged pixel in {cycles} cycles, skipping result check due to write mask')
else:
rdtest.log.print(f"At event {lastmod.eventId} the target is index {output_index}")
debuggedValue = list(debugged.value.f32v[0:4])
try:
output_sourcevar = self.find_output_source_var(debug.trace, rd.ShaderBuiltin.ColorOutput, output_index)
# For now, ignore debugged values that are uninitialised. This is an application bug but it causes
# false reports of problems
for idx in range(4):
if debugged.value.u32v[idx] == 0xcccccccc:
debuggedValue[idx] = lastmod.shaderOut.col.floatValue[idx]
debugged = self.evaluate_source_var(output_sourcevar, variables)
historyValue = list(lastmod.shaderOut.col.floatValue)
debuggedValue = list(debugged.value.f32v[0:4])
tex = self.get_texture(target)
# For now, ignore debugged values that are uninitialised. This is an application bug but it causes
# false reports of problems
for idx in range(4):
if debugged.value.u32v[idx] == 0xcccccccc:
debuggedValue[idx] = lastmod.shaderOut.col.floatValue[idx]
historyValue = historyValue[0:tex.format.compCount]
debuggedValue = debuggedValue[0:tex.format.compCount]
historyValue = list(lastmod.shaderOut.col.floatValue)
# Unfortunately we can't ever trust that we should get back a matching results, because some shaders
# rely on undefined/inaccurate maths that we don't emulate.
# So the best we can do is log an error for manual verification
is_eq, diff_amt = rdtest.value_compare_diff(historyValue, debuggedValue, eps=5.0E-06)
if not is_eq:
rdtest.log.error(
f"Debugged value {debugged.name} at EID {lastmod.eventId} {x},{y}: {diff_amt} difference. {debuggedValue} doesn't exactly match history shader output {historyValue}")
tex = self.get_texture(target)
rdtest.log.success(f'Successfully debugged pixel in {cycles} cycles, result matches')
except rdtest.TestFailureException:
# This could be an application error - undefined but seen in the wild
rdtest.log.error(f"At EID {lastmod.eventId} No output variable declared for index {output_index}")
historyValue = historyValue[0:tex.format.compCount]
debuggedValue = debuggedValue[0:tex.format.compCount]
# Unfortunately we can't ever trust that we should get back a matching results, because some shaders
# rely on undefined/inaccurate maths that we don't emulate.
# So the best we can do is log an error for manual verification
is_eq, diff_amt = rdtest.value_compare_diff(historyValue, debuggedValue, eps=5.0E-06)
if not is_eq:
rdtest.log.error(
f"Debugged value {debugged.name} at EID {lastmod.eventId} {x},{y}: {diff_amt} difference. {debuggedValue} doesn't exactly match history shader output {historyValue}")
rdtest.log.success(f'Successfully debugged pixel in {cycles} cycles, result matches')
except rdtest.TestFailureException:
# This could be an application error - undefined but seen in the wild
rdtest.log.error(f"At EID {lastmod.eventId} No output variable declared for index {output_index}")
self.set_event(action.eventId, True)
+10 -13
View File
@@ -97,24 +97,21 @@ class VK_Graphics_Pipeline(rdtest.TestCase):
inputs = rd.DebugPixelInputs()
inputs.sample = 0
inputs.primitive = 0
trace = self.controller.DebugPixel(200, 150, inputs)
with self.debug_pixel(200, 150, inputs) as debug:
cycles, variables = self.process_trace(debug.trace)
cycles, variables = self.process_trace(trace)
output_sourcevar = self.find_output_source_var(debug.trace, rd.ShaderBuiltin.ColorOutput, 0)
output_sourcevar = self.find_output_source_var(trace, rd.ShaderBuiltin.ColorOutput, 0)
debugged = self.evaluate_source_var(output_sourcevar, variables)
debugged = self.evaluate_source_var(output_sourcevar, variables)
debuggedValue = list(debugged.value.f32v[0:4])
self.controller.FreeTrace(trace)
is_eq, diff_amt = rdtest.value_compare_diff(history[1].shaderOut.col.floatValue, debuggedValue, eps=5.0E-06)
if not is_eq:
raise rdtest.TestFailureException(
f"Debugged pixel value {debugged.name}: {diff_amt} difference. {debuggedValue} doesn't exactly match history shader output {history[1].shaderOut.col.floatValue}")
debuggedValue = list(debugged.value.f32v[0:4])
is_eq, diff_amt = rdtest.value_compare_diff(history[1].shaderOut.col.floatValue, debuggedValue, eps=5.0E-06)
if not is_eq:
raise rdtest.TestFailureException(
f"Debugged pixel value {debugged.name}: {diff_amt} difference. {debuggedValue} doesn't exactly match history shader output {history[1].shaderOut.col.floatValue}")
rdtest.log.success(f'Successfully debugged pixel in {cycles} cycles, result matches')
rdtest.log.success(f'Successfully debugged pixel in {cycles} cycles, result matches')
out = self.controller.CreateOutput(rd.CreateHeadlessWindowingData(100, 100), rd.ReplayOutputType.Texture)
+14 -15
View File
@@ -17,23 +17,22 @@ class VK_KHR_Buffer_Address(rdtest.TestCase):
pipe = self.controller.GetPipelineState()
# Debug the pixel shader
trace = self.controller.DebugPixel(x, y, rd.DebugPixelInputs())
with self.debug_pixel(x, y, rd.DebugPixelInputs()) as debug:
cycles, variables = self.process_trace(debug.trace)
output = self.find_output_source_var(debug.trace, rd.ShaderBuiltin.ColorOutput, 0)
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.check_pixel_value(pipe.GetOutputTargets()[0].resource, x, y, debugged.value.f32v[0:4])
debugged = self.evaluate_source_var(output, variables)
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, x, y, debugged.value.f32v[0:4])
self.controller.FreeTrace(trace)
x = x + 100
if x > 300:
x = 100
y += 100
x = x + 100
if x > 300:
x = 100
y += 100
inst = 0
postvs = self.get_postvs(action, rd.MeshDataStage.VSOut, instance=inst)
for vtx in range(action.numIndices):
idx = vtx
self.check_vertex_debug(vtx, idx, inst, postvs)
inst = 0
postvs = self.get_postvs(action, rd.MeshDataStage.VSOut, instance=inst)
for vtx in range(action.numIndices):
idx = vtx
self.check_vertex_debug(vtx, idx, inst, postvs)
rdtest.log.success("All tests matched")
+13 -16
View File
@@ -54,31 +54,28 @@ class VK_Multi_Entry(rdtest.TestCase):
if not rdtest.value_compare(history[1].shaderOut.col.floatValue, (0.0, 1.0, 0.0, 1.0)):
raise rdtest.TestFailureException(f"History for drawcall output is wrong: {history[1].shaderOut.col.floatValue}")
inputs = rd.DebugPixelInputs()
inputs.sample = 0
inputs.primitive = 0
trace = self.controller.DebugPixel(200, 150, inputs)
refl = pipe.GetShaderReflection(rd.ShaderStage.Pixel)
assert len(refl.readOnlyResources) == 1
cycles, variables = self.process_trace(trace)
inputs = rd.DebugPixelInputs()
inputs.sample = 0
inputs.primitive = 0
with self.debug_pixel(200, 150, inputs) as debug:
cycles, variables = self.process_trace(debug.trace)
output_sourcevar = self.find_output_source_var(trace, rd.ShaderBuiltin.ColorOutput, 0)
output_sourcevar = self.find_output_source_var(debug.trace, rd.ShaderBuiltin.ColorOutput, 0)
debugged = self.evaluate_source_var(output_sourcevar, variables)
debugged = self.evaluate_source_var(output_sourcevar, variables)
self.controller.FreeTrace(trace)
debuggedValue = list(debugged.value.f32v[0:4])
debuggedValue = list(debugged.value.f32v[0:4])
is_eq, diff_amt = rdtest.value_compare_diff(history[1].shaderOut.col.floatValue, debuggedValue, eps=5.0E-06)
if not is_eq:
rdtest.log.error(
f"Debugged pixel value {debugged.name}: {diff_amt} difference. {debuggedValue} doesn't exactly match history shader output {history[1].shaderOut.col.floatValue}")
is_eq, diff_amt = rdtest.value_compare_diff(history[1].shaderOut.col.floatValue, debuggedValue, eps=5.0E-06)
if not is_eq:
rdtest.log.error(
f"Debugged pixel value {debugged.name}: {diff_amt} difference. {debuggedValue} doesn't exactly match history shader output {history[1].shaderOut.col.floatValue}")
rdtest.log.success(f'Successfully debugged pixel in {cycles} cycles, result matches')
rdtest.log.success(f'Successfully debugged pixel in {cycles} cycles, result matches')
out = self.controller.CreateOutput(rd.CreateHeadlessWindowingData(100, 100), rd.ReplayOutputType.Texture)
+26 -30
View File
@@ -23,23 +23,21 @@ class VK_Multi_View(rdtest.TestCase):
# Debug the pixel shader
inputs = rd.DebugPixelInputs()
inputs.view = view
trace = self.controller.DebugPixel(x, y, inputs)
with self.debug_pixel(x, y, inputs) as debug:
cycles, variables = self.process_trace(debug.trace)
output = self.find_output_source_var(debug.trace, rd.ShaderBuiltin.ColorOutput, 0)
cycles, variables = self.process_trace(trace)
output = self.find_output_source_var(trace, rd.ShaderBuiltin.ColorOutput, 0)
debugged = self.evaluate_source_var(output, variables)
slice = view + 1
sub = rd.Subresource(0, slice, 0)
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, x, y, debugged.value.f32v[0:4], sub=sub)
debugged = self.evaluate_source_var(output, variables)
slice = view + 1
sub = rd.Subresource(0, slice, 0)
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, x, y, debugged.value.f32v[0:4], sub=sub)
self.controller.FreeTrace(trace)
inst = 0
postvs = self.get_postvs(action, rd.MeshDataStage.VSOut, instance=inst, view=view)
for vtx in range(action.numIndices):
idx = vtx
self.check_vertex_debug(vtx, idx, inst, postvs, view=view)
rdtest.log.print(f"View {view} Slice {slice} passed")
inst = 0
postvs = self.get_postvs(action, rd.MeshDataStage.VSOut, instance=inst, view=view)
for vtx in range(action.numIndices):
idx = vtx
self.check_vertex_debug(vtx, idx, inst, postvs, view=view)
rdtest.log.success(f"View {view} Slice {slice} passed")
for test_name in ["viewportIndex choice"]:
rdtest.log.print(f"Test {test_name}")
@@ -61,23 +59,21 @@ class VK_Multi_View(rdtest.TestCase):
# Debug the pixel shader
inputs = rd.DebugPixelInputs()
inputs.view = view
trace = self.controller.DebugPixel(x, y, inputs)
with self.debug_pixel(x, y, inputs) as debug:
cycles, variables = self.process_trace(debug.trace)
output = self.find_output_source_var(debug.trace, rd.ShaderBuiltin.ColorOutput, 0)
cycles, variables = self.process_trace(trace)
output = self.find_output_source_var(trace, rd.ShaderBuiltin.ColorOutput, 0)
debugged = self.evaluate_source_var(output, variables)
slice = view + 1
sub = rd.Subresource(0, slice, 0)
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, x, y, debugged.value.f32v[0:4], sub=sub)
debugged = self.evaluate_source_var(output, variables)
slice = view + 1
sub = rd.Subresource(0, slice, 0)
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, x, y, debugged.value.f32v[0:4], sub=sub)
self.controller.FreeTrace(trace)
inst = 0
postvs = self.get_postvs(action, rd.MeshDataStage.VSOut, instance=inst, view=view)
for vtx in range(action.numIndices):
idx = vtx
self.check_vertex_debug(vtx, idx, inst, postvs, view=view)
rdtest.log.print(f"View {view} Slice {slice} passed")
inst = 0
postvs = self.get_postvs(action, rd.MeshDataStage.VSOut, instance=inst, view=view)
for vtx in range(action.numIndices):
idx = vtx
self.check_vertex_debug(vtx, idx, inst, postvs, view=view)
rdtest.log.print(f"View {view} Slice {slice} passed")
rdtest.log.success("All tests matched")
+16 -19
View File
@@ -24,30 +24,27 @@ class VK_Shader_Debug_Zoo(rdtest.TestCase):
y = 4 * child + 1
# Debug the shader
trace = self.controller.DebugPixel(x, y, rd.DebugPixelInputs())
with self.debug_pixel(x, y, rd.DebugPixelInputs()) as debug:
_, variables = self.process_trace(debug.trace)
_, variables = self.process_trace(trace)
output = self.find_output_source_var(debug.trace, rd.ShaderBuiltin.ColorOutput, 0)
output = self.find_output_source_var(trace, rd.ShaderBuiltin.ColorOutput, 0)
debugged = self.evaluate_source_var(output, variables)
debugged = self.evaluate_source_var(output, variables)
try:
valscale = min(debugged.value.f32v[0:4])
eps = rdtest.FLT_EPSILON
if valscale > 1.0:
eps = 5.0e-05
try:
valscale = min(debugged.value.f32v[0:4])
eps = rdtest.FLT_EPSILON
if valscale > 1.0:
eps = 5.0e-05
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, x, y, debugged.value.f32v[0:4], eps=eps)
except rdtest.TestFailureException as ex:
failed = True
rdtest.log.error(f"Test {test} in sub-section {child} did not match. {ex!s}")
continue
self.check_pixel_value(pipe.GetOutputTargets()[0].resource, x, y, debugged.value.f32v[0:4], eps=eps)
except rdtest.TestFailureException as ex:
failed = True
rdtest.log.error(f"Test {test} in sub-section {child} did not match. {ex!s}")
continue
finally:
self.controller.FreeTrace(trace)
rdtest.log.success(f"Test {test} in sub-section {child} matched as expected")
rdtest.log.success(f"Test {test} in sub-section {child} matched as expected")
rdtest.log.end_section(test_name)
test_name = "Disassembly Tests"