Mesa (main): radv: Add support for RT bind point.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue May 18 18:53:17 UTC 2021


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

Author: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
Date:   Mon Mar 22 01:20:11 2021 +0100

radv: Add support for RT bind point.

Reviewed-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9767>

---

 src/amd/vulkan/radv_cmd_buffer.c | 168 ++++++++++++++++++++++++---------------
 src/amd/vulkan/radv_constants.h  |   2 +-
 src/amd/vulkan/radv_private.h    |  12 ++-
 3 files changed, 112 insertions(+), 70 deletions(-)

diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c
index 8a2b8b44368..8c0977e9080 100644
--- a/src/amd/vulkan/radv_cmd_buffer.c
+++ b/src/amd/vulkan/radv_cmd_buffer.c
@@ -48,6 +48,12 @@ enum {
                             RADV_PREFETCH_GS | RADV_PREFETCH_PS)
 };
 
+enum {
+   RADV_RT_STAGE_BITS = (VK_SHADER_STAGE_RAYGEN_BIT_KHR | VK_SHADER_STAGE_ANY_HIT_BIT_KHR |
+                         VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | VK_SHADER_STAGE_MISS_BIT_KHR |
+                         VK_SHADER_STAGE_INTERSECTION_BIT_KHR | VK_SHADER_STAGE_CALLABLE_BIT_KHR)
+};
+
 static void radv_handle_image_transition(struct radv_cmd_buffer *cmd_buffer,
                                          struct radv_image *image, VkImageLayout src_layout,
                                          bool src_render_loop, VkImageLayout dst_layout,
@@ -2656,7 +2662,7 @@ radv_flush_push_descriptors(struct radv_cmd_buffer *cmd_buffer, VkPipelineBindPo
 
 static void
 radv_flush_indirect_descriptor_sets(struct radv_cmd_buffer *cmd_buffer,
-                                    VkPipelineBindPoint bind_point)
+                                    struct radv_pipeline *pipeline, VkPipelineBindPoint bind_point)
 {
    struct radv_descriptor_state *descriptors_state =
       radv_get_descriptors_state(cmd_buffer, bind_point);
@@ -2679,42 +2685,38 @@ radv_flush_indirect_descriptor_sets(struct radv_cmd_buffer *cmd_buffer,
    uint64_t va = radv_buffer_get_va(cmd_buffer->upload.upload_bo);
    va += offset;
 
-   if (cmd_buffer->state.pipeline) {
-      if (cmd_buffer->state.pipeline->shaders[MESA_SHADER_VERTEX])
-         radv_emit_userdata_address(cmd_buffer, cmd_buffer->state.pipeline, MESA_SHADER_VERTEX,
+   if (bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS) {
+      if (pipeline->shaders[MESA_SHADER_VERTEX])
+         radv_emit_userdata_address(cmd_buffer, pipeline, MESA_SHADER_VERTEX,
                                     AC_UD_INDIRECT_DESCRIPTOR_SETS, va);
 
-      if (cmd_buffer->state.pipeline->shaders[MESA_SHADER_FRAGMENT])
-         radv_emit_userdata_address(cmd_buffer, cmd_buffer->state.pipeline, MESA_SHADER_FRAGMENT,
+      if (pipeline->shaders[MESA_SHADER_FRAGMENT])
+         radv_emit_userdata_address(cmd_buffer, pipeline, MESA_SHADER_FRAGMENT,
                                     AC_UD_INDIRECT_DESCRIPTOR_SETS, va);
 
-      if (radv_pipeline_has_gs(cmd_buffer->state.pipeline))
-         radv_emit_userdata_address(cmd_buffer, cmd_buffer->state.pipeline, MESA_SHADER_GEOMETRY,
+      if (radv_pipeline_has_gs(pipeline))
+         radv_emit_userdata_address(cmd_buffer, pipeline, MESA_SHADER_GEOMETRY,
                                     AC_UD_INDIRECT_DESCRIPTOR_SETS, va);
 
-      if (radv_pipeline_has_tess(cmd_buffer->state.pipeline))
-         radv_emit_userdata_address(cmd_buffer, cmd_buffer->state.pipeline, MESA_SHADER_TESS_CTRL,
+      if (radv_pipeline_has_tess(pipeline))
+         radv_emit_userdata_address(cmd_buffer, pipeline, MESA_SHADER_TESS_CTRL,
                                     AC_UD_INDIRECT_DESCRIPTOR_SETS, va);
 
-      if (radv_pipeline_has_tess(cmd_buffer->state.pipeline))
-         radv_emit_userdata_address(cmd_buffer, cmd_buffer->state.pipeline, MESA_SHADER_TESS_EVAL,
+      if (radv_pipeline_has_tess(pipeline))
+         radv_emit_userdata_address(cmd_buffer, pipeline, MESA_SHADER_TESS_EVAL,
                                     AC_UD_INDIRECT_DESCRIPTOR_SETS, va);
+   } else {
+      radv_emit_userdata_address(cmd_buffer, pipeline, MESA_SHADER_COMPUTE,
+                                 AC_UD_INDIRECT_DESCRIPTOR_SETS, va);
    }
-
-   if (cmd_buffer->state.compute_pipeline)
-      radv_emit_userdata_address(cmd_buffer, cmd_buffer->state.compute_pipeline,
-                                 MESA_SHADER_COMPUTE, AC_UD_INDIRECT_DESCRIPTOR_SETS, va);
 }
 
 static void
-radv_flush_descriptors(struct radv_cmd_buffer *cmd_buffer, VkShaderStageFlags stages)
+radv_flush_descriptors(struct radv_cmd_buffer *cmd_buffer, VkShaderStageFlags stages,
+                       struct radv_pipeline *pipeline, VkPipelineBindPoint bind_point)
 {
-   VkPipelineBindPoint bind_point = stages & VK_SHADER_STAGE_COMPUTE_BIT
-                                       ? VK_PIPELINE_BIND_POINT_COMPUTE
-                                       : VK_PIPELINE_BIND_POINT_GRAPHICS;
    struct radv_descriptor_state *descriptors_state =
       radv_get_descriptors_state(cmd_buffer, bind_point);
-   struct radv_cmd_state *state = &cmd_buffer->state;
    bool flush_indirect_descriptors;
 
    if (!descriptors_state->dirty)
@@ -2723,34 +2725,29 @@ radv_flush_descriptors(struct radv_cmd_buffer *cmd_buffer, VkShaderStageFlags st
    if (descriptors_state->push_dirty)
       radv_flush_push_descriptors(cmd_buffer, bind_point);
 
-   flush_indirect_descriptors =
-      (bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS && state->pipeline &&
-       state->pipeline->need_indirect_descriptor_sets) ||
-      (bind_point == VK_PIPELINE_BIND_POINT_COMPUTE && state->compute_pipeline &&
-       state->compute_pipeline->need_indirect_descriptor_sets);
+   flush_indirect_descriptors = pipeline && pipeline->need_indirect_descriptor_sets;
 
    if (flush_indirect_descriptors)
-      radv_flush_indirect_descriptor_sets(cmd_buffer, bind_point);
+      radv_flush_indirect_descriptor_sets(cmd_buffer, pipeline, bind_point);
 
    ASSERTED unsigned cdw_max =
       radeon_check_space(cmd_buffer->device->ws, cmd_buffer->cs, MAX_SETS * MESA_SHADER_STAGES * 4);
 
-   if (cmd_buffer->state.pipeline) {
-      radv_foreach_stage(stage, stages)
-      {
-         if (!cmd_buffer->state.pipeline->shaders[stage])
-            continue;
+   if (pipeline) {
+      if (stages & VK_SHADER_STAGE_COMPUTE_BIT) {
+         radv_emit_descriptor_pointers(cmd_buffer, pipeline, descriptors_state,
+                                       MESA_SHADER_COMPUTE);
+      } else {
+         radv_foreach_stage(stage, stages)
+         {
+            if (!cmd_buffer->state.pipeline->shaders[stage])
+               continue;
 
-         radv_emit_descriptor_pointers(cmd_buffer, cmd_buffer->state.pipeline, descriptors_state,
-                                       stage);
+            radv_emit_descriptor_pointers(cmd_buffer, pipeline, descriptors_state, stage);
+         }
       }
    }
 
-   if (cmd_buffer->state.compute_pipeline && (stages & VK_SHADER_STAGE_COMPUTE_BIT)) {
-      radv_emit_descriptor_pointers(cmd_buffer, cmd_buffer->state.compute_pipeline,
-                                    descriptors_state, MESA_SHADER_COMPUTE);
-   }
-
    descriptors_state->dirty = 0;
    descriptors_state->push_dirty = false;
 
@@ -2761,14 +2758,9 @@ radv_flush_descriptors(struct radv_cmd_buffer *cmd_buffer, VkShaderStageFlags st
 }
 
 static void
-radv_flush_constants(struct radv_cmd_buffer *cmd_buffer, VkShaderStageFlags stages)
-{
-   struct radv_pipeline *pipeline = stages & VK_SHADER_STAGE_COMPUTE_BIT
-                                       ? cmd_buffer->state.compute_pipeline
-                                       : cmd_buffer->state.pipeline;
-   VkPipelineBindPoint bind_point = stages & VK_SHADER_STAGE_COMPUTE_BIT
-                                       ? VK_PIPELINE_BIND_POINT_COMPUTE
-                                       : VK_PIPELINE_BIND_POINT_GRAPHICS;
+radv_flush_constants(struct radv_cmd_buffer *cmd_buffer, VkShaderStageFlags stages,
+                     struct radv_pipeline *pipeline, VkPipelineBindPoint bind_point)
+{
    struct radv_descriptor_state *descriptors_state =
       radv_get_descriptors_state(cmd_buffer, bind_point);
    struct radv_pipeline_layout *layout = pipeline->layout;
@@ -2777,12 +2769,29 @@ radv_flush_constants(struct radv_cmd_buffer *cmd_buffer, VkShaderStageFlags stag
    unsigned offset;
    void *ptr;
    uint64_t va;
+   uint32_t internal_stages;
+   uint32_t dirty_stages = 0;
 
    stages &= cmd_buffer->push_constant_stages;
    if (!stages || (!layout->push_constant_size && !layout->dynamic_offset_count))
       return;
 
-   radv_foreach_stage(stage, stages)
+   internal_stages = stages;
+   switch (bind_point) {
+   case VK_PIPELINE_BIND_POINT_GRAPHICS:
+      break;
+   case VK_PIPELINE_BIND_POINT_COMPUTE:
+      dirty_stages = RADV_RT_STAGE_BITS;
+      break;
+   case VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR:
+      internal_stages = VK_SHADER_STAGE_COMPUTE_BIT;
+      dirty_stages = VK_SHADER_STAGE_COMPUTE_BIT;
+      break;
+   default:
+      unreachable("Unhandled bind point");
+   }
+
+   radv_foreach_stage(stage, internal_stages)
    {
       shader = radv_get_shader(pipeline, stage);
       if (!shader)
@@ -2815,7 +2824,7 @@ radv_flush_constants(struct radv_cmd_buffer *cmd_buffer, VkShaderStageFlags stag
          radeon_check_space(cmd_buffer->device->ws, cmd_buffer->cs, MESA_SHADER_STAGES * 4);
 
       prev_shader = NULL;
-      radv_foreach_stage(stage, stages)
+      radv_foreach_stage(stage, internal_stages)
       {
          shader = radv_get_shader(pipeline, stage);
 
@@ -2830,6 +2839,7 @@ radv_flush_constants(struct radv_cmd_buffer *cmd_buffer, VkShaderStageFlags stag
    }
 
    cmd_buffer->push_constant_stages &= ~stages;
+   cmd_buffer->push_constant_stages |= dirty_stages;
 }
 
 static void
@@ -3068,8 +3078,10 @@ radv_upload_graphics_shader_descriptors(struct radv_cmd_buffer *cmd_buffer, bool
 {
    radv_flush_vertex_descriptors(cmd_buffer, pipeline_is_dirty);
    radv_flush_streamout_descriptors(cmd_buffer);
-   radv_flush_descriptors(cmd_buffer, VK_SHADER_STAGE_ALL_GRAPHICS);
-   radv_flush_constants(cmd_buffer, VK_SHADER_STAGE_ALL_GRAPHICS);
+   radv_flush_descriptors(cmd_buffer, VK_SHADER_STAGE_ALL_GRAPHICS, cmd_buffer->state.pipeline,
+                          VK_PIPELINE_BIND_POINT_GRAPHICS);
+   radv_flush_constants(cmd_buffer, VK_SHADER_STAGE_ALL_GRAPHICS, cmd_buffer->state.pipeline,
+                        VK_PIPELINE_BIND_POINT_GRAPHICS);
    radv_flush_ngg_gs_state(cmd_buffer);
 }
 
@@ -4277,10 +4289,8 @@ radv_EndCommandBuffer(VkCommandBuffer commandBuffer)
 }
 
 static void
-radv_emit_compute_pipeline(struct radv_cmd_buffer *cmd_buffer)
+radv_emit_compute_pipeline(struct radv_cmd_buffer *cmd_buffer, struct radv_pipeline *pipeline)
 {
-   struct radv_pipeline *pipeline = cmd_buffer->state.compute_pipeline;
-
    if (!pipeline || pipeline == cmd_buffer->state.emitted_compute_pipeline)
       return;
 
@@ -5914,16 +5924,22 @@ radv_emit_dispatch_packets(struct radv_cmd_buffer *cmd_buffer,
 }
 
 static void
-radv_upload_compute_shader_descriptors(struct radv_cmd_buffer *cmd_buffer)
+radv_upload_compute_shader_descriptors(struct radv_cmd_buffer *cmd_buffer,
+                                       struct radv_pipeline *pipeline,
+                                       VkPipelineBindPoint bind_point)
 {
-   radv_flush_descriptors(cmd_buffer, VK_SHADER_STAGE_COMPUTE_BIT);
-   radv_flush_constants(cmd_buffer, VK_SHADER_STAGE_COMPUTE_BIT);
+   radv_flush_descriptors(cmd_buffer, VK_SHADER_STAGE_COMPUTE_BIT, pipeline, bind_point);
+   radv_flush_constants(cmd_buffer,
+                        bind_point == VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR
+                           ? RADV_RT_STAGE_BITS
+                           : VK_SHADER_STAGE_COMPUTE_BIT,
+                        pipeline, bind_point);
 }
 
 static void
-radv_dispatch(struct radv_cmd_buffer *cmd_buffer, const struct radv_dispatch_info *info)
+radv_dispatch(struct radv_cmd_buffer *cmd_buffer, const struct radv_dispatch_info *info,
+              struct radv_pipeline *pipeline, VkPipelineBindPoint bind_point)
 {
-   struct radv_pipeline *pipeline = cmd_buffer->state.compute_pipeline;
    bool has_prefetch = cmd_buffer->device->physical_device->rad_info.chip_class >= GFX7;
    bool pipeline_is_dirty = pipeline && pipeline != cmd_buffer->state.emitted_compute_pipeline;
 
@@ -5937,11 +5953,11 @@ radv_dispatch(struct radv_cmd_buffer *cmd_buffer, const struct radv_dispatch_inf
        * time the CUs are idle is very short. (there are only SET_SH
        * packets between the wait and the draw)
        */
-      radv_emit_compute_pipeline(cmd_buffer);
+      radv_emit_compute_pipeline(cmd_buffer, pipeline);
       si_emit_cache_flush(cmd_buffer);
       /* <-- CUs are idle here --> */
 
-      radv_upload_compute_shader_descriptors(cmd_buffer);
+      radv_upload_compute_shader_descriptors(cmd_buffer, pipeline, bind_point);
 
       radv_emit_dispatch_packets(cmd_buffer, info);
       /* <-- CUs are busy here --> */
@@ -5963,15 +5979,35 @@ radv_dispatch(struct radv_cmd_buffer *cmd_buffer, const struct radv_dispatch_inf
          radv_emit_shader_prefetch(cmd_buffer, pipeline->shaders[MESA_SHADER_COMPUTE]);
       }
 
-      radv_upload_compute_shader_descriptors(cmd_buffer);
+      radv_upload_compute_shader_descriptors(cmd_buffer, pipeline, bind_point);
 
-      radv_emit_compute_pipeline(cmd_buffer);
+      radv_emit_compute_pipeline(cmd_buffer, pipeline);
       radv_emit_dispatch_packets(cmd_buffer, info);
    }
 
+   if (pipeline_is_dirty) {
+      /* Raytracing uses compute shaders but has separate bind points and pipelines.
+       * So if we set compute userdata & shader registers we should dirty the raytracing
+       * ones and the other way around.
+       *
+       * We only need to do this when the pipeline is dirty because when we switch between
+       * the two we always need to switch pipelines.
+       */
+      radv_mark_descriptor_sets_dirty(cmd_buffer, bind_point == VK_PIPELINE_BIND_POINT_COMPUTE
+                                                     ? VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR
+                                                     : VK_PIPELINE_BIND_POINT_COMPUTE);
+   }
+
    radv_cmd_buffer_after_draw(cmd_buffer, RADV_CMD_FLAG_CS_PARTIAL_FLUSH);
 }
 
+static void
+radv_compute_dispatch(struct radv_cmd_buffer *cmd_buffer, const struct radv_dispatch_info *info)
+{
+   radv_dispatch(cmd_buffer, info, cmd_buffer->state.compute_pipeline,
+                 VK_PIPELINE_BIND_POINT_COMPUTE);
+}
+
 void
 radv_CmdDispatchBase(VkCommandBuffer commandBuffer, uint32_t base_x, uint32_t base_y,
                      uint32_t base_z, uint32_t x, uint32_t y, uint32_t z)
@@ -5986,7 +6022,7 @@ radv_CmdDispatchBase(VkCommandBuffer commandBuffer, uint32_t base_x, uint32_t ba
    info.offsets[0] = base_x;
    info.offsets[1] = base_y;
    info.offsets[2] = base_z;
-   radv_dispatch(cmd_buffer, &info);
+   radv_compute_dispatch(cmd_buffer, &info);
 }
 
 void
@@ -6005,7 +6041,7 @@ radv_CmdDispatchIndirect(VkCommandBuffer commandBuffer, VkBuffer _buffer, VkDevi
    info.indirect = buffer;
    info.indirect_offset = offset;
 
-   radv_dispatch(cmd_buffer, &info);
+   radv_compute_dispatch(cmd_buffer, &info);
 }
 
 void
@@ -6018,7 +6054,7 @@ radv_unaligned_dispatch(struct radv_cmd_buffer *cmd_buffer, uint32_t x, uint32_t
    info.blocks[2] = z;
    info.unaligned = 1;
 
-   radv_dispatch(cmd_buffer, &info);
+   radv_compute_dispatch(cmd_buffer, &info);
 }
 
 void
diff --git a/src/amd/vulkan/radv_constants.h b/src/amd/vulkan/radv_constants.h
index bceedac3da6..327365c91f0 100644
--- a/src/amd/vulkan/radv_constants.h
+++ b/src/amd/vulkan/radv_constants.h
@@ -51,7 +51,7 @@
 #define MAX_SO_OUTPUTS                 64
 #define MAX_INLINE_UNIFORM_BLOCK_SIZE  (4ull * 1024 * 1024)
 #define MAX_INLINE_UNIFORM_BLOCK_COUNT 64
-#define MAX_BIND_POINTS                2 /* compute + graphics */
+#define MAX_BIND_POINTS                3 /* compute + graphics + raytracing */
 
 #define NUM_DEPTH_CLEAR_PIPELINES      3
 #define NUM_DEPTH_DECOMPRESS_PIPELINES 3
diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
index 2b99ca829f6..7a23edd6ea5 100644
--- a/src/amd/vulkan/radv_private.h
+++ b/src/amd/vulkan/radv_private.h
@@ -1604,9 +1604,15 @@ radv_emit_shader_pointer(struct radv_device *device, struct radeon_cmdbuf *cs, u
 static inline struct radv_descriptor_state *
 radv_get_descriptors_state(struct radv_cmd_buffer *cmd_buffer, VkPipelineBindPoint bind_point)
 {
-   assert(bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS ||
-          bind_point == VK_PIPELINE_BIND_POINT_COMPUTE);
-   return &cmd_buffer->descriptors[bind_point];
+   switch (bind_point) {
+   case VK_PIPELINE_BIND_POINT_GRAPHICS:
+   case VK_PIPELINE_BIND_POINT_COMPUTE:
+      return &cmd_buffer->descriptors[bind_point];
+   case VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR:
+      return &cmd_buffer->descriptors[2];
+   default:
+      unreachable("Unhandled bind point");
+   }
 }
 
 /*



More information about the mesa-commit mailing list