From ae4b1fc095abb086a50c10ec7849645f571e5b81 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Tue, 16 Jul 2019 16:39:15 +0200 Subject: [PATCH] radv/gfx10: always build the GS copy shader but uses it on-demand It should be possible to build it on-demand too but it requires more work. On GFX10, the GS copy shader is required when tess is enabled with extreme geometry. Signed-off-by: Samuel Pitoiset Reviewed-by: Bas Nieuwenhuizen --- src/amd/vulkan/radv_cmd_buffer.c | 8 ++++---- src/amd/vulkan/radv_pipeline.c | 21 ++++++++++++++++++--- src/amd/vulkan/radv_private.h | 2 ++ 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index 6a0db2b67e9..a6d4e0d0e21 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -929,7 +929,7 @@ radv_emit_prefetch_L2(struct radv_cmd_buffer *cmd_buffer, if (mask & RADV_PREFETCH_GS) { radv_emit_shader_prefetch(cmd_buffer, pipeline->shaders[MESA_SHADER_GEOMETRY]); - if (pipeline->gs_copy_shader) + if (radv_pipeline_has_gs_copy_shader(pipeline)) radv_emit_shader_prefetch(cmd_buffer, pipeline->gs_copy_shader); } @@ -1124,7 +1124,7 @@ radv_emit_graphics_pipeline(struct radv_cmd_buffer *cmd_buffer) pipeline->shaders[i]->bo); } - if (radv_pipeline_has_gs(pipeline) && pipeline->gs_copy_shader) + if (radv_pipeline_has_gs_copy_shader(pipeline)) radv_cs_add_buffer(cmd_buffer->device->ws, cmd_buffer->cs, pipeline->gs_copy_shader->bo); @@ -2362,7 +2362,7 @@ radv_emit_streamout_buffers(struct radv_cmd_buffer *cmd_buffer, uint64_t va) base_reg + loc->sgpr_idx * 4, va, false); } - if (pipeline->gs_copy_shader) { + if (radv_pipeline_has_gs_copy_shader(pipeline)) { loc = &pipeline->gs_copy_shader->info.user_sgprs_locs.shader_data[AC_UD_STREAMOUT_BUFFERS]; if (loc->sgpr_idx != -1) { base_reg = R_00B130_SPI_SHADER_USER_DATA_VS_0; @@ -4071,7 +4071,7 @@ static void radv_emit_view_index(struct radv_cmd_buffer *cmd_buffer, unsigned in radeon_set_sh_reg(cmd_buffer->cs, base_reg + loc->sgpr_idx * 4, index); } - if (pipeline->gs_copy_shader) { + if (radv_pipeline_has_gs_copy_shader(pipeline)) { struct radv_userdata_info *loc = &pipeline->gs_copy_shader->info.user_sgprs_locs.shader_data[AC_UD_VIEW_INDEX]; if (loc->sgpr_idx != -1) { uint32_t base_reg = R_00B130_SPI_SHADER_USER_DATA_VS_0; diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c index 31495ec078d..d1eede172dc 100644 --- a/src/amd/vulkan/radv_pipeline.c +++ b/src/amd/vulkan/radv_pipeline.c @@ -120,6 +120,22 @@ bool radv_pipeline_has_ngg(const struct radv_pipeline *pipeline) return variant->info.is_ngg; } +bool radv_pipeline_has_gs_copy_shader(const struct radv_pipeline *pipeline) +{ + if (!radv_pipeline_has_gs(pipeline)) + return false; + + /* The GS copy shader is required if the pipeline has GS on GFX6-GFX9. + * On GFX10, it might be required in rare cases if it's not possible to + * enable NGG. + */ + if (radv_pipeline_has_ngg(pipeline)) + return false; + + assert(pipeline->gs_copy_shader); + return true; +} + static void radv_pipeline_destroy(struct radv_device *device, struct radv_pipeline *pipeline, @@ -2395,7 +2411,6 @@ void radv_create_shaders(struct radv_pipeline *pipeline, struct radv_shader_binary *binaries[MESA_SHADER_STAGES] = {NULL}; struct radv_shader_variant_key keys[MESA_SHADER_STAGES] = {{{{{0}}}}}; unsigned char hash[20], gs_copy_hash[20]; - bool use_ngg = device->physical_device->rad_info.chip_class >= GFX10; radv_start_feedback(pipeline_feedback); @@ -2416,7 +2431,7 @@ void radv_create_shaders(struct radv_pipeline *pipeline, gs_copy_hash[0] ^= 1; bool found_in_application_cache = true; - if (modules[MESA_SHADER_GEOMETRY] && !use_ngg) { + if (modules[MESA_SHADER_GEOMETRY]) { struct radv_shader_variant *variants[MESA_SHADER_STAGES] = {0}; radv_create_shader_variants_from_pipeline_cache(device, cache, gs_copy_hash, variants, &found_in_application_cache); @@ -2567,7 +2582,7 @@ void radv_create_shaders(struct radv_pipeline *pipeline, } } - if(modules[MESA_SHADER_GEOMETRY] && !use_ngg) { + if(modules[MESA_SHADER_GEOMETRY]) { struct radv_shader_binary *gs_copy_binary = NULL; if (!pipeline->gs_copy_shader) { pipeline->gs_copy_shader = radv_create_gs_copy_shader( diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index 08c2abef7ab..b9ac97249d3 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -1512,6 +1512,8 @@ static inline bool radv_pipeline_has_tess(const struct radv_pipeline *pipeline) bool radv_pipeline_has_ngg(const struct radv_pipeline *pipeline); +bool radv_pipeline_has_gs_copy_shader(const struct radv_pipeline *pipeline); + struct radv_userdata_info *radv_lookup_user_sgpr(struct radv_pipeline *pipeline, gl_shader_stage stage, int idx); -- 2.30.2