radv/gfx10: always build the GS copy shader but uses it on-demand
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>
Tue, 16 Jul 2019 14:39:15 +0000 (16:39 +0200)
committerSamuel Pitoiset <samuel.pitoiset@gmail.com>
Wed, 17 Jul 2019 06:32:30 +0000 (08:32 +0200)
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 <samuel.pitoiset@gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
src/amd/vulkan/radv_cmd_buffer.c
src/amd/vulkan/radv_pipeline.c
src/amd/vulkan/radv_private.h

index 6a0db2b67e995c71a710afe92ce6b66a15f5af2a..a6d4e0d0e2132a7dee9dda25c95379ea0b2e565d 100644 (file)
@@ -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;
index 31495ec078df3c792e89b647862652adf127f0db..d1eede172dc9ecef18b10c8bf313fcaf5d1a354c 100644 (file)
@@ -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(
index 08c2abef7abd158b22553ec7242c4f9b4fe83329..b9ac97249d35bc86e87e7e794d7ee250d89d914b 100644 (file)
@@ -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);