Mesa (main): radv/rt: Don't load ClosestHit SBT on every hit, but only once after traversal

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Jul 22 15:55:35 UTC 2022


Module: Mesa
Branch: main
Commit: c0945f70dfb13a05df477d7654469091b0a743d8
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=c0945f70dfb13a05df477d7654469091b0a743d8

Author: Daniel Schürmann <daniel at schuermann.dev>
Date:   Wed Jun 22 11:35:47 2022 +0200

radv/rt: Don't load ClosestHit SBT on every hit, but only once after traversal

Quake II RTX:
Totals from 7 (0.01% of 134913) affected shaders:
CodeSize: 217592 -> 215956 (-0.75%)
Instrs: 39468 -> 39341 (-0.32%)
Latency: 761581 -> 746802 (-1.94%)
InvThroughput: 507721 -> 497870 (-1.94%)
Copies: 4621 -> 4585 (-0.78%)
Branches: 1598 -> 1584 (-0.88%)

Reviewed-by: Konstantin Seurer <konstantin.seurer at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17301>

---

 src/amd/vulkan/radv_pipeline_rt.c | 68 ++++++++++++++++++---------------------
 1 file changed, 31 insertions(+), 37 deletions(-)

diff --git a/src/amd/vulkan/radv_pipeline_rt.c b/src/amd/vulkan/radv_pipeline_rt.c
index 31a620718ba..09d5a707366 100644
--- a/src/amd/vulkan/radv_pipeline_rt.c
+++ b/src/amd/vulkan/radv_pipeline_rt.c
@@ -185,7 +185,10 @@ fail:
  * Global variables for an RT pipeline
  */
 struct rt_variables {
-   /* idx of the next shader to run in the next iteration of the main loop */
+   /* idx of the next shader to run in the next iteration of the main loop.
+    * During traversal, idx is used to store the SBT index and will contain
+    * the correct resume index upon returning.
+    */
    nir_variable *idx;
 
    /* scratch offset of the argument area relative to stack_ptr */
@@ -1076,7 +1079,7 @@ struct rt_traversal_vars {
    nir_variable *instance_id;
    nir_variable *custom_instance_and_mask;
    nir_variable *instance_addr;
-   nir_variable *should_return;
+   nir_variable *hit;
    nir_variable *bvh_base;
    nir_variable *stack;
    nir_variable *top_stack;
@@ -1100,8 +1103,7 @@ init_traversal_vars(nir_builder *b)
       b->shader, nir_var_shader_temp, glsl_uint_type(), "traversal_custom_instance_and_mask");
    ret.instance_addr =
       nir_variable_create(b->shader, nir_var_shader_temp, glsl_uint64_t_type(), "instance_addr");
-   ret.should_return = nir_variable_create(b->shader, nir_var_shader_temp, glsl_bool_type(),
-                                           "traversal_should_return");
+   ret.hit = nir_variable_create(b->shader, nir_var_shader_temp, glsl_bool_type(), "traversal_hit");
    ret.bvh_base = nir_variable_create(b->shader, nir_var_shader_temp, glsl_uint64_t_type(),
                                       "traversal_bvh_base");
    ret.stack =
@@ -1248,14 +1250,8 @@ insert_traversal_triangle_case(struct radv_device *device,
          nir_store_var(b, vars->custom_instance_and_mask,
                        nir_load_var(b, trav_vars->custom_instance_and_mask), 0x1);
 
-         load_sbt_entry(b, vars, sbt_idx, SBT_HIT, 0);
-
-         nir_store_var(b, trav_vars->should_return,
-                       nir_ior(b,
-                               nir_test_mask(b, nir_load_var(b, vars->flags),
-                                             SpvRayFlagsSkipClosestHitShaderKHRMask),
-                               nir_ieq_imm(b, nir_load_var(b, vars->idx), 0)),
-                       1);
+         nir_store_var(b, vars->idx, sbt_idx, 1);
+         nir_store_var(b, trav_vars->hit, nir_imm_true(b), 1);
 
          nir_ssa_def *terminate_on_first_hit =
             nir_test_mask(b, nir_load_var(b, vars->flags), SpvRayFlagsTerminateOnFirstHitKHRMask);
@@ -1399,14 +1395,8 @@ insert_traversal_aabb_case(struct radv_device *device,
          nir_store_var(b, vars->custom_instance_and_mask,
                        nir_load_var(b, trav_vars->custom_instance_and_mask), 0x1);
 
-         load_sbt_entry(b, vars, sbt_idx, SBT_HIT, 0);
-
-         nir_store_var(b, trav_vars->should_return,
-                       nir_ior(b,
-                               nir_test_mask(b, nir_load_var(b, vars->flags),
-                                             SpvRayFlagsSkipClosestHitShaderKHRMask),
-                               nir_ieq_imm(b, nir_load_var(b, vars->idx), 0)),
-                       1);
+         nir_store_var(b, vars->idx, sbt_idx, 1);
+         nir_store_var(b, trav_vars->hit, nir_imm_true(b), 1);
 
          nir_ssa_def *terminate_on_first_hit =
             nir_test_mask(b, nir_load_var(b, vars->flags), SpvRayFlagsTerminateOnFirstHitKHRMask);
@@ -1449,11 +1439,7 @@ build_traversal_shader(struct radv_device *device,
 
    struct rt_traversal_vars trav_vars = init_traversal_vars(&b);
 
-   /* Initialize the follow-up shader idx to 0, to be replaced by the miss shader
-    * if we actually miss. */
-   nir_store_var(&b, vars.idx, nir_imm_int(&b, 0), 1);
-
-   nir_store_var(&b, trav_vars.should_return, nir_imm_bool(&b, false), 1);
+   nir_store_var(&b, trav_vars.hit, nir_imm_false(&b), 1);
 
    nir_push_if(&b, nir_ine_imm(&b, accel_struct, 0));
    {
@@ -1617,23 +1603,31 @@ build_traversal_shader(struct radv_device *device,
    }
    nir_pop_if(&b, NULL);
 
-   /* should_return is set if we had a hit but we won't be calling the closest hit shader and hence
-    * need to return immediately to the calling shader. */
-   nir_push_if(&b, nir_load_var(&b, trav_vars.should_return));
-   {
-      insert_rt_return(&b, &vars);
-   }
-   nir_push_else(&b, NULL);
+   /* Initialize follow-up shader. */
+   nir_push_if(&b, nir_load_var(&b, trav_vars.hit));
    {
-      /* Only load the miss shader if we actually miss, which we determining by not having set
-       * a closest hit shader. It is valid to not specify an SBT pointer for miss shaders if none
-       * of the rays miss. */
-      nir_push_if(&b, nir_ieq_imm(&b, nir_load_var(&b, vars.idx), 0));
+      /* vars.idx contains the SBT index at this point. */
+      load_sbt_entry(&b, &vars, nir_load_var(&b, vars.idx), SBT_HIT, 0);
+
+      nir_ssa_def *should_return = nir_ior(&b,
+                                           nir_test_mask(&b, nir_load_var(&b, vars.flags),
+                                                         SpvRayFlagsSkipClosestHitShaderKHRMask),
+                                           nir_ieq_imm(&b, nir_load_var(&b, vars.idx), 0));
+
+      /* should_return is set if we had a hit but we won't be calling the closest hit shader and hence
+       * need to return immediately to the calling shader. */
+      nir_push_if(&b, should_return);
       {
-         load_sbt_entry(&b, &vars, nir_load_var(&b, vars.miss_index), SBT_MISS, 0);
+         insert_rt_return(&b, &vars);
       }
       nir_pop_if(&b, NULL);
    }
+   nir_push_else(&b, NULL);
+   {
+      /* Only load the miss shader if we actually miss. It is valid to not specify an SBT pointer
+       * for miss shaders if none of the rays miss. */
+      load_sbt_entry(&b, &vars, nir_load_var(&b, vars.miss_index), SBT_MISS, 0);
+   }
    nir_pop_if(&b, NULL);
 
    return b.shader;



More information about the mesa-commit mailing list