From: Dave Airlie <airl...@redhat.com>

This adds gs copy shader support to the pipeline cache, and few
geometry related changes.

Signed-off-by: Dave Airlie <airl...@redhat.com>
---
 src/amd/vulkan/radv_pipeline.c       | 124 +++++++++++++++++++++++++++++++++--
 src/amd/vulkan/radv_pipeline_cache.c |   4 +-
 src/amd/vulkan/radv_private.h        |   4 +-
 3 files changed, 124 insertions(+), 8 deletions(-)

diff --git a/src/amd/vulkan/radv_pipeline.c b/src/amd/vulkan/radv_pipeline.c
index 360b519..fbc70eb 100644
--- a/src/amd/vulkan/radv_pipeline.c
+++ b/src/amd/vulkan/radv_pipeline.c
@@ -119,6 +119,9 @@ void radv_DestroyPipeline(
                if (pipeline->shaders[i])
                        radv_shader_variant_destroy(device, 
pipeline->shaders[i]);
 
+       if (pipeline->gs_copy_shader)
+               radv_shader_variant_destroy(device, pipeline->gs_copy_shader);
+
        vk_free2(&device->alloc, pAllocator, pipeline);
 }
 
@@ -268,7 +271,8 @@ static const char *radv_get_shader_name(struct 
radv_shader_variant *var,
                                        gl_shader_stage stage)
 {
        switch (stage) {
-       case MESA_SHADER_VERTEX: return "Vertex Shader as VS";
+       case MESA_SHADER_VERTEX: return var->info.vs.as_es ? "Vertex Shader as 
ES" : "Vertex Shader as VS";
+       case MESA_SHADER_GEOMETRY: return "Geometry Shader";
        case MESA_SHADER_FRAGMENT: return "Pixel Shader";
        case MESA_SHADER_COMPUTE: return "Compute Shader";
        default:
@@ -363,6 +367,7 @@ static void radv_fill_shader_variant(struct radv_device 
*device,
 
        switch (stage) {
        case MESA_SHADER_VERTEX:
+       case MESA_SHADER_GEOMETRY:
                variant->rsrc2 = 
S_00B12C_USER_SGPR(variant->info.num_user_sgprs) |
                        S_00B12C_SCRATCH_EN(scratch_enabled);
                vgpr_comp_cnt = variant->info.vs.vgpr_comp_cnt;
@@ -445,6 +450,43 @@ static struct radv_shader_variant 
*radv_shader_variant_create(struct radv_device
        return variant;
 }
 
+static struct radv_shader_variant *
+radv_pipeline_create_gs_copy_shader(struct radv_pipeline *pipeline,
+                                   struct nir_shader *nir,
+                                   void** code_out,
+                                   unsigned *code_size_out,
+                                   bool dump_shader)
+{
+       struct radv_shader_variant *variant = calloc(1, sizeof(struct 
radv_shader_variant));
+       enum radeon_family chip_family = 
pipeline->device->physical_device->rad_info.family;
+       LLVMTargetMachineRef tm;
+       if (!variant)
+               return NULL;
+
+       struct ac_nir_compiler_options options = {0};
+       struct ac_shader_binary binary;
+       options.family = chip_family;
+       options.chip_class = 
pipeline->device->physical_device->rad_info.chip_class;
+
+       tm = ac_create_target_machine(chip_family);
+       ac_create_gs_copy_shader(tm, nir, &binary, &variant->config, 
&variant->info, &options, dump_shader);
+       LLVMDisposeTargetMachine(tm);
+
+       radv_fill_shader_variant(pipeline->device, variant, &binary, 
MESA_SHADER_VERTEX);
+
+       if (code_out) {
+               *code_out = binary.code;
+               *code_size_out = binary.code_size;
+       } else
+               free(binary.code);
+       free(binary.config);
+       free(binary.rodata);
+       free(binary.global_symbol_offsets);
+       free(binary.relocs);
+       free(binary.disasm_string);
+       variant->ref_count = 1;
+       return variant; 
+}
 
 static struct radv_shader_variant *
 radv_pipeline_compile(struct radv_pipeline *pipeline,
@@ -457,6 +499,7 @@ radv_pipeline_compile(struct radv_pipeline *pipeline,
                      const union ac_shader_variant_key *key)
 {
        unsigned char sha1[20];
+       unsigned char gs_copy_sha1[20];
        struct radv_shader_variant *variant;
        nir_shader *nir;
        void *code = NULL;
@@ -468,12 +511,23 @@ radv_pipeline_compile(struct radv_pipeline *pipeline,
                                   strlen(module->nir->info->name),
                                   module->sha1);
 
-       radv_hash_shader(sha1, module, entrypoint, spec_info, layout, key);
+       radv_hash_shader(sha1, module, entrypoint, spec_info, layout, key, 0);
+       if (stage == MESA_SHADER_GEOMETRY)
+               radv_hash_shader(gs_copy_sha1, module, entrypoint, spec_info,
+                                layout, key, 1);
 
        if (cache) {
                variant = 
radv_create_shader_variant_from_pipeline_cache(pipeline->device,
                                                                         cache,
                                                                         sha1);
+
+               if (stage == MESA_SHADER_GEOMETRY) {
+                       pipeline->gs_copy_shader =
+                               radv_create_shader_variant_from_pipeline_cache(
+                                       pipeline->device,
+                                       cache,
+                                       gs_copy_sha1);
+               }
                if (variant)
                        return variant;
        }
@@ -486,8 +540,24 @@ radv_pipeline_compile(struct radv_pipeline *pipeline,
 
        variant = radv_shader_variant_create(pipeline->device, nir, layout, key,
                                             &code, &code_size, dump);
+
+       if (stage == MESA_SHADER_GEOMETRY) {
+               void *gs_copy_code = NULL;
+               unsigned gs_copy_code_size = 0;
+               pipeline->gs_copy_shader = radv_pipeline_create_gs_copy_shader(
+                       pipeline, nir, &gs_copy_code, &gs_copy_code_size, dump);
+
+               if (pipeline->gs_copy_shader && cache) {
+                       pipeline->gs_copy_shader =
+                               radv_pipeline_cache_insert_shader(cache,
+                                                                 gs_copy_sha1,
+                                                                 
pipeline->gs_copy_shader,
+                                                                 gs_copy_code,
+                                                                 
gs_copy_code_size);
+               }
+       }
        if (!module->nir)
-                       ralloc_free(nir);
+               ralloc_free(nir);
 
        if (variant && cache)
                variant = radv_pipeline_cache_insert_shader(cache, sha1, 
variant,
@@ -1118,6 +1188,29 @@ si_translate_prim(enum VkPrimitiveTopology topology)
 }
 
 static uint32_t
+si_conv_gl_prim_to_gs_out(unsigned gl_prim)
+{
+       switch (gl_prim) {
+       case 0: /* GL_POINTS */
+               return V_028A6C_OUTPRIM_TYPE_POINTLIST;
+       case 1: /* GL_LINES */
+       case 3: /* GL_LINE_STRIP */
+       case 0xA: /* GL_LINE_STRIP_ADJACENCY_ARB */
+       case 0x8E7A: /* GL_ISOLINES */
+               return V_028A6C_OUTPRIM_TYPE_LINESTRIP;
+
+       case 4: /* GL_TRIANGLES */
+       case 0xc: /* GL_TRIANGLES_ADJACENCY_ARB */
+       case 5: /* GL_TRIANGLE_STRIP */
+       case 7: /* GL_QUADS */
+               return V_028A6C_OUTPRIM_TYPE_TRISTRIP;
+       default:
+               assert(0);
+               return 0;
+       }
+}
+
+static uint32_t
 si_conv_prim_to_gs_out(enum VkPrimitiveTopology topology)
 {
        switch (topology) {
@@ -1285,7 +1378,7 @@ radv_pipeline_init_dynamic_state(struct radv_pipeline 
*pipeline,
 }
 
 static union ac_shader_variant_key
-radv_compute_vs_key(const VkGraphicsPipelineCreateInfo *pCreateInfo)
+radv_compute_vs_key(const VkGraphicsPipelineCreateInfo *pCreateInfo, bool 
as_es)
 {
        union ac_shader_variant_key key;
        const VkPipelineVertexInputStateCreateInfo *input_state =
@@ -1293,6 +1386,7 @@ radv_compute_vs_key(const VkGraphicsPipelineCreateInfo 
*pCreateInfo)
 
        memset(&key, 0, sizeof(key));
        key.vs.instance_rate_inputs = 0;
+       key.vs.as_es = as_es;
 
        for (unsigned i = 0; i < input_state->vertexAttributeDescriptionCount; 
++i) {
                unsigned binding;
@@ -1332,7 +1426,8 @@ radv_pipeline_init(struct radv_pipeline *pipeline,
 
        /* */
        if (modules[MESA_SHADER_VERTEX]) {
-               union ac_shader_variant_key key = 
radv_compute_vs_key(pCreateInfo);
+               bool as_es = modules[MESA_SHADER_GEOMETRY] != NULL;
+               union ac_shader_variant_key key = 
radv_compute_vs_key(pCreateInfo, as_es);
 
                pipeline->shaders[MESA_SHADER_VERTEX] =
                         radv_pipeline_compile(pipeline, cache, 
modules[MESA_SHADER_VERTEX],
@@ -1344,6 +1439,19 @@ radv_pipeline_init(struct radv_pipeline *pipeline,
                pipeline->active_stages |= 
mesa_to_vk_shader_stage(MESA_SHADER_VERTEX);
        }
 
+       if (modules[MESA_SHADER_GEOMETRY]) {
+               union ac_shader_variant_key key = 
radv_compute_vs_key(pCreateInfo, false);
+
+               pipeline->shaders[MESA_SHADER_GEOMETRY] =
+                        radv_pipeline_compile(pipeline, cache, 
modules[MESA_SHADER_GEOMETRY],
+                                              
pStages[MESA_SHADER_GEOMETRY]->pName,
+                                              MESA_SHADER_GEOMETRY,
+                                              
pStages[MESA_SHADER_GEOMETRY]->pSpecializationInfo,
+                                              pipeline->layout, &key);
+
+               pipeline->active_stages |= 
mesa_to_vk_shader_stage(MESA_SHADER_GEOMETRY);
+       }
+
        if (!modules[MESA_SHADER_FRAGMENT]) {
                nir_builder fs_b;
                nir_builder_init_simple_shader(&fs_b, NULL, 
MESA_SHADER_FRAGMENT, NULL);
@@ -1375,7 +1483,11 @@ radv_pipeline_init(struct radv_pipeline *pipeline,
        radv_pipeline_init_raster_state(pipeline, pCreateInfo);
        radv_pipeline_init_multisample_state(pipeline, pCreateInfo);
        pipeline->graphics.prim = 
si_translate_prim(pCreateInfo->pInputAssemblyState->topology);
-       pipeline->graphics.gs_out = 
si_conv_prim_to_gs_out(pCreateInfo->pInputAssemblyState->topology);
+       if (radv_pipeline_has_gs(pipeline)) {
+               pipeline->graphics.gs_out = 
si_conv_gl_prim_to_gs_out(pipeline->shaders[MESA_SHADER_GEOMETRY]->info.gs.output_prim);
+       } else {
+               pipeline->graphics.gs_out = 
si_conv_prim_to_gs_out(pCreateInfo->pInputAssemblyState->topology);
+       }
        if (extra && extra->use_rectlist) {
                pipeline->graphics.prim = V_008958_DI_PT_RECTLIST;
                pipeline->graphics.gs_out = V_028A6C_OUTPRIM_TYPE_TRISTRIP;
diff --git a/src/amd/vulkan/radv_pipeline_cache.c 
b/src/amd/vulkan/radv_pipeline_cache.c
index 2cb1dfb..7fc4e78 100644
--- a/src/amd/vulkan/radv_pipeline_cache.c
+++ b/src/amd/vulkan/radv_pipeline_cache.c
@@ -88,7 +88,8 @@ radv_hash_shader(unsigned char *hash, struct 
radv_shader_module *module,
                 const char *entrypoint,
                 const VkSpecializationInfo *spec_info,
                 const struct radv_pipeline_layout *layout,
-                const union ac_shader_variant_key *key)
+                const union ac_shader_variant_key *key,
+                uint32_t is_geom_copy_shader)
 {
        struct mesa_sha1 *ctx;
 
@@ -104,6 +105,7 @@ radv_hash_shader(unsigned char *hash, struct 
radv_shader_module *module,
                                  spec_info->mapEntryCount * sizeof 
spec_info->pMapEntries[0]);
                _mesa_sha1_update(ctx, spec_info->pData, spec_info->dataSize);
        }
+       _mesa_sha1_update(ctx, &is_geom_copy_shader, 4);
        _mesa_sha1_final(ctx, hash);
 }
 
diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h
index f8bc007..53f2f55 100644
--- a/src/amd/vulkan/radv_private.h
+++ b/src/amd/vulkan/radv_private.h
@@ -820,7 +820,8 @@ radv_hash_shader(unsigned char *hash, struct 
radv_shader_module *module,
                 const char *entrypoint,
                 const VkSpecializationInfo *spec_info,
                 const struct radv_pipeline_layout *layout,
-                const union ac_shader_variant_key *key);
+                const union ac_shader_variant_key *key,
+                uint32_t is_geom_copy_shader);
 
 static inline gl_shader_stage
 vk_to_mesa_shader_stage(VkShaderStageFlagBits vk_stage)
@@ -905,6 +906,7 @@ struct radv_pipeline {
        bool                                         needs_data_cache;
 
        struct radv_shader_variant *                 
shaders[MESA_SHADER_STAGES];
+       struct radv_shader_variant *gs_copy_shader;
        VkShaderStageFlags                           active_stages;
 
        uint32_t va_rsrc_word3[MAX_VERTEX_ATTRIBS];
-- 
2.9.3

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to