Use context helpers for pixel history

This commit is contained in:
baldurk committed 2026-09-11 21:17:18 +01:00
1 parent ca682d6d34
commit 01893b9896
9 files changed
+378 -372

No files matched your search

+60 -63
View File
@@ -238,7 +238,6 @@ class Pixel_History(rdtest.TestCase):
x, y = self.relative_xy(110, 100)
rdtest.log.print(f"Testing Unbound PS {x}, {y}")
modifs = self.controller.PixelHistory(tex, x, y, sub, comp)
events = [
{
'event_name': 'Begin RenderPass',
@@ -258,11 +257,11 @@ class Pixel_History(rdtest.TestCase):
'post_mod_stencil': 0x55
},
]
self.check_events(events, modifs)
with self.pixel_history(tex, x, y, sub, comp) as history:
self.check_events(events, history.modifs)
x, y = self.relative_xy(170, 140)
rdtest.log.print(f"Testing Stencil failure {x}, {y}")
modifs = self.controller.PixelHistory(tex, x, y, sub, comp)
events = [
{
'event_name': 'Begin RenderPass',
@@ -288,11 +287,11 @@ class Pixel_History(rdtest.TestCase):
with_stencil('stencil_test_failed'): True
},
]
self.check_events(events, modifs)
with self.pixel_history(tex, x, y, sub, comp) as history:
self.check_events(events, history.modifs)
x, y = self.relative_xy(170, 160)
rdtest.log.print(f"Testing Depth failure {x}, {y}")
modifs = self.controller.PixelHistory(tex, x, y, sub, comp)
events = [
{
'event_name': 'Begin RenderPass',
@@ -315,11 +314,11 @@ class Pixel_History(rdtest.TestCase):
'depth_test_failed': True
},
]
self.check_events(events, modifs)
with self.pixel_history(tex, x, y, sub, comp) as history:
self.check_events(events, history.modifs)
x, y = self.relative_xy(150, 250)
rdtest.log.print(f"Testing Discard {x}, {y}")
modifs = self.controller.PixelHistory(tex, x, y, sub, comp)
events = [
{
'event_name': 'Begin RenderPass',
@@ -330,11 +329,11 @@ class Pixel_History(rdtest.TestCase):
'shader_discarded': True
},
]
self.check_events(events, modifs)
with self.pixel_history(tex, x, y, sub, comp) as history:
self.check_events(events, history.modifs)
x, y = self.relative_xy(330, 145)
rdtest.log.print(f"Testing Primitive ID {x}, {y}")
modifs = self.controller.PixelHistory(tex, x, y, sub, comp)
events = [
{
'event_name': 'Begin RenderPass',
@@ -347,11 +346,11 @@ class Pixel_History(rdtest.TestCase):
'shader_out_col': fmt_adjusted(0, 0, 0, alpha_value)
},
]
self.check_events(events, modifs)
with self.pixel_history(tex, x, y, sub, comp) as history:
self.check_events(events, history.modifs)
x, y = self.relative_xy(340, 145)
rdtest.log.print(f"Testing Depth Clip {x}, {y}")
modifs = self.controller.PixelHistory(tex, x, y, sub, comp)
events = [
{
'event_name': 'Begin RenderPass',
@@ -363,13 +362,13 @@ class Pixel_History(rdtest.TestCase):
'depth_clipped': True
},
]
self.check_events(events, modifs)
with self.pixel_history(tex, x, y, sub, comp) as history:
self.check_events(events, history.modifs)
# if depth bounds test isn't supported these draws won't be emitted
if has_depth_bounds:
x, y = self.relative_xy(330, 102)
rdtest.log.print(f"Testing Depth Bounds Pass {x}, {y}")
modifs = self.controller.PixelHistory(tex, x, y, sub, comp)
events = [
{
'event_name': 'Begin RenderPass',
@@ -388,12 +387,12 @@ class Pixel_History(rdtest.TestCase):
'shader_out_col': fmt_adjusted(0, 1, 0, alpha_value)
},
]
self.check_events(events, modifs)
with self.pixel_history(tex, x, y, sub, comp) as history:
self.check_events(events, history.modifs)
# slightly precise X to ensure it still picks the right edge of the triangle on mip version
x, y = self.relative_xy(318, 102)
rdtest.log.print(f"Testing Depth Bounds Fail {x}, {y}")
modifs = self.controller.PixelHistory(tex, x, y, sub, comp)
events = [
{
'event_name': 'Begin RenderPass',
@@ -411,11 +410,11 @@ class Pixel_History(rdtest.TestCase):
'depth_bounds_failed': True
},
]
self.check_events(events, modifs)
with self.pixel_history(tex, x, y, sub, comp) as history:
self.check_events(events, history.modifs)
x, y = self.relative_xy(346, 102)
rdtest.log.print(f"Testing Depth Bounds Fail {x}, {y}")
modifs = self.controller.PixelHistory(tex, x, y, sub, comp)
events = [
{
'event_name': 'Begin RenderPass',
@@ -433,7 +432,8 @@ class Pixel_History(rdtest.TestCase):
'depth_bounds_failed': True
},
]
self.check_events(events, modifs)
with self.pixel_history(tex, x, y, sub, comp) as history:
self.check_events(events, history.modifs)
rdtest.log.print("Testing stencil/scissor checks")
test_marker = self.find_action("Stencil Mask", base_eid)
@@ -441,7 +441,6 @@ class Pixel_History(rdtest.TestCase):
x, y = self.relative_xy(106, 248)
rdtest.log.print(f"Testing pixel {x}, {y}")
modifs = self.controller.PixelHistory(tex, x, y, sub, comp)
events = [
{
'event_name': 'Begin RenderPass',
@@ -474,7 +473,8 @@ class Pixel_History(rdtest.TestCase):
'post_mod_col': fmt_clamped(0, 1, 1, alpha_value)
},
]
self.check_events(events, modifs)
with self.pixel_history(tex, x, y, sub, comp) as history:
self.check_events(events, history.modifs)
rdtest.log.print("Testing depth test for per fragment reporting")
test_marker = self.find_action("Depth Test", base_eid)
@@ -482,7 +482,6 @@ class Pixel_History(rdtest.TestCase):
x, y = self.relative_xy(275, 258)
rdtest.log.print(f"Testing pixel {x}, {y}")
modifs = self.controller.PixelHistory(tex, x, y, sub, comp)
events = [
{
'event_name': 'Begin RenderPass',
@@ -580,7 +579,8 @@ class Pixel_History(rdtest.TestCase):
'post_mod_col': fmt_clamped(0, 0, 1, alpha_value),
},
]
self.check_events(events, modifs)
with self.pixel_history(tex, x, y, sub, comp) as history:
self.check_events(events, history.modifs)
# For pixel 60, 130 inside the light green triangle which is 300 draws of 1 instance of 1 triangle
rdtest.log.print("Testing Lots of Drawcalls")
@@ -588,38 +588,38 @@ class Pixel_History(rdtest.TestCase):
self.set_event(test_marker.nextAction.eventId, True)
x, y = self.relative_xy(60, 130)
rdtest.log.print(f"Testing pixel {x}, {y}")
modifs = self.controller.PixelHistory(tex, x, y, sub, comp)
if not self.is_secondary:
self.check_final_colour(tex, x, y, modifs, sub, comp)
countEvents = 1 + 300
if len(modifs) != countEvents:
self.error(f"Expected {countEvents} events, got {len(modifs)}")
self.check_modifs_consistent(modifs)
with self.pixel_history(tex, x, y, sub, comp) as history:
if len(history.modifs) != countEvents:
self.error(f"Expected {countEvents} events, got {len(history.modifs)}")
if not self.is_secondary:
self.check_final_colour(tex, x, y, history.modifs, sub, comp)
self.check_modifs_consistent(history.modifs)
# For pixel 60, 50 inside the orange triangle which is 1 draws of 300 instances of 1 triangle
rdtest.log.print("Testing Lots of Instances")
x, y = self.relative_xy(60, 50)
rdtest.log.print(f"Testing pixel {x}, {y}")
modifs = self.controller.PixelHistory(tex, x, y, sub, comp)
if not self.is_secondary:
self.check_final_colour(tex, x, y, modifs, sub, comp)
with self.pixel_history(tex, x, y, sub, comp) as history:
if not self.is_secondary:
self.check_final_colour(tex, x, y, history.modifs, sub, comp)
countEvents = 1 + 255
# secondaries can't count fragment events, so we only get 1 for the draw
if self.is_secondary:
countEvents = 1 + 1
if len(modifs) != countEvents:
self.error(f"Expected {countEvents} events, got {len(modifs)}")
self.check_modifs_consistent(modifs)
countEvents = 1 + 255
# secondaries can't count fragment events, so we only get 1 for the draw
if self.is_secondary:
countEvents = 1 + 1
if len(history.modifs) != countEvents:
self.error(f"Expected {countEvents} events, got {len(history.modifs)}")
self.check_modifs_consistent(history.modifs)
rdtest.log.print("Testing Sample colouring")
test_marker = self.find_action("Sample Colouring", base_eid)
self.set_event(test_marker.nextAction.eventId, True)
x, y = self.relative_xy(330, 200)
rdtest.log.print(f"Testing pixel {x}, {y}")
modifs = self.controller.PixelHistory(tex, x, y, sub, comp)
events = [
{
'event_name': 'Begin RenderPass',
@@ -632,13 +632,12 @@ class Pixel_History(rdtest.TestCase):
'shader_out_col': fmt_adjusted(1, 0, 0, alpha_value)
},
]
self.check_events(events, modifs)
self.check_modifs_consistent(modifs)
with self.pixel_history(tex, x, y, sub, comp) as history:
self.check_events(events, history.modifs)
if tex_details.msSamp == 4:
sub.sample = 1
rdtest.log.print(f"Testing sample {sub.sample}")
modifs = self.controller.PixelHistory(tex, x, y, sub, comp)
events = [
{
'event_name': 'Begin RenderPass',
@@ -651,12 +650,11 @@ class Pixel_History(rdtest.TestCase):
'shader_out_col': fmt_adjusted(0, 0, 1, alpha_value)
},
]
self.check_events(events, modifs)
self.check_modifs_consistent(modifs)
with self.pixel_history(tex, x, y, sub, comp) as history:
self.check_events(events, history.modifs)
sub.sample = 2
rdtest.log.print(f"Testing sample {sub.sample}")
modifs = self.controller.PixelHistory(tex, x, y, sub, comp)
events = [
{
'event_name': 'Begin RenderPass',
@@ -669,12 +667,11 @@ class Pixel_History(rdtest.TestCase):
'shader_out_col': fmt_adjusted(0, 1, 1, alpha_value)
},
]
self.check_events(events, modifs)
self.check_modifs_consistent(modifs)
with self.pixel_history(tex, x, y, sub, comp) as history:
self.check_events(events, history.modifs)
sub.sample = 3
rdtest.log.print(f"Testing sample {sub.sample}")
modifs = self.controller.PixelHistory(tex, x, y, sub, comp)
events = [
{
'event_name': 'Begin RenderPass',
@@ -686,8 +683,8 @@ class Pixel_History(rdtest.TestCase):
'sample_masked': True,
},
]
self.check_events(events, modifs)
self.check_modifs_consistent(modifs)
with self.pixel_history(tex, x, y, sub, comp) as history:
self.check_events(events, history.modifs)
sub.sample = 0
@@ -697,7 +694,6 @@ class Pixel_History(rdtest.TestCase):
x, y = self.relative_xy(200, 250)
rdtest.log.print(f"Testing pixel {x}, {y}")
modifs = self.controller.PixelHistory(tex, x, y, sub, comp)
events = [
{
'event_name': 'Begin RenderPass',
@@ -731,7 +727,8 @@ class Pixel_History(rdtest.TestCase):
'post_mod_col': fmt_clamped(1, 1, 1, alpha_value),
},
]
self.check_events(events, modifs)
with self.pixel_history(tex, x, y, sub, comp) as history:
self.check_events(events, history.modifs)
rdtest.log.print("Testing colour masking")
test_marker = self.find_action("Colour Masked", base_eid)
@@ -739,7 +736,6 @@ class Pixel_History(rdtest.TestCase):
x, y = self.relative_xy(60, 80)
rdtest.log.print(f"Testing pixel {x}, {y}")
modifs = self.controller.PixelHistory(tex, x, y, sub, comp)
events = [
{
'event_name': 'Begin RenderPass',
@@ -752,7 +748,8 @@ class Pixel_History(rdtest.TestCase):
'post_mod_col': fmt_clamped(3, 3, clear_col, 1),
},
]
self.check_events(events, modifs)
with self.pixel_history(tex, x, y, sub, comp) as history:
self.check_events(events, history.modifs)
if self.has_colour:
rdtest.log.print("Testing direct writes")
@@ -763,7 +760,6 @@ class Pixel_History(rdtest.TestCase):
self.set_event(test_marker.nextAction.eventId, True)
x, y = self.relative_xy(225, 85)
rdtest.log.print(f"Testing pixel {x}, {y}")
modifs = self.controller.PixelHistory(tex, x, y, sub, comp)
events = [
{
'event_name': 'Begin RenderPass',
@@ -783,7 +779,8 @@ class Pixel_History(rdtest.TestCase):
'post_mod_col': fmt_clamped(3, 3, 3, 9),
},
]
self.check_events(events, modifs)
with self.pixel_history(tex, x, y, sub, comp) as history:
self.check_events(events, history.modifs)
rdtest.log.print("Testing overflowed writes")
test_marker = self.find_action("Overflowing", base_eid)
@@ -791,7 +788,6 @@ class Pixel_History(rdtest.TestCase):
x, y = self.relative_xy(105, 50)
rdtest.log.print(f"Testing pixel {x}, {y}")
modifs = self.controller.PixelHistory(tex, x, y, sub, comp)
events = [
{
'event_name': 'Begin RenderPass',
@@ -830,7 +826,8 @@ class Pixel_History(rdtest.TestCase):
'post_mod_col': fmt_clamped(0, 0, overflow_value, alpha_value)
},
]
self.check_events(events, modifs)
with self.pixel_history(tex, x, y, sub, comp) as history:
self.check_events(events, history.modifs)
rdtest.log.print("Testing per-fragment discards")
test_marker = self.find_action("Per-Fragment discarding", base_eid)
@@ -838,7 +835,6 @@ class Pixel_History(rdtest.TestCase):
x, y = self.relative_xy(60, 160)
rdtest.log.print(f"Testing pixel {x}, {y}")
modifs = self.controller.PixelHistory(tex, x, y, sub, comp)
events = [
{
'event_name': 'Begin RenderPass',
@@ -878,7 +874,8 @@ class Pixel_History(rdtest.TestCase):
'post_mod_col': fmt_clamped(1, 1, 1, alpha_value),
},
]
self.check_events(events, modifs)
with self.pixel_history(tex, x, y, sub, comp) as history:
self.check_events(events, history.modifs)
if self.has_colour:
x, y = self.relative_xy(120, 110)
@@ -886,7 +883,6 @@ class Pixel_History(rdtest.TestCase):
test_marker = self.find_action("No Output Shader", base_eid)
self.set_event(test_marker.nextAction.eventId, True)
modifs = self.controller.PixelHistory(tex, x, y, sub, comp)
events = [
{
'event_name': 'Begin RenderPass',
@@ -904,7 +900,8 @@ class Pixel_History(rdtest.TestCase):
'primitive_id': 0
},
]
self.check_events(events, modifs)
with self.pixel_history(tex, x, y, sub, comp) as history:
self.check_events(events, history.modifs)
def check_final_colour(self, tex: rd.ResourceId, x: int, y: int, modifs: List[rd.PixelModification], sub: rd.Subresource, comp: rd.CompType):
m = modifs[-1]
@@ -43,85 +43,86 @@ class D3D12_Blend_Pixel_History(rdtest.TestCase):
# Pixel inside of all of the triangles
x, y = 200, 150
rdtest.log.print(f"Testing pixel {x}, {y}")
modifs = self.controller.PixelHistory(tex, x, y, sub, rt.format.compType)
self.check_modifs_consistent(modifs)
red_modifs = [m for m in modifs if m.eventId >= red_eid and m.eventId < red_last_eid]
green_modifs = [m for m in modifs if m.eventId == green_eid]
blue_modifs = [m for m in modifs if m.eventId == blue_eid]
all_modifs = [m for m in modifs if m.eventId == all_eid]
with self.pixel_history(tex, x, y, sub, rt.format.compType) as history:
modifs = history.modifs
self.check_modifs_consistent(modifs)
red_modifs = [m for m in modifs if m.eventId >= red_eid and m.eventId < red_last_eid]
green_modifs = [m for m in modifs if m.eventId == green_eid]
blue_modifs = [m for m in modifs if m.eventId == blue_eid]
all_modifs = [m for m in modifs if m.eventId == all_eid]
if len(red_modifs) != NUM_TRIANGLES_RED_REAL:
raise rdtest.TestFailureException(f"Expected {NUM_TRIANGLES_RED_REAL} modifications for red triangles (EIDS {red_eid} until {red_last_eid}) but got {len(red_modifs)}")
if len(red_modifs) != NUM_TRIANGLES_RED_REAL:
raise rdtest.TestFailureException(f"Expected {NUM_TRIANGLES_RED_REAL} modifications for red triangles (EIDS {red_eid} until {red_last_eid}) but got {len(red_modifs)}")
for i, modif in enumerate(red_modifs):
if not rdtest.value_compare(modif.shaderOut.col.floatValue, (1.0/255.0, 0.0, 0.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong shader output for red triangle {i}; got {modif.shaderOut.col.floatValue}, wanted {(1.0 / 255.0, 0.0, 0.0, 1.0)}")
if not rdtest.value_compare(modif.postMod.col.floatValue, ((i+1)/255.0, 0.0, 0.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong post mod for red triangle {i}; got {modif.postMod.col.floatValue}, wanted {((i + 1) / 255.0, 0.0, 0.0, 1.0)}")
i = 1
eid_counter = 0
modif_counter = 0
while i <= NUM_TRIANGLES_RED:
for primitive_id in range(i):
if red_modifs[modif_counter].eventId != red_eid + eid_counter:
raise rdtest.TestFailureException(f"Expected red triangle {modif_counter} to be part of EID {red_eid + eid_counter} but was {red_modifs[modif_counter].eventId}")
if red_modifs[modif_counter].primitiveID != primitive_id:
raise rdtest.TestFailureException(f"Expected red triangle {modif_counter} to have primitive ID {primitive_id} but was {red_modifs[modif_counter].primitiveID}")
modif_counter += 1
eid_counter += 1
i *= 2
if len(green_modifs) != NUM_TRIANGLES_GREEN:
raise rdtest.TestFailureException(f"Expected {NUM_TRIANGLES_GREEN} modifications for green triangles (EID {green_eid}) but got {len(green_modifs)}")
for i, modif in enumerate(green_modifs):
if modif.primitiveID != i:
raise rdtest.TestFailureException(f"Expected green triangle {i} to have primitive ID {modif.primitiveID} but was {modif.primitiveID}")
if not rdtest.value_compare(modif.shaderOut.col.floatValue, (0.0, 1.0/255.0, 0.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong shader output for green triangle {i}; got {modif.shaderOut.col.floatValue}, wanted {(0.0, 1.0 / 255.0, 0.0, 1.0)}")
if not rdtest.value_compare(modif.postMod.col.floatValue, (NUM_TRIANGLES_RED_REAL/255.0, (i+1)/255.0, 0.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong post mod for green triangle {i}; got {modif.postMod.col.floatValue}, wanted {(NUM_TRIANGLES_RED_REAL / 255.0, (i + 1) / 255.0, 0.0, 1.0)}")
# We can only record 255 modifications due to the stencil format
if len(blue_modifs) != 255:
raise rdtest.TestFailureException(f"Expected {255} modifications for blue triangles (EID {blue_eid}) but got {len(blue_modifs)}")
for i, modif in enumerate(blue_modifs):
if modif.primitiveID != i:
raise rdtest.TestFailureException(f"Expected blue triangle {i} to have primitive ID {modif.primitiveID} but was {modif.primitiveID}")
if not rdtest.value_compare(modif.shaderOut.col.floatValue, (0.0, 0.0, 1.0/255.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong shader output for blue triangle {i}; got {modif.shaderOut.col.floatValue}, wanted {(0.0, 0.0, 1.0 / 255.0, 1.0)}")
if i == 254:
if not rdtest.value_compare(modif.postMod.col.floatValue, (NUM_TRIANGLES_RED_REAL/255.0, 1.0, NUM_TRIANGLES_BLUE/255.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong post mod for final blue triangle {i}; got {modif.postMod.col.floatValue}, wanted {(NUM_TRIANGLES_RED_REAL / 255.0, 1.0, NUM_TRIANGLES_BLUE / 255.0, 1.0)}")
else:
if not rdtest.value_compare(modif.postMod.col.floatValue, (NUM_TRIANGLES_RED_REAL/255.0, 1.0, (i+1)/255.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong post mod for blue triangle {i}; got {modif.postMod.col.floatValue}, wanted {(NUM_TRIANGLES_RED_REAL / 255.0, 1.0, (i + 1) / 255.0, 1.0)}")
# Once again, we can only record 255 modifications due to the stencil format
if len(all_modifs) != 255:
raise rdtest.TestFailureException(f"Expected {255} modifications for all triangles (EID {all_eid}) but got {len(all_modifs)}")
for i, modif in enumerate(all_modifs):
if modif.primitiveID != i:
raise rdtest.TestFailureException(f"Expected triangle {i} in all to have primitive ID {modif.primitiveID} but was {modif.primitiveID}")
if i < NUM_TRIANGLES_RED:
for i, modif in enumerate(red_modifs):
if not rdtest.value_compare(modif.shaderOut.col.floatValue, (1.0/255.0, 0.0, 0.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong shader output for red triangle in all {i}; got {modif.shaderOut.col.floatValue}, wanted {(1.0 / 255.0, 0.0, 0.0, 1.0)}")
raise rdtest.TestFailureException(f"Wrong shader output for red triangle {i}; got {modif.shaderOut.col.floatValue}, wanted {(1.0 / 255.0, 0.0, 0.0, 1.0)}")
if not rdtest.value_compare(modif.postMod.col.floatValue, ((i+1)/255.0, 0.0, 0.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong post mod for red triangle in all {i}; got {modif.postMod.col.floatValue}, wanted {((i + 1) / 255.0, 0.0, 0.0, 1.0)}")
else:
raise rdtest.TestFailureException(f"Wrong post mod for red triangle {i}; got {modif.postMod.col.floatValue}, wanted {((i + 1) / 255.0, 0.0, 0.0, 1.0)}")
i = 1
eid_counter = 0
modif_counter = 0
while i <= NUM_TRIANGLES_RED:
for primitive_id in range(i):
if red_modifs[modif_counter].eventId != red_eid + eid_counter:
raise rdtest.TestFailureException(f"Expected red triangle {modif_counter} to be part of EID {red_eid + eid_counter} but was {red_modifs[modif_counter].eventId}")
if red_modifs[modif_counter].primitiveID != primitive_id:
raise rdtest.TestFailureException(f"Expected red triangle {modif_counter} to have primitive ID {primitive_id} but was {red_modifs[modif_counter].primitiveID}")
modif_counter += 1
eid_counter += 1
i *= 2
if len(green_modifs) != NUM_TRIANGLES_GREEN:
raise rdtest.TestFailureException(f"Expected {NUM_TRIANGLES_GREEN} modifications for green triangles (EID {green_eid}) but got {len(green_modifs)}")
for i, modif in enumerate(green_modifs):
if modif.primitiveID != i:
raise rdtest.TestFailureException(f"Expected green triangle {i} to have primitive ID {modif.primitiveID} but was {modif.primitiveID}")
if not rdtest.value_compare(modif.shaderOut.col.floatValue, (0.0, 1.0/255.0, 0.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong shader output for green triangle in all {i}; got {modif.shaderOut.col.floatValue}, wanted {(0.0, 1.0 / 255.0, 0.0, 1.0)}")
if i != 254:
if not rdtest.value_compare(modif.postMod.col.floatValue, (NUM_TRIANGLES_RED/255.0, (i+1-NUM_TRIANGLES_RED)/255.0, 0.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong post mod for green triangle in all {i}; got {modif.postMod.col.floatValue}, wanted {(NUM_TRIANGLES_RED / 255.0, (i + 1 - NUM_TRIANGLES_RED) / 255.0, 0.0, 1.0)}")
raise rdtest.TestFailureException(f"Wrong shader output for green triangle {i}; got {modif.shaderOut.col.floatValue}, wanted {(0.0, 1.0 / 255.0, 0.0, 1.0)}")
if not rdtest.value_compare(modif.postMod.col.floatValue, (NUM_TRIANGLES_RED_REAL/255.0, (i+1)/255.0, 0.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong post mod for green triangle {i}; got {modif.postMod.col.floatValue}, wanted {(NUM_TRIANGLES_RED_REAL / 255.0, (i + 1) / 255.0, 0.0, 1.0)}")
# We can only record 255 modifications due to the stencil format
if len(blue_modifs) != 255:
raise rdtest.TestFailureException(f"Expected {255} modifications for blue triangles (EID {blue_eid}) but got {len(blue_modifs)}")
for i, modif in enumerate(blue_modifs):
if modif.primitiveID != i:
raise rdtest.TestFailureException(f"Expected blue triangle {i} to have primitive ID {modif.primitiveID} but was {modif.primitiveID}")
if not rdtest.value_compare(modif.shaderOut.col.floatValue, (0.0, 0.0, 1.0/255.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong shader output for blue triangle {i}; got {modif.shaderOut.col.floatValue}, wanted {(0.0, 0.0, 1.0 / 255.0, 1.0)}")
if i == 254:
if not rdtest.value_compare(modif.postMod.col.floatValue, (NUM_TRIANGLES_RED_REAL/255.0, 1.0, NUM_TRIANGLES_BLUE/255.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong post mod for final blue triangle {i}; got {modif.postMod.col.floatValue}, wanted {(NUM_TRIANGLES_RED_REAL / 255.0, 1.0, NUM_TRIANGLES_BLUE / 255.0, 1.0)}")
else:
# For i = 254 (the last triangle), the post-mod value is always set to the final post-mod value, but everything else is correctly set to the 255th modification
if not rdtest.value_compare(modif.postMod.col.floatValue, (NUM_TRIANGLES_RED/255.0, 1.0, NUM_TRIANGLES_BLUE/255.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong post mod for final (blue) triangle in all {i}; got {modif.postMod.col.floatValue}, wanted {(NUM_TRIANGLES_RED / 255.0, 1.0, NUM_TRIANGLES_BLUE / 255.0, 1.0)}")
if not rdtest.value_compare(modif.postMod.col.floatValue, (NUM_TRIANGLES_RED_REAL/255.0, 1.0, (i+1)/255.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong post mod for blue triangle {i}; got {modif.postMod.col.floatValue}, wanted {(NUM_TRIANGLES_RED_REAL / 255.0, 1.0, (i + 1) / 255.0, 1.0)}")
# Once again, we can only record 255 modifications due to the stencil format
if len(all_modifs) != 255:
raise rdtest.TestFailureException(f"Expected {255} modifications for all triangles (EID {all_eid}) but got {len(all_modifs)}")
for i, modif in enumerate(all_modifs):
if modif.primitiveID != i:
raise rdtest.TestFailureException(f"Expected triangle {i} in all to have primitive ID {modif.primitiveID} but was {modif.primitiveID}")
if i < NUM_TRIANGLES_RED:
if not rdtest.value_compare(modif.shaderOut.col.floatValue, (1.0/255.0, 0.0, 0.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong shader output for red triangle in all {i}; got {modif.shaderOut.col.floatValue}, wanted {(1.0 / 255.0, 0.0, 0.0, 1.0)}")
if not rdtest.value_compare(modif.postMod.col.floatValue, ((i+1)/255.0, 0.0, 0.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong post mod for red triangle in all {i}; got {modif.postMod.col.floatValue}, wanted {((i + 1) / 255.0, 0.0, 0.0, 1.0)}")
else:
if not rdtest.value_compare(modif.shaderOut.col.floatValue, (0.0, 1.0/255.0, 0.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong shader output for green triangle in all {i}; got {modif.shaderOut.col.floatValue}, wanted {(0.0, 1.0 / 255.0, 0.0, 1.0)}")
if i != 254:
if not rdtest.value_compare(modif.postMod.col.floatValue, (NUM_TRIANGLES_RED/255.0, (i+1-NUM_TRIANGLES_RED)/255.0, 0.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong post mod for green triangle in all {i}; got {modif.postMod.col.floatValue}, wanted {(NUM_TRIANGLES_RED / 255.0, (i + 1 - NUM_TRIANGLES_RED) / 255.0, 0.0, 1.0)}")
else:
# For i = 254 (the last triangle), the post-mod value is always set to the final post-mod value, but everything else is correctly set to the 255th modification
if not rdtest.value_compare(modif.postMod.col.floatValue, (NUM_TRIANGLES_RED/255.0, 1.0, NUM_TRIANGLES_BLUE/255.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong post mod for final (blue) triangle in all {i}; got {modif.postMod.col.floatValue}, wanted {(NUM_TRIANGLES_RED / 255.0, 1.0, NUM_TRIANGLES_BLUE / 255.0, 1.0)}")
def check_modifs_consistent(self, modifs: List[rd.PixelModification]):
# postmod of each should match premod of the next
@@ -47,10 +47,10 @@ class D3D12_Execute_Indirect(rdtest.TestCase):
rt = pipe.GetOutputTargets()[0]
tex = rt.resource
sub = rd.Subresource()
modifs = self.controller.PixelHistory(tex, x, y, sub, rt.format.compType)
if len(modifs) < 2:
raise rdtest.TestFailureException(f"No pixel history found at ({x}, {y})")
rdtest.log.success(f"Pixel History {x}, {y} Worked")
with self.pixel_history(tex, x, y, sub, rt.format.compType) as history:
if len(history.modifs) < 2:
raise rdtest.TestFailureException(f"No pixel history found at ({x}, {y})")
rdtest.log.success(f"Pixel History {x}, {y} Worked")
def check_root_consts(self, expected: List[float]):
pipe = self.controller.GetPipelineState()
+92 -91
View File
@@ -202,128 +202,129 @@ class Iter_Test(rdtest.TestCase):
rdtest.log.print("Fetching history for %d,%d on target %s" % (x, y, str(target)))
history = self.controller.PixelHistory(target, x, y, rd.Subresource(0, 0, 0), rd.CompType.Typeless)
with self.pixel_history(target, x, y, rd.Subresource(0, 0, 0), rd.CompType.Typeless) as history:
modifs = history.modifs
rdtest.log.success("Pixel %d,%d has %d history events" % (x, y, len(history)))
rdtest.log.success("Pixel %d,%d has %d history events" % (x, y, len(modifs)))
lastmod = None
lastmod = None
for i in reversed(range(len(history))):
mod = history[i]
next_action = self.find_action('', mod.eventId)
for i in reversed(range(len(modifs))):
mod = modifs[i]
next_action = self.find_action('', mod.eventId)
if next_action is None:
continue
action = next_action
if not(action.flags & rd.ActionFlags.Drawcall):
if action.drawIndex == 0:
continue
if not(action.flags & rd.ActionFlags.Clear):
continue
if not(action.flags & rd.ActionFlags.Copy):
continue
if not(action.flags & rd.ActionFlags.Resolve):
if next_action is None:
continue
rdtest.log.print(" hit %d at %d (%s)" % (i, mod.eventId, str(action.flags)))
action = next_action
lastmod = history[i]
if not(action.flags & rd.ActionFlags.Drawcall):
if action.drawIndex == 0:
continue
if not(action.flags & rd.ActionFlags.Clear):
continue
if not(action.flags & rd.ActionFlags.Copy):
continue
if not(action.flags & rd.ActionFlags.Resolve):
continue
rdtest.log.print("Got a hit on a action at event %d" % lastmod.eventId)
rdtest.log.print(" hit %d at %d (%s)" % (i, mod.eventId, str(action.flags)))
if mod.sampleMasked or mod.backfaceCulled or mod.depthClipped or mod.viewClipped or mod.scissorClipped or mod.shaderDiscarded or mod.depthTestFailed or mod.stencilTestFailed:
rdtest.log.print("This hit failed, looking for one that passed....")
lastmod = None
continue
lastmod = modifs[i]
if not mod.shaderOut.IsValid():
rdtest.log.print("This hit's shader out is not valid, looking for one that valid....")
lastmod = None
continue
rdtest.log.print("Got a hit on a action at event %d" % lastmod.eventId)
if mod.primitiveID == 0xffffffff:
rdtest.log.print("This hit's primitive ID is invalid, looking for one that is valid....")
lastmod = None
continue
if mod.sampleMasked or mod.backfaceCulled or mod.depthClipped or mod.viewClipped or mod.scissorClipped or mod.shaderDiscarded or mod.depthTestFailed or mod.stencilTestFailed:
rdtest.log.print("This hit failed, looking for one that passed....")
lastmod = None
continue
break
if not mod.shaderOut.IsValid():
rdtest.log.print("This hit's shader out is not valid, looking for one that valid....")
lastmod = None
continue
if target == pipe.GetDepthTarget().resource:
rdtest.log.print("Not doing pixel debug for depth output")
return
if mod.primitiveID == 0xffffffff:
rdtest.log.print("This hit's primitive ID is invalid, looking for one that is valid....")
lastmod = None
continue
if lastmod is not None:
rdtest.log.print(f"Debugging pixel {x},{y} @ {lastmod.eventId}, primitive {lastmod.primitiveID}")
self.set_event(lastmod.eventId, True)
break
pipe = self.controller.GetPipelineState()
refl = pipe.GetShaderReflection(rd.ShaderStage.Pixel)
if refl is None:
rdtest.log.print(f"Nothing to debug. No pixel shader bound at {action.eventId}")
if target == pipe.GetDepthTarget().resource:
rdtest.log.print("Not doing pixel debug for depth output")
return
if not refl.debugInfo.debuggable:
rdtest.log.print(f"Pixel shader is not debuggable at {action.eventId}")
return
if lastmod is not None:
rdtest.log.print(f"Debugging pixel {x},{y} @ {lastmod.eventId}, primitive {lastmod.primitiveID}")
self.set_event(lastmod.eventId, True)
inputs = rd.DebugPixelInputs()
inputs.sample = 0
inputs.primitive = lastmod.primitiveID;
with self.debug_pixel(x, y, inputs) as debug:
try:
cycles, variables = self.process_trace(debug.trace)
except rdtest.TestFailureException as err:
rdtest.log.error(f"Error debugging: {err.message}")
pipe = self.controller.GetPipelineState()
refl = pipe.GetShaderReflection(rd.ShaderStage.Pixel)
if refl is None:
rdtest.log.print(f"Nothing to debug. No pixel shader bound at {action.eventId}")
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')
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}")
if not refl.debugInfo.debuggable:
rdtest.log.print(f"Pixel shader is not debuggable at {action.eventId}")
return
inputs = rd.DebugPixelInputs()
inputs.sample = 0
inputs.primitive = lastmod.primitiveID;
with self.debug_pixel(x, y, inputs) as debug:
try:
output_sourcevar = self.find_output_source_var(debug.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)
debuggedValue = list(debugged.value.f32v[0:4])
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}")
# 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]
try:
output_sourcevar = self.find_output_source_var(debug.trace, rd.ShaderBuiltin.ColorOutput, output_index)
historyValue = list(lastmod.shaderOut.col.floatValue)
debugged = self.evaluate_source_var(output_sourcevar, variables)
tex = self.get_texture(target)
debuggedValue = list(debugged.value.f32v[0:4])
historyValue = historyValue[0:tex.format.compCount]
debuggedValue = debuggedValue[0:tex.format.compCount]
# 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]
# 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}")
historyValue = list(lastmod.shaderOut.col.floatValue)
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}")
tex = self.get_texture(target)
self.set_event(action.eventId, True)
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)
def mesh_output(self, action: rd.ActionDescription):
self.controller.GetPostVSData(0, 0, rd.MeshDataStage.VSOut)
@@ -46,85 +46,86 @@ class VK_Blend_Pixel_History(rdtest.TestCase):
# Pixel inside of all of the triangles
x, y = 200, 150
rdtest.log.print(f"Testing pixel {x}, {y}")
modifs = self.controller.PixelHistory(tex, x, y, sub, rt.format.compType)
self.check_modifs_consistent(modifs)
red_modifs = [m for m in modifs if m.eventId >= red_eid and m.eventId < red_last_eid]
green_modifs = [m for m in modifs if m.eventId == green_eid]
blue_modifs = [m for m in modifs if m.eventId == blue_eid]
all_modifs = [m for m in modifs if m.eventId == all_eid]
with self.pixel_history(tex, x, y, sub, rt.format.compType) as history:
modifs = history.modifs
self.check_modifs_consistent(modifs)
red_modifs = [m for m in modifs if m.eventId >= red_eid and m.eventId < red_last_eid]
green_modifs = [m for m in modifs if m.eventId == green_eid]
blue_modifs = [m for m in modifs if m.eventId == blue_eid]
all_modifs = [m for m in modifs if m.eventId == all_eid]
if len(red_modifs) != NUM_TRIANGLES_RED_REAL:
raise rdtest.TestFailureException(f"Expected {NUM_TRIANGLES_RED_REAL} modifications for red triangles (EIDS {red_eid} until {red_last_eid}) but got {len(red_modifs)}")
if len(red_modifs) != NUM_TRIANGLES_RED_REAL:
raise rdtest.TestFailureException(f"Expected {NUM_TRIANGLES_RED_REAL} modifications for red triangles (EIDS {red_eid} until {red_last_eid}) but got {len(red_modifs)}")
for i, modif in enumerate(red_modifs):
if not rdtest.value_compare(modif.shaderOut.col.floatValue, (1.0/255.0, 0.0, 0.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong shader output for red triangle {i}; got {modif.shaderOut.col.floatValue}, wanted {(1.0 / 255.0, 0.0, 0.0, 1.0)}")
if not rdtest.value_compare(modif.postMod.col.floatValue, ((i+1)/255.0, 0.0, 0.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong post mod for red triangle {i}; got {modif.postMod.col.floatValue}, wanted {((i + 1) / 255.0, 0.0, 0.0, 1.0)}")
i = 1
eid_counter = 0
modif_counter = 0
while i <= NUM_TRIANGLES_RED:
for primitive_id in range(i):
if red_modifs[modif_counter].eventId != red_eid + eid_counter:
raise rdtest.TestFailureException(f"Expected red triangle {modif_counter} to be part of EID {red_eid + eid_counter} but was {red_modifs[modif_counter].eventId}")
if red_modifs[modif_counter].primitiveID != primitive_id:
raise rdtest.TestFailureException(f"Expected red triangle {modif_counter} to have primitive ID {primitive_id} but was {red_modifs[modif_counter].primitiveID}")
modif_counter += 1
eid_counter += 1
i *= 2
if len(green_modifs) != NUM_TRIANGLES_GREEN:
raise rdtest.TestFailureException(f"Expected {NUM_TRIANGLES_GREEN} modifications for green triangles (EID {green_eid}) but got {len(green_modifs)}")
for i, modif in enumerate(green_modifs):
if modif.primitiveID != i:
raise rdtest.TestFailureException(f"Expected green triangle {i} to have primitive ID {modif.primitiveID} but was {modif.primitiveID}")
if not rdtest.value_compare(modif.shaderOut.col.floatValue, (0.0, 1.0/255.0, 0.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong shader output for green triangle {i}; got {modif.shaderOut.col.floatValue}, wanted {(0.0, 1.0 / 255.0, 0.0, 1.0)}")
if not rdtest.value_compare(modif.postMod.col.floatValue, (NUM_TRIANGLES_RED_REAL/255.0, (i+1)/255.0, 0.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong post mod for green triangle {i}; got {modif.postMod.col.floatValue}, wanted {(NUM_TRIANGLES_RED_REAL / 255.0, (i + 1) / 255.0, 0.0, 1.0)}")
# We can only record 255 modifications due to the stencil format
if len(blue_modifs) != 255:
raise rdtest.TestFailureException(f"Expected {255} modifications for blue triangles (EID {blue_eid}) but got {len(blue_modifs)}")
for i, modif in enumerate(blue_modifs):
if modif.primitiveID != i:
raise rdtest.TestFailureException(f"Expected blue triangle {i} to have primitive ID {modif.primitiveID} but was {modif.primitiveID}")
if not rdtest.value_compare(modif.shaderOut.col.floatValue, (0.0, 0.0, 1.0/255.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong shader output for blue triangle {i}; got {modif.shaderOut.col.floatValue}, wanted {(0.0, 0.0, 1.0 / 255.0, 1.0)}")
if i == 254:
if not rdtest.value_compare(modif.postMod.col.floatValue, (NUM_TRIANGLES_RED_REAL/255.0, 1.0, NUM_TRIANGLES_BLUE/255.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong post mod for final blue triangle {i}; got {modif.postMod.col.floatValue}, wanted {(NUM_TRIANGLES_RED_REAL / 255.0, 1.0, NUM_TRIANGLES_BLUE / 255.0, 1.0)}")
else:
if not rdtest.value_compare(modif.postMod.col.floatValue, (NUM_TRIANGLES_RED_REAL/255.0, 1.0, (i+1)/255.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong post mod for blue triangle {i}; got {modif.postMod.col.floatValue}, wanted {(NUM_TRIANGLES_RED_REAL / 255.0, 1.0, (i + 1) / 255.0, 1.0)}")
# Once again, we can only record 255 modifications due to the stencil format
if len(all_modifs) != 255:
raise rdtest.TestFailureException(f"Expected {255} modifications for all triangles (EID {all_eid}) but got {len(all_modifs)}")
for i, modif in enumerate(all_modifs):
if modif.primitiveID != i:
raise rdtest.TestFailureException(f"Expected triangle {i} in all to have primitive ID {modif.primitiveID} but was {modif.primitiveID}")
if i < NUM_TRIANGLES_RED:
for i, modif in enumerate(red_modifs):
if not rdtest.value_compare(modif.shaderOut.col.floatValue, (1.0/255.0, 0.0, 0.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong shader output for red triangle in all {i}; got {modif.shaderOut.col.floatValue}, wanted {(1.0 / 255.0, 0.0, 0.0, 1.0)}")
raise rdtest.TestFailureException(f"Wrong shader output for red triangle {i}; got {modif.shaderOut.col.floatValue}, wanted {(1.0 / 255.0, 0.0, 0.0, 1.0)}")
if not rdtest.value_compare(modif.postMod.col.floatValue, ((i+1)/255.0, 0.0, 0.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong post mod for red triangle in all {i}; got {modif.postMod.col.floatValue}, wanted {((i + 1) / 255.0, 0.0, 0.0, 1.0)}")
else:
raise rdtest.TestFailureException(f"Wrong post mod for red triangle {i}; got {modif.postMod.col.floatValue}, wanted {((i + 1) / 255.0, 0.0, 0.0, 1.0)}")
i = 1
eid_counter = 0
modif_counter = 0
while i <= NUM_TRIANGLES_RED:
for primitive_id in range(i):
if red_modifs[modif_counter].eventId != red_eid + eid_counter:
raise rdtest.TestFailureException(f"Expected red triangle {modif_counter} to be part of EID {red_eid + eid_counter} but was {red_modifs[modif_counter].eventId}")
if red_modifs[modif_counter].primitiveID != primitive_id:
raise rdtest.TestFailureException(f"Expected red triangle {modif_counter} to have primitive ID {primitive_id} but was {red_modifs[modif_counter].primitiveID}")
modif_counter += 1
eid_counter += 1
i *= 2
if len(green_modifs) != NUM_TRIANGLES_GREEN:
raise rdtest.TestFailureException(f"Expected {NUM_TRIANGLES_GREEN} modifications for green triangles (EID {green_eid}) but got {len(green_modifs)}")
for i, modif in enumerate(green_modifs):
if modif.primitiveID != i:
raise rdtest.TestFailureException(f"Expected green triangle {i} to have primitive ID {modif.primitiveID} but was {modif.primitiveID}")
if not rdtest.value_compare(modif.shaderOut.col.floatValue, (0.0, 1.0/255.0, 0.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong shader output for green triangle in all {i}; got {modif.shaderOut.col.floatValue}, wanted {(0.0, 1.0 / 255.0, 0.0, 1.0)}")
if i != 254:
if not rdtest.value_compare(modif.postMod.col.floatValue, (NUM_TRIANGLES_RED/255.0, (i+1-NUM_TRIANGLES_RED)/255.0, 0.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong post mod for green triangle in all {i}; got {modif.postMod.col.floatValue}, wanted {(NUM_TRIANGLES_RED / 255.0, (i + 1 - NUM_TRIANGLES_RED) / 255.0, 0.0, 1.0)}")
raise rdtest.TestFailureException(f"Wrong shader output for green triangle {i}; got {modif.shaderOut.col.floatValue}, wanted {(0.0, 1.0 / 255.0, 0.0, 1.0)}")
if not rdtest.value_compare(modif.postMod.col.floatValue, (NUM_TRIANGLES_RED_REAL/255.0, (i+1)/255.0, 0.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong post mod for green triangle {i}; got {modif.postMod.col.floatValue}, wanted {(NUM_TRIANGLES_RED_REAL / 255.0, (i + 1) / 255.0, 0.0, 1.0)}")
# We can only record 255 modifications due to the stencil format
if len(blue_modifs) != 255:
raise rdtest.TestFailureException(f"Expected {255} modifications for blue triangles (EID {blue_eid}) but got {len(blue_modifs)}")
for i, modif in enumerate(blue_modifs):
if modif.primitiveID != i:
raise rdtest.TestFailureException(f"Expected blue triangle {i} to have primitive ID {modif.primitiveID} but was {modif.primitiveID}")
if not rdtest.value_compare(modif.shaderOut.col.floatValue, (0.0, 0.0, 1.0/255.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong shader output for blue triangle {i}; got {modif.shaderOut.col.floatValue}, wanted {(0.0, 0.0, 1.0 / 255.0, 1.0)}")
if i == 254:
if not rdtest.value_compare(modif.postMod.col.floatValue, (NUM_TRIANGLES_RED_REAL/255.0, 1.0, NUM_TRIANGLES_BLUE/255.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong post mod for final blue triangle {i}; got {modif.postMod.col.floatValue}, wanted {(NUM_TRIANGLES_RED_REAL / 255.0, 1.0, NUM_TRIANGLES_BLUE / 255.0, 1.0)}")
else:
# For i = 254 (the last triangle), the post-mod value is always set to the final post-mod value, but everything else is correctly set to the 255th modification
if not rdtest.value_compare(modif.postMod.col.floatValue, (NUM_TRIANGLES_RED/255.0, 1.0, NUM_TRIANGLES_BLUE/255.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong post mod for final (blue) triangle in all {i}; got {modif.postMod.col.floatValue}, wanted {(NUM_TRIANGLES_RED / 255.0, 1.0, NUM_TRIANGLES_BLUE / 255.0, 1.0)}")
if not rdtest.value_compare(modif.postMod.col.floatValue, (NUM_TRIANGLES_RED_REAL/255.0, 1.0, (i+1)/255.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong post mod for blue triangle {i}; got {modif.postMod.col.floatValue}, wanted {(NUM_TRIANGLES_RED_REAL / 255.0, 1.0, (i + 1) / 255.0, 1.0)}")
# Once again, we can only record 255 modifications due to the stencil format
if len(all_modifs) != 255:
raise rdtest.TestFailureException(f"Expected {255} modifications for all triangles (EID {all_eid}) but got {len(all_modifs)}")
for i, modif in enumerate(all_modifs):
if modif.primitiveID != i:
raise rdtest.TestFailureException(f"Expected triangle {i} in all to have primitive ID {modif.primitiveID} but was {modif.primitiveID}")
if i < NUM_TRIANGLES_RED:
if not rdtest.value_compare(modif.shaderOut.col.floatValue, (1.0/255.0, 0.0, 0.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong shader output for red triangle in all {i}; got {modif.shaderOut.col.floatValue}, wanted {(1.0 / 255.0, 0.0, 0.0, 1.0)}")
if not rdtest.value_compare(modif.postMod.col.floatValue, ((i+1)/255.0, 0.0, 0.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong post mod for red triangle in all {i}; got {modif.postMod.col.floatValue}, wanted {((i + 1) / 255.0, 0.0, 0.0, 1.0)}")
else:
if not rdtest.value_compare(modif.shaderOut.col.floatValue, (0.0, 1.0/255.0, 0.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong shader output for green triangle in all {i}; got {modif.shaderOut.col.floatValue}, wanted {(0.0, 1.0 / 255.0, 0.0, 1.0)}")
if i != 254:
if not rdtest.value_compare(modif.postMod.col.floatValue, (NUM_TRIANGLES_RED/255.0, (i+1-NUM_TRIANGLES_RED)/255.0, 0.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong post mod for green triangle in all {i}; got {modif.postMod.col.floatValue}, wanted {(NUM_TRIANGLES_RED / 255.0, (i + 1 - NUM_TRIANGLES_RED) / 255.0, 0.0, 1.0)}")
else:
# For i = 254 (the last triangle), the post-mod value is always set to the final post-mod value, but everything else is correctly set to the 255th modification
if not rdtest.value_compare(modif.postMod.col.floatValue, (NUM_TRIANGLES_RED/255.0, 1.0, NUM_TRIANGLES_BLUE/255.0, 1.0), eps=1.0/256.0):
raise rdtest.TestFailureException(f"Wrong post mod for final (blue) triangle in all {i}; got {modif.postMod.col.floatValue}, wanted {(NUM_TRIANGLES_RED / 255.0, 1.0, NUM_TRIANGLES_BLUE / 255.0, 1.0)}")
def check_modifs_consistent(self, modifs: List[rd.PixelModification]):
# postmod of each should match premod of the next
+18 -17
View File
@@ -46,23 +46,24 @@ class VK_Custom_Resolve(rdtest.TestCase):
sub = rd.Subresource()
x = 200
y = 150
modifs = self.controller.PixelHistory(tex, x, y, sub, rt.format.compType)
if len(modifs) != len(passed):
raise rdtest.TestFailureException(f"Pixel history incorrect modifications count expected:{len(passed)} actual:{len(modifs)}")
for i, m in enumerate(modifs):
if m.Passed() != passed[i]:
raise rdtest.TestFailureException(f"EID:{m.eventId} Pixel history incorrect passed expected:{passed[i]} actual:{m.Passed()}")
if m.preMod.IsValid() != preModValid[i]:
raise rdtest.TestFailureException(f"EID:{m.eventId} Pixel history incorrect pre mod valid expected:{preModValid[i]} actual:{m.preMod.IsValid()}")
if m.preMod.IsValid():
if not rdtest.util.value_compare(m.preMod.col.floatValue, preMod[i], eps=1.0/255.0):
raise rdtest.TestFailureException(f"EID:{m.eventId} Pixel history incorrect pre mod expected:{preMod[i]} actual:{m.preMod.col.floatValue}")
if m.postMod.IsValid() != postModValid[i]:
raise rdtest.TestFailureException(f"EID:{m.eventId} Pixel history incorrect post mod valid expected:{postModValid[i]} actual:{m.postMod.IsValid()}")
if m.postMod.IsValid():
if not rdtest.util.value_compare(m.postMod.col.floatValue, postMod[i], eps=1.0/255.0):
raise rdtest.TestFailureException(f"EID:{m.eventId} Pixel history incorrect post mod expected:{postMod[i]} actual:{m.postMod.col.floatValue}")
rdtest.log.success(f"Pixel History Worked {len(modifs)} modifications found")
with self.pixel_history(tex, x, y, sub, rt.format.compType) as history:
modifs = history.modifs
if len(modifs) != len(passed):
raise rdtest.TestFailureException(f"Pixel history incorrect modifications count expected:{len(passed)} actual:{len(modifs)}")
for i, m in enumerate(modifs):
if m.Passed() != passed[i]:
raise rdtest.TestFailureException(f"EID:{m.eventId} Pixel history incorrect passed expected:{passed[i]} actual:{m.Passed()}")
if m.preMod.IsValid() != preModValid[i]:
raise rdtest.TestFailureException(f"EID:{m.eventId} Pixel history incorrect pre mod valid expected:{preModValid[i]} actual:{m.preMod.IsValid()}")
if m.preMod.IsValid():
if not rdtest.util.value_compare(m.preMod.col.floatValue, preMod[i], eps=1.0/255.0):
raise rdtest.TestFailureException(f"EID:{m.eventId} Pixel history incorrect pre mod expected:{preMod[i]} actual:{m.preMod.col.floatValue}")
if m.postMod.IsValid() != postModValid[i]:
raise rdtest.TestFailureException(f"EID:{m.eventId} Pixel history incorrect post mod valid expected:{postModValid[i]} actual:{m.postMod.IsValid()}")
if m.postMod.IsValid():
if not rdtest.util.value_compare(m.postMod.col.floatValue, postMod[i], eps=1.0/255.0):
raise rdtest.TestFailureException(f"EID:{m.eventId} Pixel history incorrect post mod expected:{postMod[i]} actual:{m.postMod.col.floatValue}")
rdtest.log.success(f"Pixel History Worked {len(modifs)} modifications found")
def check_capture(self):
markers = ["MSAA Draw", "MSAA Resolve"]
+22 -22
View File
@@ -80,38 +80,38 @@ class VK_Graphics_Pipeline(rdtest.TestCase):
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)
with self.pixel_history(pipe.GetOutputTargets()[0].resource, 200, 150, rd.Subresource(0, 0, 0), rd.CompType.Typeless) as modifs:
modifs = modifs.modifs
# should be a clear then a draw
assert len(history) == 2
# should be a clear then a draw
assert len(modifs) == 2
assert self.find_action('', history[0].eventId).flags & rd.ActionFlags.BeginPass
assert self.find_action('', modifs[0].eventId).flags & rd.ActionFlags.BeginPass
assert self.find_action('', history[1].eventId).eventId == action.eventId
assert history[1].Passed()
assert self.find_action('', modifs[1].eventId).eventId == action.eventId
assert modifs[1].Passed()
if not rdtest.value_compare(history[1].shaderOut.col.floatValue, tri_col, eps=1.0 / 256.0):
raise rdtest.TestFailureException(f"History for drawcall output is wrong: {history[1].shaderOut.col.floatValue}")
if not rdtest.value_compare(modifs[1].shaderOut.col.floatValue, tri_col, eps=1.0 / 256.0):
raise rdtest.TestFailureException(f"History for drawcall output is wrong: {modifs[1].shaderOut.col.floatValue}")
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)
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(debug.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)
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:
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}")
is_eq, diff_amt = rdtest.value_compare_diff(modifs[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 {modifs[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)
+4 -4
View File
@@ -67,10 +67,10 @@ class VK_Indirect(rdtest.TestCase):
rt = pipe.GetOutputTargets()[0]
tex = rt.resource
sub = rd.Subresource()
modifs = self.controller.PixelHistory(tex, x, y, sub, rt.format.compType)
if len(modifs) < 2:
raise rdtest.TestFailureException(f"EID: {eid} No pixel history found at ({x}, {y})")
rdtest.log.success(f"EID: {eid} Pixel History {x}, {y} Worked")
with self.pixel_history(tex, x, y, sub, rt.format.compType) as history:
if len(history.modifs) < 2:
raise rdtest.TestFailureException(f"No pixel history found at ({x}, {y})")
rdtest.log.success(f"Pixel History {x}, {y} Worked")
def check_overlay(self, pass_samples: List[Tuple[int,int]], *, no_overlay = False):
pipe = self.controller.GetPipelineState()
+30 -25
View File
@@ -40,42 +40,47 @@ class VK_Multi_Entry(rdtest.TestCase):
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)
with self.pixel_history(
pipe.GetOutputTargets()[0].resource,
200,
150,
rd.Subresource(0, 0, 0),
rd.CompType.Typeless,
) as history:
modifs = history.modifs
# should be a clear then a draw
assert len(modifs) == 2
# should be a clear then a draw
assert len(history) == 2
assert self.find_action('', modifs[0].eventId).flags & rd.ActionFlags.Clear
assert self.find_action('', history[0].eventId).flags & rd.ActionFlags.Clear
assert self.find_action('', modifs[1].eventId).eventId == action.eventId
assert modifs[1].Passed()
assert self.find_action('', history[1].eventId).eventId == action.eventId
assert history[1].Passed()
if not rdtest.value_compare(modifs[1].shaderOut.col.floatValue, (0.0, 1.0, 0.0, 1.0)):
raise rdtest.TestFailureException(f"History for drawcall output is wrong: {modifs[1].shaderOut.col.floatValue}")
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}")
refl = pipe.GetShaderReflection(rd.ShaderStage.Pixel)
refl = pipe.GetShaderReflection(rd.ShaderStage.Pixel)
assert len(refl.readOnlyResources) == 1
assert len(refl.readOnlyResources) == 1
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)
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(debug.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)
debuggedValue = list(debugged.value.f32v[0:4])
debuggedValue = list(debugged.value.f32v[0:4])
is_eq, diff_amt = rdtest.value_compare_diff(modifs[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 {modifs[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)