diff --git a/util/test/rdtest/shared/Pixel_History.py b/util/test/rdtest/shared/Pixel_History.py index a9524a65e..0af8bc31e 100644 --- a/util/test/rdtest/shared/Pixel_History.py +++ b/util/test/rdtest/shared/Pixel_History.py @@ -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] diff --git a/util/test/tests/D3D12/D3D12_Blend_Pixel_History.py b/util/test/tests/D3D12/D3D12_Blend_Pixel_History.py index c1824ffa9..f195749e4 100644 --- a/util/test/tests/D3D12/D3D12_Blend_Pixel_History.py +++ b/util/test/tests/D3D12/D3D12_Blend_Pixel_History.py @@ -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 diff --git a/util/test/tests/D3D12/D3D12_Execute_Indirect.py b/util/test/tests/D3D12/D3D12_Execute_Indirect.py index 75570b8f6..e598e0089 100644 --- a/util/test/tests/D3D12/D3D12_Execute_Indirect.py +++ b/util/test/tests/D3D12/D3D12_Execute_Indirect.py @@ -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() diff --git a/util/test/tests/Iter_Test.py b/util/test/tests/Iter_Test.py index f03398292..1e855e47e 100644 --- a/util/test/tests/Iter_Test.py +++ b/util/test/tests/Iter_Test.py @@ -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) diff --git a/util/test/tests/Vulkan/VK_Blend_Pixel_History.py b/util/test/tests/Vulkan/VK_Blend_Pixel_History.py index 7a57724aa..812c7074a 100644 --- a/util/test/tests/Vulkan/VK_Blend_Pixel_History.py +++ b/util/test/tests/Vulkan/VK_Blend_Pixel_History.py @@ -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 diff --git a/util/test/tests/Vulkan/VK_Custom_Resolve.py b/util/test/tests/Vulkan/VK_Custom_Resolve.py index 5a8ff4626..2239d9e9b 100644 --- a/util/test/tests/Vulkan/VK_Custom_Resolve.py +++ b/util/test/tests/Vulkan/VK_Custom_Resolve.py @@ -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"] diff --git a/util/test/tests/Vulkan/VK_Graphics_Pipeline.py b/util/test/tests/Vulkan/VK_Graphics_Pipeline.py index 5e7d1bf48..bd403fd8b 100644 --- a/util/test/tests/Vulkan/VK_Graphics_Pipeline.py +++ b/util/test/tests/Vulkan/VK_Graphics_Pipeline.py @@ -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) diff --git a/util/test/tests/Vulkan/VK_Indirect.py b/util/test/tests/Vulkan/VK_Indirect.py index cc742702b..c76b8f44a 100644 --- a/util/test/tests/Vulkan/VK_Indirect.py +++ b/util/test/tests/Vulkan/VK_Indirect.py @@ -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() diff --git a/util/test/tests/Vulkan/VK_Multi_Entry.py b/util/test/tests/Vulkan/VK_Multi_Entry.py index 43e9f1000..0753794f5 100644 --- a/util/test/tests/Vulkan/VK_Multi_Entry.py +++ b/util/test/tests/Vulkan/VK_Multi_Entry.py @@ -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)