radv: Add code to compile merged shaders.
authorBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Mon, 16 Oct 2017 11:18:02 +0000 (13:18 +0200)
committerBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Thu, 19 Oct 2017 20:25:23 +0000 (22:25 +0200)
Reviewed-by: Dave Airlie <airlied@redhat.com>
src/amd/common/ac_nir_to_llvm.h
src/amd/vulkan/radv_pipeline.c
src/amd/vulkan/radv_shader.c
src/amd/vulkan/radv_shader.h

index 360d613d58dcdb041e0c6b5790d52c6e86706b45..eecc2cb8d493d48a85c1830d3280b768529b9857 100644 (file)
@@ -52,6 +52,7 @@ struct ac_tes_variant_key {
 };
 
 struct ac_tcs_variant_key {
+       struct ac_vs_variant_key vs_key;
        unsigned primitive_mode;
        unsigned input_vertices;
 };
index 7102d07a03a19670bd44f04d6ea3ecdea31ee507..4f840d156fa895853706d10f1c98ae42183d9531 100644 (file)
@@ -1637,7 +1637,7 @@ void radv_create_shaders(struct radv_pipeline *pipeline,
 
        if (nir[MESA_SHADER_FRAGMENT]) {
                pipeline->shaders[MESA_SHADER_FRAGMENT] =
-                       radv_shader_variant_create(device, modules[MESA_SHADER_FRAGMENT], nir[MESA_SHADER_FRAGMENT],
+                       radv_shader_variant_create(device, modules[MESA_SHADER_FRAGMENT], &nir[MESA_SHADER_FRAGMENT], 1,
                                                   pipeline->layout, keys ? keys + MESA_SHADER_FRAGMENT : 0,
                                                   &codes[MESA_SHADER_FRAGMENT], &code_sizes[MESA_SHADER_FRAGMENT]);
 
@@ -1652,14 +1652,35 @@ void radv_create_shaders(struct radv_pipeline *pipeline,
                pipeline->active_stages |= mesa_to_vk_shader_stage(MESA_SHADER_FRAGMENT);
        }
 
+       if (device->physical_device->rad_info.chip_class >= GFX9 &&
+           modules[MESA_SHADER_TESS_CTRL] && !pipeline->shaders[MESA_SHADER_TESS_CTRL]) {
+               struct nir_shader *combined_nir[] = {nir[MESA_SHADER_VERTEX], nir[MESA_SHADER_TESS_CTRL]};
+               struct ac_shader_variant_key key = keys[MESA_SHADER_TESS_CTRL];
+               key.tcs.vs_key = keys[MESA_SHADER_VERTEX].vs;
+               pipeline->shaders[MESA_SHADER_TESS_CTRL] = radv_shader_variant_create(device, modules[MESA_SHADER_TESS_CTRL], combined_nir, 2,
+                                                                                     pipeline->layout,
+                                                                                     &key, &codes[MESA_SHADER_TESS_CTRL],
+                                                                                     &code_sizes[MESA_SHADER_TESS_CTRL]);
+               modules[MESA_SHADER_VERTEX] = NULL;
+       }
+
+       if (device->physical_device->rad_info.chip_class >= GFX9 &&
+           modules[MESA_SHADER_GEOMETRY] && !pipeline->shaders[MESA_SHADER_GEOMETRY]) {
+               gl_shader_stage pre_stage = modules[MESA_SHADER_TESS_EVAL] ? MESA_SHADER_TESS_EVAL : MESA_SHADER_VERTEX;
+               struct nir_shader *combined_nir[] = {nir[pre_stage], nir[MESA_SHADER_GEOMETRY]};
+               pipeline->shaders[MESA_SHADER_GEOMETRY] = radv_shader_variant_create(device, modules[MESA_SHADER_GEOMETRY], combined_nir, 2,
+                                                                                    pipeline->layout,
+                                                                                    &keys[pre_stage] , &codes[MESA_SHADER_GEOMETRY],
+                                                                                    &code_sizes[MESA_SHADER_GEOMETRY]);
+               modules[pre_stage] = NULL;
+       }
+
        for (int i = 0; i < MESA_SHADER_STAGES; ++i) {
                if(modules[i] && !pipeline->shaders[i]) {
-                       pipeline->shaders[i] = radv_shader_variant_create(device, modules[i], nir[i],
+                       pipeline->shaders[i] = radv_shader_variant_create(device, modules[i], &nir[i], 1,
                                                                          pipeline->layout,
                                                                          keys ? keys + i : 0, &codes[i],
                                                                          &code_sizes[i]);
-
-               pipeline->active_stages |= mesa_to_vk_shader_stage(i);
                }
        }
 
index 19153aac6c9240c7136db476b95cfdb58449d6e0..ed76e1d024213a7b9f24cfcc9d4a5150eadd24b2 100644 (file)
@@ -378,7 +378,8 @@ radv_fill_shader_variant(struct radv_device *device,
 static struct radv_shader_variant *
 shader_variant_create(struct radv_device *device,
                      struct radv_shader_module *module,
-                     struct nir_shader *shader,
+                     struct nir_shader * const *shaders,
+                     int shader_count,
                      gl_shader_stage stage,
                      struct ac_nir_compiler_options *options,
                      bool gs_copy_shader,
@@ -406,11 +407,12 @@ shader_variant_create(struct radv_device *device,
        tm = ac_create_target_machine(chip_family, tm_options);
 
        if (gs_copy_shader) {
-               ac_create_gs_copy_shader(tm, shader, &binary, &variant->config,
+               assert(shader_count == 1);
+               ac_create_gs_copy_shader(tm, *shaders, &binary, &variant->config,
                                         &variant->info, options, dump_shaders);
        } else {
                ac_compile_nir_shader(tm, &binary, &variant->config,
-                                     &variant->info, &shader, 1, options,
+                                     &variant->info, shaders, shader_count, options,
                                      dump_shaders);
        }
 
@@ -432,7 +434,7 @@ shader_variant_create(struct radv_device *device,
        if (device->trace_bo) {
                variant->disasm_string = binary.disasm_string;
                if (!gs_copy_shader && !module->nir) {
-                       variant->nir = shader;
+                       variant->nir = *shaders;
                        variant->spirv = (uint32_t *)module->data;
                        variant->spirv_size = module->size;
                }
@@ -446,7 +448,8 @@ shader_variant_create(struct radv_device *device,
 struct radv_shader_variant *
 radv_shader_variant_create(struct radv_device *device,
                           struct radv_shader_module *module,
-                          struct nir_shader *shader,
+                          struct nir_shader *const *shaders,
+                          int shader_count,
                           struct radv_pipeline_layout *layout,
                           const struct ac_shader_variant_key *key,
                           void **code_out,
@@ -461,7 +464,7 @@ radv_shader_variant_create(struct radv_device *device,
        options.unsafe_math = !!(device->instance->debug_flags & RADV_DEBUG_UNSAFE_MATH);
        options.supports_spill = device->llvm_supports_spill;
 
-       return shader_variant_create(device, module, shader, shader->stage,
+       return shader_variant_create(device, module, shaders, shader_count, shaders[shader_count - 1]->stage,
                                     &options, false, code_out, code_size_out);
 }
 
@@ -476,7 +479,7 @@ radv_create_gs_copy_shader(struct radv_device *device,
 
        options.key.has_multiview_view_index = multiview;
 
-       return shader_variant_create(device, NULL, shader, MESA_SHADER_VERTEX,
+       return shader_variant_create(device, NULL, &shader, 1, MESA_SHADER_VERTEX,
                                     &options, true, code_out, code_size_out);
 }
 
index 3862b3094cb5e6fc50630805a46b34edf535d20d..952594a18e08de49db23189910923234cf016bdd 100644 (file)
@@ -87,10 +87,11 @@ radv_destroy_shader_slabs(struct radv_device *device);
 struct radv_shader_variant *
 radv_shader_variant_create(struct radv_device *device,
                           struct radv_shader_module *module,
-                          struct nir_shader *shader,
+                          struct nir_shader *const *shaders,
+                          int shader_count,
                           struct radv_pipeline_layout *layout,
                           const struct ac_shader_variant_key *key,
-                          void ** code_out,
+                          void **code_out,
                           unsigned *code_size_out);
 
 struct radv_shader_variant *