Module: Mesa Branch: main Commit: eba2b4137ebf8dde0a1026af4f1a4e871d9e418e URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=eba2b4137ebf8dde0a1026af4f1a4e871d9e418e
Author: Bas Nieuwenhuizen <[email protected]> Date: Mon Mar 22 01:20:11 2021 +0100 radv: Add support for RT bind point. Reviewed-by: Samuel Pitoiset <[email protected]> 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"); + } } /* _______________________________________________ mesa-commit mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-commit
