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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev