anv/pipeline: Pull shader compilation out into a helper.
Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
This commit is contained in:
@@ -1017,6 +1017,122 @@ anv_pipeline_compile_fs(struct anv_pipeline *pipeline,
|
|||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VkResult
|
||||||
|
anv_pipeline_compile_graphics(struct anv_pipeline *pipeline,
|
||||||
|
struct anv_pipeline_cache *cache,
|
||||||
|
const VkGraphicsPipelineCreateInfo *info)
|
||||||
|
{
|
||||||
|
struct anv_pipeline_stage stages[MESA_SHADER_STAGES] = {};
|
||||||
|
|
||||||
|
VkResult result;
|
||||||
|
for (uint32_t i = 0; i < info->stageCount; i++) {
|
||||||
|
const VkPipelineShaderStageCreateInfo *sinfo = &info->pStages[i];
|
||||||
|
gl_shader_stage stage = vk_to_mesa_shader_stage(sinfo->stage);
|
||||||
|
|
||||||
|
pipeline->active_stages |= sinfo->stage;
|
||||||
|
|
||||||
|
stages[stage].stage = stage;
|
||||||
|
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 = &pipeline->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,
|
||||||
|
info->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, pipeline->subpass,
|
||||||
|
info->pMultisampleState,
|
||||||
|
&stages[stage].key.wm);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
unreachable("Invalid graphics shader stage");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pipeline->active_stages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
|
||||||
|
pipeline->active_stages |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
|
||||||
|
|
||||||
|
assert(pipeline->active_stages & VK_SHADER_STAGE_VERTEX_BIT);
|
||||||
|
|
||||||
|
ANV_FROM_HANDLE(anv_pipeline_layout, layout, info->layout);
|
||||||
|
|
||||||
|
unsigned char sha1[20];
|
||||||
|
anv_pipeline_hash_graphics(pipeline, layout, stages, sha1);
|
||||||
|
|
||||||
|
for (unsigned s = 0; s < MESA_SHADER_STAGES; s++) {
|
||||||
|
if (!stages[s].entrypoint)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
stages[s].cache_key.stage = s;
|
||||||
|
memcpy(stages[s].cache_key.sha1, sha1, sizeof(sha1));
|
||||||
|
|
||||||
|
struct anv_shader_bin *bin =
|
||||||
|
anv_device_search_for_kernel(pipeline->device, cache,
|
||||||
|
&stages[s].cache_key,
|
||||||
|
sizeof(stages[s].cache_key));
|
||||||
|
if (bin)
|
||||||
|
anv_pipeline_add_compiled_stage(pipeline, s, bin);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned s = 0; s < MESA_SHADER_STAGES; s++) {
|
||||||
|
if (!stages[s].entrypoint)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
assert(stages[s].stage == s);
|
||||||
|
|
||||||
|
if (pipeline->shaders[s])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (s) {
|
||||||
|
case MESA_SHADER_VERTEX:
|
||||||
|
result = anv_pipeline_compile_vs(pipeline, cache, info,
|
||||||
|
&stages[s]);
|
||||||
|
break;
|
||||||
|
case MESA_SHADER_TESS_CTRL:
|
||||||
|
/* Handled with TESS_EVAL */
|
||||||
|
break;
|
||||||
|
case MESA_SHADER_TESS_EVAL:
|
||||||
|
result = anv_pipeline_compile_tcs_tes(pipeline, cache, info,
|
||||||
|
&stages[MESA_SHADER_TESS_CTRL],
|
||||||
|
&stages[MESA_SHADER_TESS_EVAL]);
|
||||||
|
break;
|
||||||
|
case MESA_SHADER_GEOMETRY:
|
||||||
|
result = anv_pipeline_compile_gs(pipeline, cache, info, &stages[s]);
|
||||||
|
break;
|
||||||
|
case MESA_SHADER_FRAGMENT:
|
||||||
|
result = anv_pipeline_compile_fs(pipeline, cache, info, &stages[s]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
unreachable("Invalid graphics shader stage");
|
||||||
|
}
|
||||||
|
if (result != VK_SUCCESS)
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
return VK_SUCCESS;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
for (unsigned s = 0; s < MESA_SHADER_STAGES; s++) {
|
||||||
|
if (pipeline->shaders[s])
|
||||||
|
anv_shader_bin_unref(pipeline->device, pipeline->shaders[s]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
VkResult
|
VkResult
|
||||||
anv_pipeline_compile_cs(struct anv_pipeline *pipeline,
|
anv_pipeline_compile_cs(struct anv_pipeline *pipeline,
|
||||||
struct anv_pipeline_cache *cache,
|
struct anv_pipeline_cache *cache,
|
||||||
@@ -1358,104 +1474,10 @@ anv_pipeline_init(struct anv_pipeline *pipeline,
|
|||||||
|
|
||||||
pipeline->active_stages = 0;
|
pipeline->active_stages = 0;
|
||||||
|
|
||||||
struct anv_pipeline_stage stages[MESA_SHADER_STAGES] = {};
|
result = anv_pipeline_compile_graphics(pipeline, cache, pCreateInfo);
|
||||||
for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
|
if (result != VK_SUCCESS) {
|
||||||
const VkPipelineShaderStageCreateInfo *sinfo = &pCreateInfo->pStages[i];
|
anv_reloc_list_finish(&pipeline->batch_relocs, alloc);
|
||||||
gl_shader_stage stage = vk_to_mesa_shader_stage(sinfo->stage);
|
return result;
|
||||||
|
|
||||||
pipeline->active_stages |= sinfo->stage;
|
|
||||||
|
|
||||||
stages[stage].stage = stage;
|
|
||||||
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, pipeline->subpass,
|
|
||||||
pCreateInfo->pMultisampleState,
|
|
||||||
&stages[stage].key.wm);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
unreachable("Invalid graphics shader stage");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pipeline->active_stages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
|
|
||||||
pipeline->active_stages |= VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
|
|
||||||
|
|
||||||
assert(pipeline->active_stages & VK_SHADER_STAGE_VERTEX_BIT);
|
|
||||||
|
|
||||||
ANV_FROM_HANDLE(anv_pipeline_layout, layout, pCreateInfo->layout);
|
|
||||||
|
|
||||||
unsigned char sha1[20];
|
|
||||||
anv_pipeline_hash_graphics(pipeline, layout, stages, sha1);
|
|
||||||
|
|
||||||
for (unsigned s = 0; s < MESA_SHADER_STAGES; s++) {
|
|
||||||
if (!stages[s].entrypoint)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
stages[s].cache_key.stage = s;
|
|
||||||
memcpy(stages[s].cache_key.sha1, sha1, sizeof(sha1));
|
|
||||||
|
|
||||||
struct anv_shader_bin *bin =
|
|
||||||
anv_device_search_for_kernel(pipeline->device, cache,
|
|
||||||
&stages[s].cache_key,
|
|
||||||
sizeof(stages[s].cache_key));
|
|
||||||
if (bin)
|
|
||||||
anv_pipeline_add_compiled_stage(pipeline, s, bin);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned s = 0; s < MESA_SHADER_STAGES; s++) {
|
|
||||||
if (!stages[s].entrypoint)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
assert(stages[s].stage == s);
|
|
||||||
|
|
||||||
if (pipeline->shaders[s])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
switch (s) {
|
|
||||||
case MESA_SHADER_VERTEX:
|
|
||||||
result = anv_pipeline_compile_vs(pipeline, cache, pCreateInfo,
|
|
||||||
&stages[s]);
|
|
||||||
break;
|
|
||||||
case MESA_SHADER_TESS_CTRL:
|
|
||||||
/* Handled with TESS_EVAL */
|
|
||||||
break;
|
|
||||||
case MESA_SHADER_TESS_EVAL:
|
|
||||||
result = anv_pipeline_compile_tcs_tes(pipeline, cache, pCreateInfo,
|
|
||||||
&stages[MESA_SHADER_TESS_CTRL],
|
|
||||||
&stages[MESA_SHADER_TESS_EVAL]);
|
|
||||||
break;
|
|
||||||
case MESA_SHADER_GEOMETRY:
|
|
||||||
result = anv_pipeline_compile_gs(pipeline, cache, pCreateInfo,
|
|
||||||
&stages[s]);
|
|
||||||
break;
|
|
||||||
case MESA_SHADER_FRAGMENT:
|
|
||||||
result = anv_pipeline_compile_fs(pipeline, cache, pCreateInfo,
|
|
||||||
&stages[s]);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
unreachable("Invalid graphics shader stage");
|
|
||||||
}
|
|
||||||
if (result != VK_SUCCESS)
|
|
||||||
goto compile_fail;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(pipeline->shaders[MESA_SHADER_VERTEX]);
|
assert(pipeline->shaders[MESA_SHADER_VERTEX]);
|
||||||
@@ -1535,14 +1557,4 @@ anv_pipeline_init(struct anv_pipeline *pipeline,
|
|||||||
pipeline->topology = vk_to_gen_primitive_type[ia_info->topology];
|
pipeline->topology = vk_to_gen_primitive_type[ia_info->topology];
|
||||||
|
|
||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
|
|
||||||
compile_fail:
|
|
||||||
for (unsigned s = 0; s < MESA_SHADER_STAGES; s++) {
|
|
||||||
if (pipeline->shaders[s])
|
|
||||||
anv_shader_bin_unref(device, pipeline->shaders[s]);
|
|
||||||
}
|
|
||||||
|
|
||||||
anv_reloc_list_finish(&pipeline->batch_relocs, alloc);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user