[Mesa-dev] [PATCH 08/21] anv/pipeline: Populate keys up-front

Jason Ekstrand jason at jlekstrand.net
Sat Oct 28 18:36:16 UTC 2017


Instead of having each anv_pipeline_compile_* function populate the
shader key, make it part of the anv_pipeline_stage struct and fill it
out up-front.
---
 src/intel/vulkan/anv_pipeline.c | 113 +++++++++++++++++++++-------------------
 1 file changed, 59 insertions(+), 54 deletions(-)

diff --git a/src/intel/vulkan/anv_pipeline.c b/src/intel/vulkan/anv_pipeline.c
index 311bd91..0ebc90b 100644
--- a/src/intel/vulkan/anv_pipeline.c
+++ b/src/intel/vulkan/anv_pipeline.c
@@ -365,12 +365,13 @@ struct anv_pipeline_stage {
    const struct anv_shader_module *module;
    const char *entrypoint;
    const VkSpecializationInfo *spec_info;
+
+   union brw_any_prog_key key;
 };
 
 static void
 anv_pipeline_hash_shader(struct anv_pipeline *pipeline,
                          struct anv_pipeline_stage *stage,
-                         const void *key, size_t key_size,
                          unsigned char *sha1_out)
 {
    struct mesa_sha1 ctx;
@@ -394,7 +395,7 @@ anv_pipeline_hash_shader(struct anv_pipeline *pipeline,
       _mesa_sha1_update(&ctx, stage->spec_info->pData,
                         stage->spec_info->dataSize);
    }
-   _mesa_sha1_update(&ctx, key, key_size);
+   _mesa_sha1_update(&ctx, &stage->key, brw_prog_key_size(stage->stage));
    _mesa_sha1_final(&ctx, sha1_out);
 }
 
