mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-09-15 10:15:48 +00:00
Add helper for checking vertex debugging matches postvs
* There are a few 'extras' here as the uses aren't quite uniform, but they are close enough it makes sense to have a common helper
This commit is contained in:
@@ -121,7 +121,7 @@ class Draw_Zoo(rdtest.TestCase):
|
||||
|
||||
idx = vsout_ref[vtx]['idx']
|
||||
|
||||
self.check_debug(vtx, idx, inst, postvs)
|
||||
self.check_vertex_debug(vtx, idx, inst, postvs)
|
||||
else:
|
||||
rdtest.log.print('Not checking shader debugging, unsupported')
|
||||
|
||||
@@ -136,41 +136,6 @@ class Draw_Zoo(rdtest.TestCase):
|
||||
|
||||
rdtest.log.success("Checked action {}".format(action.eventId))
|
||||
|
||||
def check_debug(self, vtx, idx, inst, postvs):
|
||||
trace: rd.ShaderDebugTrace = self.controller.DebugVertex(vtx, inst, idx, 0)
|
||||
|
||||
if trace.debugger is None:
|
||||
self.controller.FreeTrace(trace)
|
||||
|
||||
raise rdtest.TestFailureException("Couldn't debug vertex {} in instance {}".format(vtx, inst))
|
||||
|
||||
cycles, variables = self.process_trace(trace)
|
||||
|
||||
for var in trace.sourceVars:
|
||||
var: rd.SourceVariableMapping
|
||||
if var.variables[0].type == rd.DebugVariableType.Variable and var.signatureIndex >= 0:
|
||||
name = var.name
|
||||
|
||||
if name not in postvs[vtx].keys():
|
||||
raise rdtest.TestFailureException("Don't have expected output for {}".format(name))
|
||||
|
||||
expect = postvs[vtx][name]
|
||||
value = self.evaluate_source_var(var, variables)
|
||||
|
||||
if len(expect) != value.columns:
|
||||
raise rdtest.TestFailureException(
|
||||
"Output {} at vert {} (idx {}) instance {} has different size ({} values) to expectation ({} values)"
|
||||
.format(name, vtx, idx, inst, value.columns, len(expect)))
|
||||
|
||||
debugged = value.value.f32v[0:value.columns]
|
||||
|
||||
if not rdtest.value_compare(expect, debugged):
|
||||
raise rdtest.TestFailureException(
|
||||
"Debugged value {} at vert {} (idx {}) instance {}: {} doesn't exactly match postvs output {}".format(
|
||||
name, vtx, idx, inst, debugged, expect))
|
||||
rdtest.log.success('Successfully debugged vertex {} in instance {}'
|
||||
.format(vtx, inst))
|
||||
|
||||
def check_capture(self):
|
||||
test_marker: rd.ActionDescription = self.find_action("Test")
|
||||
self.check_capture_action(test_marker)
|
||||
|
||||
@@ -536,6 +536,84 @@ class TestCase:
|
||||
|
||||
log.success("Simple triangle is as expected")
|
||||
|
||||
def check_vertex_debug(
|
||||
self,
|
||||
vtx: int,
|
||||
idx: int,
|
||||
inst: int,
|
||||
postvs: analyse.MeshData,
|
||||
*,
|
||||
view=-1,
|
||||
eps=util.FLT_EPSILON,
|
||||
single_postvs=False,
|
||||
ignore_uninit=False,
|
||||
name_retry: Callable[[str], str] | None = None
|
||||
):
|
||||
trace = self.controller.DebugVertex(vtx, inst, idx, max(0, view))
|
||||
|
||||
ctx = f"vertex {vtx} (idx {idx}) instance {inst}"
|
||||
if view >= 0:
|
||||
ctx += f" view {view}"
|
||||
|
||||
if trace.debugger is None:
|
||||
self.controller.FreeTrace(trace)
|
||||
|
||||
raise TestFailureException(f"Couldn't debug {ctx}")
|
||||
|
||||
try:
|
||||
cycles, variables = self.process_trace(trace)
|
||||
|
||||
postvs_vtx = vtx
|
||||
if single_postvs:
|
||||
postvs_vtx = 0
|
||||
|
||||
for var in trace.sourceVars:
|
||||
if var.variables[0].type == rd.DebugVariableType.Variable and var.signatureIndex >= 0:
|
||||
name = var.name
|
||||
|
||||
if name not in postvs[postvs_vtx].keys() and name_retry is not None:
|
||||
name = name_retry(name)
|
||||
|
||||
if name not in postvs[postvs_vtx].keys():
|
||||
raise TestFailureException(f"Don't have expected output for {name}")
|
||||
|
||||
expect = postvs[postvs_vtx][name]
|
||||
assert expect is not None
|
||||
value = self.evaluate_source_var(var, variables)
|
||||
|
||||
expect_cols = 1
|
||||
if util.is_vector(expect):
|
||||
expect_cols = len(expect)
|
||||
if expect_cols != value.columns:
|
||||
raise TestFailureException(
|
||||
f"Output {name} at {ctx} has different size ({value.columns} values) to expectation ({expect_cols} values)")
|
||||
|
||||
compType = rd.VarTypeCompType(value.type)
|
||||
debugged: util.VectorValue = []
|
||||
if compType == rd.CompType.UInt:
|
||||
debugged = list(value.value.u32v[0:value.columns])
|
||||
elif compType == rd.CompType.SInt:
|
||||
debugged = list(value.value.s32v[0:value.columns])
|
||||
else:
|
||||
debugged = list(value.value.f32v[0:value.columns])
|
||||
|
||||
# For now, ignore debugged values that are uninitialised. This is an application bug but it causes false
|
||||
# reports of problems
|
||||
if ignore_uninit and value.columns > 1:
|
||||
assert util.is_vector(expect)
|
||||
for comp in range(4):
|
||||
if value.value.u32v[comp] == 0xcccccccc:
|
||||
debugged[comp] = expect[comp]
|
||||
|
||||
is_eq, diff_amt = util.value_compare_diff(expect, debugged, eps=5.0E-06)
|
||||
if not is_eq:
|
||||
raise TestFailureException(
|
||||
f"Debugged value {name} at {ctx}: {debugged} doesn't exactly match postvs output {expect}. {diff_amt} difference")
|
||||
|
||||
log.success(f'Successfully debugged vertex {ctx} in {cycles} cycles')
|
||||
finally:
|
||||
self.controller.FreeTrace(trace)
|
||||
|
||||
def run(self):
|
||||
self.capture_filename = self.get_capture()
|
||||
|
||||
|
||||
@@ -97,65 +97,14 @@ class GL_Shader_Debug_Zoo(rdtest.TestCase):
|
||||
|
||||
postvs = self.get_postvs(action, rd.MeshDataStage.VSOut, first_index=vtx, num_indices=1, instance=inst)
|
||||
|
||||
trace: rd.ShaderDebugTrace = self.controller.DebugVertex(vtx, inst, idx, 0)
|
||||
|
||||
if trace.debugger is None:
|
||||
try:
|
||||
self.check_vertex_debug(vtx, idx, inst, postvs, single_postvs=True, name_retry = lambda x: x.replace(".", "Block."))
|
||||
except rdtest.TestFailureException as err:
|
||||
failed = True
|
||||
rdtest.log.error("Test {} in sub-section {} did not debug vertex".format(test, child))
|
||||
self.controller.FreeTrace(trace)
|
||||
rdtest.log.error(f"Error debugging vertex at test {test} in sub-section {child}: {err.message}")
|
||||
continue
|
||||
|
||||
_, variables = self.process_trace(trace)
|
||||
|
||||
outputs = 0
|
||||
|
||||
for var in trace.sourceVars:
|
||||
var: rd.SourceVariableMapping
|
||||
if var.variables[0].type == rd.DebugVariableType.Variable and var.signatureIndex >= 0:
|
||||
name = var.name
|
||||
|
||||
if name not in postvs[0].keys():
|
||||
name = name.replace(".", "Block.")
|
||||
if name not in postvs[0].keys():
|
||||
failed = True
|
||||
rdtest.log.error("Don't have expected output for {}".format(name))
|
||||
continue
|
||||
|
||||
expect = postvs[0][name]
|
||||
value = self.evaluate_source_var(var, variables)
|
||||
|
||||
if len(expect) != value.columns:
|
||||
failed = True
|
||||
rdtest.log.error(
|
||||
"Output {} at EID {} has different size ({} values) to expectation ({} values)"
|
||||
.format(name, action.eventId, value.columns, len(expect)))
|
||||
continue
|
||||
|
||||
compType = rd.VarTypeCompType(value.type)
|
||||
if compType == rd.CompType.UInt:
|
||||
debugged = list(value.value.u32v[0:value.columns])
|
||||
elif compType == rd.CompType.SInt:
|
||||
debugged = list(value.value.s32v[0:value.columns])
|
||||
else:
|
||||
debugged = list(value.value.f32v[0:value.columns])
|
||||
|
||||
if not rdtest.value_compare(expect, debugged):
|
||||
failed = True
|
||||
rdtest.log.error("Test {} in sub-section {} did not match vertex.\nExpected {} but got {}".format(test, child, expect, debugged))
|
||||
break
|
||||
|
||||
is_eq, diff_amt = rdtest.value_compare_diff(expect, debugged, eps=5.0E-06)
|
||||
if not is_eq:
|
||||
failed = True
|
||||
rdtest.log.error(
|
||||
"Debugged value {} at EID {} vert {} (idx {}) instance {}: {} difference. {} doesn't exactly match postvs output {}".format(
|
||||
name, action.eventId, vtx, idx, inst, diff_amt, debugged, expect))
|
||||
|
||||
outputs = outputs + 1
|
||||
|
||||
self.controller.FreeTrace(trace)
|
||||
|
||||
rdtest.log.success("Test {} vertex in sub-section {} matched as expected".format(test, child))
|
||||
rdtest.log.success(f"Test {test} vertex in sub-section {child} matched as expected")
|
||||
|
||||
rdtest.log.end_section(child)
|
||||
|
||||
|
||||
@@ -152,70 +152,12 @@ class Iter_Test(rdtest.TestCase):
|
||||
|
||||
postvs = self.get_postvs(action, rd.MeshDataStage.VSOut, first_index=vtx, num_indices=1, instance=inst)
|
||||
|
||||
trace: rd.ShaderDebugTrace = self.controller.DebugVertex(vtx, inst, idx, 0)
|
||||
|
||||
if trace.debugger is None:
|
||||
self.controller.FreeTrace(trace)
|
||||
|
||||
rdtest.log.print("No debug result")
|
||||
return
|
||||
|
||||
try:
|
||||
cycles, variables = self.process_trace(trace)
|
||||
self.check_vertex_debug(vtx, idx, inst, postvs, eps=5.0E-06, single_postvs=True, ignore_uninit=True)
|
||||
except rdtest.TestFailureException as err:
|
||||
rdtest.log.error(f"Error debugging: {err.message}")
|
||||
return
|
||||
|
||||
outputs = 0
|
||||
|
||||
for var in trace.sourceVars:
|
||||
var: rd.SourceVariableMapping
|
||||
if var.variables[0].type == rd.DebugVariableType.Variable and var.signatureIndex >= 0:
|
||||
name = var.name
|
||||
|
||||
if name not in postvs[0].keys():
|
||||
rdtest.log.error("Don't have expected output for {}".format(name))
|
||||
continue
|
||||
|
||||
expect = postvs[0][name]
|
||||
value = self.evaluate_source_var(var, variables)
|
||||
|
||||
if len(expect) != value.columns:
|
||||
rdtest.log.error(
|
||||
"Output {} at EID {} has different size ({} values) to expectation ({} values)"
|
||||
.format(name, action.eventId, value.columns, len(expect)))
|
||||
continue
|
||||
|
||||
compType = rd.VarTypeCompType(value.type)
|
||||
if compType == rd.CompType.UInt:
|
||||
debugged = list(value.value.u32v[0:value.columns])
|
||||
elif compType == rd.CompType.SInt:
|
||||
debugged = list(value.value.s32v[0:value.columns])
|
||||
else:
|
||||
debugged = list(value.value.f32v[0:value.columns])
|
||||
|
||||
# For now, ignore debugged values that are uninitialised. This is an application bug but it causes false
|
||||
# reports of problems
|
||||
for comp in range(4):
|
||||
if value.value.u32v[comp] == 0xcccccccc:
|
||||
debugged[comp] = expect[comp]
|
||||
|
||||
# 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(expect, debugged, eps=5.0E-06)
|
||||
if not is_eq:
|
||||
rdtest.log.error(
|
||||
"Debugged value {} at EID {} vert {} (idx {}) instance {}: {} difference. {} doesn't exactly match postvs output {}".format(
|
||||
name, action.eventId, vtx, idx, inst, diff_amt, debugged, expect))
|
||||
|
||||
outputs = outputs + 1
|
||||
|
||||
rdtest.log.success('Successfully debugged vertex in {} cycles, {}/{} outputs match'
|
||||
.format(cycles, outputs, len(refl.outputSignature)))
|
||||
|
||||
self.controller.FreeTrace(trace)
|
||||
|
||||
def pixel_debug(self, action: rd.ActionDescription):
|
||||
pipe: rd.PipeState = self.controller.GetPipelineState()
|
||||
|
||||
|
||||
@@ -76,51 +76,7 @@ class VK_Graphics_Pipeline(rdtest.TestCase):
|
||||
raise rdtest.TestFailureException(
|
||||
f"Graphics bind 0[15] isn't the accessed descriptor {str(rd.DumpObject(access))}")
|
||||
|
||||
trace = self.controller.DebugVertex(0, 0, 0, 0)
|
||||
|
||||
if trace.debugger is None:
|
||||
raise rdtest.TestFailureException("No vertex debug result")
|
||||
|
||||
cycles, variables = self.process_trace(trace)
|
||||
|
||||
outputs = 0
|
||||
|
||||
for var in trace.sourceVars:
|
||||
var: rd.SourceVariableMapping
|
||||
if var.variables[0].type == rd.DebugVariableType.Variable and var.signatureIndex >= 0:
|
||||
name = var.name
|
||||
|
||||
if name not in postvs_data[0].keys():
|
||||
raise rdtest.TestFailureException("Don't have expected output for {}".format(name))
|
||||
|
||||
expect = postvs_data[0][name]
|
||||
value = self.evaluate_source_var(var, variables)
|
||||
|
||||
if len(expect) != value.columns:
|
||||
raise rdtest.TestFailureException(
|
||||
"Vertex output {} has different size ({} values) to expectation ({} values)".format(
|
||||
name, action.eventId, value.columns, len(expect)))
|
||||
|
||||
compType = rd.VarTypeCompType(value.type)
|
||||
if compType == rd.CompType.UInt:
|
||||
debugged = list(value.value.u32v[0:value.columns])
|
||||
elif compType == rd.CompType.SInt:
|
||||
debugged = list(value.value.s32v[0:value.columns])
|
||||
else:
|
||||
debugged = list(value.value.f32v[0:value.columns])
|
||||
|
||||
is_eq, diff_amt = rdtest.value_compare_diff(expect, debugged, eps=5.0E-06)
|
||||
if not is_eq:
|
||||
rdtest.log.error(
|
||||
"Debugged vertex output value {}: {} difference. {} doesn't exactly match postvs output {}".
|
||||
format(name, action.eventId, diff_amt, debugged, expect))
|
||||
|
||||
outputs = outputs + 1
|
||||
|
||||
rdtest.log.success('Successfully debugged vertex in {} cycles, {}/{} outputs match'.format(
|
||||
cycles, outputs, len(vsrefl.outputSignature)))
|
||||
|
||||
self.controller.FreeTrace(trace)
|
||||
self.check_vertex_debug(0, 0, 0, postvs_data)
|
||||
|
||||
history = self.controller.PixelHistory(pipe.GetOutputTargets()[0].resource, 200, 150, rd.Subresource(0, 0, 0),
|
||||
rd.CompType.Typeless)
|
||||
|
||||
@@ -42,43 +42,6 @@ class VK_KHR_Buffer_Address(rdtest.TestCase):
|
||||
postvs = self.get_postvs(action, rd.MeshDataStage.VSOut, instance=inst)
|
||||
for vtx in range(action.numIndices):
|
||||
idx = vtx
|
||||
self.check_debug(vtx, idx, inst, postvs)
|
||||
self.check_vertex_debug(vtx, idx, inst, postvs)
|
||||
|
||||
rdtest.log.success("All tests matched")
|
||||
|
||||
|
||||
def check_debug(self, vtx, idx, inst, postvs):
|
||||
trace: rd.ShaderDebugTrace = self.controller.DebugVertex(vtx, inst, idx, 0)
|
||||
|
||||
if trace.debugger is None:
|
||||
self.controller.FreeTrace(trace)
|
||||
|
||||
raise rdtest.TestFailureException("Couldn't debug vertex {} in instance {}".format(vtx, inst))
|
||||
|
||||
cycles, variables = self.process_trace(trace)
|
||||
|
||||
for var in trace.sourceVars:
|
||||
var: rd.SourceVariableMapping
|
||||
if var.variables[0].type == rd.DebugVariableType.Variable and var.signatureIndex >= 0:
|
||||
name = var.name
|
||||
|
||||
if name not in postvs[vtx].keys():
|
||||
raise rdtest.TestFailureException("Don't have expected output for {}".format(name))
|
||||
|
||||
expect = postvs[vtx][name]
|
||||
value = self.evaluate_source_var(var, variables)
|
||||
|
||||
if len(expect) != value.columns:
|
||||
raise rdtest.TestFailureException(
|
||||
"Output {} at vert {} (idx {}) instance {} has different size ({} values) to expectation ({} values)"
|
||||
.format(name, vtx, idx, inst, value.columns, len(expect)))
|
||||
|
||||
debugged = value.value.f32v[0:value.columns]
|
||||
|
||||
if not rdtest.value_compare(expect, debugged):
|
||||
raise rdtest.TestFailureException(
|
||||
"Debugged value {} at vert {} (idx {}) instance {}: {} doesn't exactly match postvs output {}".format(
|
||||
name, vtx, idx, inst, debugged, expect))
|
||||
rdtest.log.success('Successfully debugged vertex {} in instance {}'
|
||||
.format(vtx, inst))
|
||||
|
||||
|
||||
@@ -36,51 +36,7 @@ class VK_Multi_Entry(rdtest.TestCase):
|
||||
|
||||
postvs = self.get_postvs(action, rd.MeshDataStage.VSOut, first_index=0, num_indices=1, instance=0)
|
||||
|
||||
trace: rd.ShaderDebugTrace = self.controller.DebugVertex(0, 0, 0, 0)
|
||||
|
||||
if trace.debugger is None:
|
||||
raise rdtest.TestFailureException("No vertex debug result")
|
||||
|
||||
cycles, variables = self.process_trace(trace)
|
||||
|
||||
outputs = 0
|
||||
|
||||
for var in trace.sourceVars:
|
||||
var: rd.SourceVariableMapping
|
||||
if var.variables[0].type == rd.DebugVariableType.Variable and var.signatureIndex >= 0:
|
||||
name = var.name
|
||||
|
||||
if name not in postvs[0].keys():
|
||||
raise rdtest.TestFailureException("Don't have expected output for {}".format(name))
|
||||
|
||||
expect = postvs[0][name]
|
||||
value = self.evaluate_source_var(var, variables)
|
||||
|
||||
if len(expect) != value.columns:
|
||||
raise rdtest.TestFailureException(
|
||||
"Vertex output {} has different size ({} values) to expectation ({} values)".format(
|
||||
name, action.eventId, value.columns, len(expect)))
|
||||
|
||||
compType = rd.VarTypeCompType(value.type)
|
||||
if compType == rd.CompType.UInt:
|
||||
debugged = list(value.value.u32v[0:value.columns])
|
||||
elif compType == rd.CompType.SInt:
|
||||
debugged = list(value.value.s32v[0:value.columns])
|
||||
else:
|
||||
debugged = list(value.value.f32v[0:value.columns])
|
||||
|
||||
is_eq, diff_amt = rdtest.value_compare_diff(expect, debugged, eps=5.0E-06)
|
||||
if not is_eq:
|
||||
rdtest.log.error(
|
||||
"Debugged vertex output value {}: {} difference. {} doesn't exactly match postvs output {}".
|
||||
format(name, action.eventId, diff_amt, debugged, expect))
|
||||
|
||||
outputs = outputs + 1
|
||||
|
||||
rdtest.log.success('Successfully debugged vertex in {} cycles, {}/{} outputs match'.format(
|
||||
cycles, outputs, len(refl.outputSignature)))
|
||||
|
||||
self.controller.FreeTrace(trace)
|
||||
self.check_vertex_debug(0, 0, 0, postvs, single_postvs=True)
|
||||
|
||||
history = self.controller.PixelHistory(pipe.GetOutputTargets()[0].resource, 200, 150, rd.Subresource(0, 0, 0),
|
||||
rd.CompType.Typeless)
|
||||
|
||||
@@ -45,7 +45,7 @@ class VK_Multi_View(rdtest.TestCase):
|
||||
postvs = self.get_postvs(action, rd.MeshDataStage.VSOut, instance=inst, view=view)
|
||||
for vtx in range(action.numIndices):
|
||||
idx = vtx
|
||||
self.check_debug(vtx, idx, inst, view, postvs)
|
||||
self.check_vertex_debug(vtx, idx, inst, postvs, view=view)
|
||||
rdtest.log.print(f"View {view} Slice {slice} passed")
|
||||
|
||||
for test_name in ["viewportIndex choice"]:
|
||||
@@ -86,49 +86,9 @@ class VK_Multi_View(rdtest.TestCase):
|
||||
postvs = self.get_postvs(action, rd.MeshDataStage.VSOut, instance=inst, view=view)
|
||||
for vtx in range(action.numIndices):
|
||||
idx = vtx
|
||||
self.check_debug(vtx, idx, inst, view, postvs)
|
||||
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")
|
||||
|
||||
|
||||
def check_debug(self, vtx, idx, inst, view, postvs):
|
||||
trace: rd.ShaderDebugTrace = self.controller.DebugVertex(vtx, inst, idx, view)
|
||||
|
||||
if trace.debugger is None:
|
||||
self.controller.FreeTrace(trace)
|
||||
|
||||
raise rdtest.TestFailureException("Couldn't debug vertex {} in instance {} for view {}".format(vtx, inst, view))
|
||||
|
||||
cycles, variables = self.process_trace(trace)
|
||||
|
||||
for var in trace.sourceVars:
|
||||
var: rd.SourceVariableMapping
|
||||
if var.variables[0].type == rd.DebugVariableType.Variable and var.signatureIndex >= 0:
|
||||
name = var.name
|
||||
|
||||
if name not in postvs[vtx].keys():
|
||||
raise rdtest.TestFailureException("Don't have expected output for {}".format(name))
|
||||
|
||||
expect = postvs[vtx][name]
|
||||
value = self.evaluate_source_var(var, variables)
|
||||
|
||||
if len(expect) != value.columns:
|
||||
raise rdtest.TestFailureException(
|
||||
"Output {} at vert {} (idx {}) instance {} view {} has different size ({} values) to expectation ({} values)"
|
||||
.format(name, vtx, idx, inst, view, value.columns, len(expect)))
|
||||
|
||||
if value.type == rd.VarType.SInt:
|
||||
debugged = value.value.s32v[0:value.columns]
|
||||
elif value.type == rd.VarType.UInt:
|
||||
debugged = value.value.u32v[0:value.columns]
|
||||
else:
|
||||
debugged = value.value.f32v[0:value.columns]
|
||||
|
||||
if not rdtest.value_compare(expect, debugged):
|
||||
raise rdtest.TestFailureException(
|
||||
"Debugged value {} at vert {} (idx {}) instance {} view {}: {} doesn't exactly match postvs output {}".format(
|
||||
name, vtx, idx, inst, view, debugged, expect))
|
||||
rdtest.log.success('Successfully debugged vertex {} in instance {} for view {}'
|
||||
.format(vtx, inst, view))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user