radv: Add support for RT bind point.

Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9767>
This commit is contained in:
Bas Nieuwenhuizen
2021-03-22 01:20:11 +01:00
committed by Marge Bot
parent bf2b990618
commit eba2b4137e
3 changed files with 111 additions and 69 deletions
+101 -65
View File
@@ -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)
radv_flush_constants(struct radv_cmd_buffer *cmd_buffer, VkShaderStageFlags stages,
struct radv_pipeline *pipeline, VkPipelineBindPoint bind_point)
{
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;
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
+1 -1
View File
@@ -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
+9 -3
View File
@@ -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");
}
}
/*