@@ -513,14 +514,11 @@ anv_pipeline_compile_vs(struct anv_pipeline *pipeline,
 {
    const struct brw_compiler *compiler =
       pipeline->device->instance->physicalDevice.compiler;
-   struct brw_vs_prog_key key;
    struct anv_shader_bin *bin = NULL;
    unsigned char sha1[20];
 
-   populate_vs_prog_key(&pipeline->device->info, &key);
-
    if (cache) {
-      anv_pipeline_hash_shader(pipeline, stage, &key, sizeof(key), sha1);
+      anv_pipeline_hash_shader(pipeline, stage, sha1);
       bin = anv_pipeline_cache_search(cache, sha1, 20);
    }
 
@@ -551,8 +549,8 @@ anv_pipeline_compile_vs(struct anv_pipeline *pipeline,
                           nir->info.separate_shader);
 
       const unsigned *shader_code =
-         brw_compile_vs(compiler, NULL, mem_ctx, &key, &prog_data, nir,
-                        false, -1, NULL);
+         brw_compile_vs(compiler, NULL, mem_ctx, &stage->key.vs,
+                        &prog_data, nir, false, -1, NULL);
       if (shader_code == NULL) {
          ralloc_free(mem_ctx);
          return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
@@ -618,30 +616,20 @@ merge_tess_info(struct shader_info *tes_info,
 static VkResult
 anv_pipeline_compile_tcs_tes(struct anv_pipeline *pipeline,
                              struct anv_pipeline_cache *cache,
-                             const VkGraphicsPipelineCreateInfo *info,
                              struct anv_pipeline_stage *tcs_stage,
                              struct anv_pipeline_stage *tes_stage)
 {
    const struct gen_device_info *devinfo = &pipeline->device->info;
    const struct brw_compiler *compiler =
       pipeline->device->instance->physicalDevice.compiler;
-   struct brw_tcs_prog_key tcs_key = {};
-   struct brw_tes_prog_key tes_key = {};
    struct anv_shader_bin *tcs_bin = NULL;
    struct anv_shader_bin *tes_bin = NULL;
    unsigned char tcs_sha1[40];
    unsigned char tes_sha1[40];
 
-   populate_tcs_prog_key(&pipeline->device->info,
-                         info->pTessellationState->patchControlPoints,
-                         &tcs_key);
-   populate_tes_prog_key(&pipeline->device->info, &tes_key);
-
    if (cache) {
-      anv_pipeline_hash_shader(pipeline, tcs_stage,
-                               &tcs_key, sizeof(tcs_key), tcs_sha1);
-      anv_pipeline_hash_shader(pipeline, tes_stage,
-                               &tes_key, sizeof(tes_key), tes_sha1);
+      anv_pipeline_hash_shader(pipeline, tcs_stage, tcs_sha1);
+      anv_pipeline_hash_shader(pipeline, tes_stage, tes_sha1);
       memcpy(&tcs_sha1[20], tes_sha1, 20);
       memcpy(&tes_sha1[20], tcs_sha1, 20);
       tcs_bin = anv_pipeline_cache_search(cache, tcs_sha1, sizeof(tcs_sha1));
@@ -691,23 +679,25 @@ anv_pipeline_compile_tcs_tes(struct anv_pipeline *pipeline,
        * this comes from the SPIR-V, which is part of the hash used for the
        * pipeline cache.  So it should be safe.
        */
-      tcs_key.tes_primitive_mode = tes_nir->info.tess.primitive_mode;
-      tcs_key.outputs_written = tcs_nir->info.outputs_written;
-      tcs_key.patch_outputs_written = tcs_nir->info.patch_outputs_written;
-      tcs_key.quads_workaround =
+      tcs_stage->key.tcs.tes_primitive_mode = tes_nir->info.tess.primitive_mode;
+      tcs_stage->key.tcs.outputs_written = tcs_nir->info.outputs_written;
+      tcs_stage->key.tcs.patch_outputs_written =
+         tcs_nir->info.patch_outputs_written;
+      tcs_stage->key.tcs.quads_workaround =
          devinfo->gen < 9 &&
          tes_nir->info.tess.primitive_mode == 7 /* GL_QUADS */ &&
          tes_nir->info.tess.spacing == TESS_SPACING_EQUAL;
 
-      tes_key.inputs_read = tcs_key.outputs_written;
-      tes_key.patch_inputs_read = tcs_key.patch_outputs_written;
+      tes_stage->key.tes.inputs_read = tcs_nir->info.outputs_written;
+      tes_stage->key.tes.patch_inputs_read =
+         tcs_nir->info.patch_outputs_written;
 
       const int shader_time_index = -1;
       const unsigned *shader_code;
 
       shader_code =
-         brw_compile_tcs(compiler, NULL, mem_ctx, &tcs_key, &tcs_prog_data,
-                         tcs_nir, shader_time_index, NULL);
+         brw_compile_tcs(compiler, NULL, mem_ctx, &tcs_stage->key.tcs,
+                         &tcs_prog_data, tcs_nir, shader_time_index, NULL);
       if (shader_code == NULL) {
          ralloc_free(mem_ctx);
          return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
@@ -726,7 +716,7 @@ anv_pipeline_compile_tcs_tes(struct anv_pipeline *pipeline,
       }
 
       shader_code =
-         brw_compile_tes(compiler, NULL, mem_ctx, &tes_key,
+         brw_compile_tes(compiler, NULL, mem_ctx, &tes_stage->key.tes,
                          &tcs_prog_data.base.vue_map, &tes_prog_data, tes_nir,
                          NULL, shader_time_index, NULL);
       if (shader_code == NULL) {
@@ -762,14 +752,11 @@ anv_pipeline_compile_gs(struct anv_pipeline *pipeline,
 {
    const struct brw_compiler *compiler =
       pipeline->device->instance->physicalDevice.compiler;
-   struct brw_gs_prog_key key;
    struct anv_shader_bin *bin = NULL;
    unsigned char sha1[20];
 
-   populate_gs_prog_key(&pipeline->device->info, &key);
-
    if (cache) {
-      anv_pipeline_hash_shader(pipeline, stage, &key, sizeof(key), sha1);
+      anv_pipeline_hash_shader(pipeline, stage, sha1);
       bin = anv_pipeline_cache_search(cache, sha1, 20);
    }
 
@@ -800,8 +787,8 @@ anv_pipeline_compile_gs(struct anv_pipeline *pipeline,
                           nir->info.separate_shader);
 
       const unsigned *shader_code =
-         brw_compile_gs(compiler, NULL, mem_ctx, &key, &prog_data, nir,
-                        NULL, -1, NULL);
+         brw_compile_gs(compiler, NULL, mem_ctx, &stage->key.gs,
+                        &prog_data, nir, NULL, -1, NULL);
       if (shader_code == NULL) {
          ralloc_free(mem_ctx);
          return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
@@ -829,28 +816,22 @@ anv_pipeline_compile_gs(struct anv_pipeline *pipeline,
 static VkResult
 anv_pipeline_compile_fs(struct anv_pipeline *pipeline,
                         struct anv_pipeline_cache *cache,
-                        const VkGraphicsPipelineCreateInfo *info,
                         struct anv_pipeline_stage *stage)
 {
    const struct brw_compiler *compiler =
       pipeline->device->instance->physicalDevice.compiler;
-   struct brw_wm_prog_key key;
    struct anv_shader_bin *bin = NULL;
    unsigned char sha1[20];
 
-   populate_wm_prog_key(&pipeline->device->info,
-                        info->pMultisampleState,
-                        pipeline->subpass->color_count, &key);
-
    /* TODO: we could set this to 0 based on the information in nir_shader, but
     * we need this before we call spirv_to_nir.
     */
    const struct brw_vue_map *vue_map =
       &anv_pipeline_get_last_vue_prog_data(pipeline)->vue_map;
-   key.input_slots_valid = vue_map->slots_valid;
+   stage->key.wm.input_slots_valid = vue_map->slots_valid;
 
    if (cache) {
-      anv_pipeline_hash_shader(pipeline, stage, &key, sizeof(key), sha1);
+      anv_pipeline_hash_shader(pipeline, stage, sha1);
       bin = anv_pipeline_cache_search(cache, sha1, 20);
    }
 
@@ -881,7 +862,7 @@ anv_pipeline_compile_fs(struct anv_pipeline *pipeline,
             continue;
 
          unsigned rt = var->data.location - FRAG_RESULT_DATA0;
-         if (rt >= key.nr_color_regions) {
+         if (rt >= stage->key.wm.nr_color_regions) {
             /* Out-of-bounds, throw it away */
             var->data.mode = nir_var_local;
             exec_node_remove(&var->node);
@@ -927,8 +908,8 @@ anv_pipeline_compile_fs(struct anv_pipeline *pipeline,
       anv_fill_binding_table(&prog_data.base, num_rts);
 
       const unsigned *shader_code =
-         brw_compile_fs(compiler, NULL, mem_ctx, &key, &prog_data, nir,
-                        NULL, -1, -1, true, false, NULL, NULL);
+         brw_compile_fs(compiler, NULL, mem_ctx, &stage->key.wm,
+                        &prog_data, nir, NULL, -1, -1, true, false, NULL, NULL);
       if (shader_code == NULL) {
          ralloc_free(mem_ctx);
          return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
@@ -970,14 +951,13 @@ anv_pipeline_compile_cs(struct anv_pipeline *pipeline,
       .spec_info = spec_info,
    };
 
-   struct brw_cs_prog_key key;
+   populate_cs_prog_key(&pipeline->device->info, &stage.key.cs);
+
    struct anv_shader_bin *bin = NULL;
    unsigned char sha1[20];
 
-   populate_cs_prog_key(&pipeline->device->info, &key);
-
    if (cache) {
-      anv_pipeline_hash_shader(pipeline, &stage, &key, sizeof(key), sha1);
+      anv_pipeline_hash_shader(pipeline, &stage, sha1);
       bin = anv_pipeline_cache_search(cache, sha1, 20);
    }
 
@@ -1003,8 +983,8 @@ anv_pipeline_compile_cs(struct anv_pipeline *pipeline,
       anv_fill_binding_table(&prog_data.base, 1);
 
       const unsigned *shader_code =
-         brw_compile_cs(compiler, NULL, mem_ctx, &key, &prog_data, nir,
-                        -1, NULL);
+         brw_compile_cs(compiler, NULL, mem_ctx, &stage.key.cs,
+                        &prog_data, nir, -1, NULL);
       if (shader_code == NULL) {
          ralloc_free(mem_ctx);
          return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
@@ -1292,6 +1272,31 @@ anv_pipeline_init(struct anv_pipeline *pipeline,
       stages[stage].module = anv_shader_module_from_handle(sinfo->module);
       stages[stage].entrypoint = sinfo->pName;
       stages[stage].spec_info = sinfo->pSpecializationInfo;
+
+      const struct gen_device_info *devinfo = &device->info;
+      switch (stage) {
+      case MESA_SHADER_VERTEX:
+         populate_vs_prog_key(devinfo, &stages[stage].key.vs);
+         break;
+      case MESA_SHADER_TESS_CTRL:
+         populate_tcs_prog_key(devinfo,
+                               pCreateInfo->pTessellationState->patchControlPoints,
+                               &stages[stage].key.tcs);
+         break;
+      case MESA_SHADER_TESS_EVAL:
+         populate_tes_prog_key(devinfo, &stages[stage].key.tes);
+         break;
+      case MESA_SHADER_GEOMETRY:
+         populate_gs_prog_key(devinfo, &stages[stage].key.gs);
+         break;
+      case MESA_SHADER_FRAGMENT:
+         populate_wm_prog_key(devinfo, pCreateInfo->pMultisampleState,
+                              pipeline->subpass->color_count,
+                              &stages[stage].key.wm);
+         break;
+      default:
+         unreachable("Invalid graphics shader stage");
+      }
    }
 
    if (stages[MESA_SHADER_VERTEX].entrypoint) {
@@ -1302,7 +1307,7 @@ anv_pipeline_init(struct anv_pipeline *pipeline,
    }
 
    if (stages[MESA_SHADER_TESS_EVAL].entrypoint) {
-      anv_pipeline_compile_tcs_tes(pipeline, cache, pCreateInfo,
+      anv_pipeline_compile_tcs_tes(pipeline, cache,
                                    &stages[MESA_SHADER_TESS_CTRL],
                                    &stages[MESA_SHADER_TESS_EVAL]);
    }
@@ -1315,7 +1320,7 @@ anv_pipeline_init(struct anv_pipeline *pipeline,
    }
 
    if (stages[MESA_SHADER_FRAGMENT].entrypoint) {
-      result = anv_pipeline_compile_fs(pipeline, cache, pCreateInfo,
+      result = anv_pipeline_compile_fs(pipeline, cache,
                                        &stages[MESA_SHADER_FRAGMENT]);
       if (result != VK_SUCCESS)
          goto compile_fail;
-- 
2.5.0.400.gff86faf



More information about the mesa-dev mailing list