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