anv: Use a dynamic array for storing executables in pipeline
Avoids waste for pipelines that don't use all the shaders, and is flexible enough to cover cases where there are multiple variants per shader (e.g. SIMD8/16/32 for fragment shader). Even though we could pre-calculate the exact size of the array, this is not a critical path so it is worth preventing the bug that will likely happen when new variants are added but not accounted for. Reviewed-by: Ian Romanick <ian.d.romanick@intel.com> Reviewed-by: Jason Ekstrand <jason@jlekstrand.net> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4040>
This commit is contained in:
@@ -1051,13 +1051,14 @@ anv_pipeline_add_executable(struct anv_pipeline *pipeline,
|
||||
free(stream_data);
|
||||
}
|
||||
|
||||
pipeline->executables[pipeline->num_executables++] =
|
||||
(struct anv_pipeline_executable) {
|
||||
.stage = stage->stage,
|
||||
.stats = *stats,
|
||||
.nir = nir,
|
||||
.disasm = disasm,
|
||||
};
|
||||
const struct anv_pipeline_executable exe = {
|
||||
.stage = stage->stage,
|
||||
.stats = *stats,
|
||||
.nir = nir,
|
||||
.disasm = disasm,
|
||||
};
|
||||
util_dynarray_append(&pipeline->executables,
|
||||
struct anv_pipeline_executable, exe);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1873,7 +1874,8 @@ anv_pipeline_init(struct anv_pipeline *pipeline,
|
||||
* of various prog_data pointers. Make them NULL by default.
|
||||
*/
|
||||
memset(pipeline->shaders, 0, sizeof(pipeline->shaders));
|
||||
pipeline->num_executables = 0;
|
||||
|
||||
util_dynarray_init(&pipeline->executables, pipeline->mem_ctx);
|
||||
|
||||
result = anv_pipeline_compile_graphics(pipeline, cache, pCreateInfo);
|
||||
if (result != VK_SUCCESS) {
|
||||
@@ -1976,12 +1978,12 @@ VkResult anv_GetPipelineExecutablePropertiesKHR(
|
||||
ANV_FROM_HANDLE(anv_pipeline, pipeline, pPipelineInfo->pipeline);
|
||||
VK_OUTARRAY_MAKE(out, pProperties, pExecutableCount);
|
||||
|
||||
for (uint32_t i = 0; i < pipeline->num_executables; i++) {
|
||||
util_dynarray_foreach (&pipeline->executables, struct anv_pipeline_executable, exe) {
|
||||
vk_outarray_append(&out, props) {
|
||||
gl_shader_stage stage = pipeline->executables[i].stage;
|
||||
gl_shader_stage stage = exe->stage;
|
||||
props->stages = mesa_to_vk_shader_stage(stage);
|
||||
|
||||
unsigned simd_width = pipeline->executables[i].stats.dispatch_width;
|
||||
unsigned simd_width = exe->stats.dispatch_width;
|
||||
if (stage == MESA_SHADER_FRAGMENT) {
|
||||
WRITE_STR(props->name, "%s%d %s",
|
||||
simd_width ? "SIMD" : "vec",
|
||||
@@ -2005,6 +2007,15 @@ VkResult anv_GetPipelineExecutablePropertiesKHR(
|
||||
return vk_outarray_status(&out);
|
||||
}
|
||||
|
||||
static const struct anv_pipeline_executable *
|
||||
anv_pipeline_get_executable(struct anv_pipeline *pipeline, uint32_t index)
|
||||
{
|
||||
assert(index < util_dynarray_num_elements(&pipeline->executables,
|
||||
struct anv_pipeline_executable));
|
||||
return util_dynarray_element(
|
||||
&pipeline->executables, struct anv_pipeline_executable, index);
|
||||
}
|
||||
|
||||
VkResult anv_GetPipelineExecutableStatisticsKHR(
|
||||
VkDevice device,
|
||||
const VkPipelineExecutableInfoKHR* pExecutableInfo,
|
||||
@@ -2014,9 +2025,8 @@ VkResult anv_GetPipelineExecutableStatisticsKHR(
|
||||
ANV_FROM_HANDLE(anv_pipeline, pipeline, pExecutableInfo->pipeline);
|
||||
VK_OUTARRAY_MAKE(out, pStatistics, pStatisticCount);
|
||||
|
||||
assert(pExecutableInfo->executableIndex < pipeline->num_executables);
|
||||
const struct anv_pipeline_executable *exe =
|
||||
&pipeline->executables[pExecutableInfo->executableIndex];
|
||||
anv_pipeline_get_executable(pipeline, pExecutableInfo->executableIndex);
|
||||
const struct brw_stage_prog_data *prog_data =
|
||||
pipeline->shaders[exe->stage]->prog_data;
|
||||
|
||||
@@ -2127,9 +2137,8 @@ VkResult anv_GetPipelineExecutableInternalRepresentationsKHR(
|
||||
pInternalRepresentationCount);
|
||||
bool incomplete_text = false;
|
||||
|
||||
assert(pExecutableInfo->executableIndex < pipeline->num_executables);
|
||||
const struct anv_pipeline_executable *exe =
|
||||
&pipeline->executables[pExecutableInfo->executableIndex];
|
||||
anv_pipeline_get_executable(pipeline, pExecutableInfo->executableIndex);
|
||||
|
||||
if (exe->nir) {
|
||||
vk_outarray_append(&out, ir) {
|
||||
|
@@ -3145,9 +3145,6 @@ anv_shader_bin_unref(struct anv_device *device, struct anv_shader_bin *shader)
|
||||
anv_shader_bin_destroy(device, shader);
|
||||
}
|
||||
|
||||
/* 5 possible simultaneous shader stages and FS may have up to 3 binaries */
|
||||
#define MAX_PIPELINE_EXECUTABLES 7
|
||||
|
||||
struct anv_pipeline_executable {
|
||||
gl_shader_stage stage;
|
||||
|
||||
@@ -3178,8 +3175,7 @@ struct anv_pipeline {
|
||||
|
||||
struct anv_shader_bin * shaders[MESA_SHADER_STAGES];
|
||||
|
||||
uint32_t num_executables;
|
||||
struct anv_pipeline_executable executables[MAX_PIPELINE_EXECUTABLES];
|
||||
struct util_dynarray executables;
|
||||
|
||||
const struct gen_l3_config * l3_config;
|
||||
|
||||
|
@@ -2256,7 +2256,8 @@ compute_pipeline_create(
|
||||
* of various prog_data pointers. Make them NULL by default.
|
||||
*/
|
||||
memset(pipeline->shaders, 0, sizeof(pipeline->shaders));
|
||||
pipeline->num_executables = 0;
|
||||
|
||||
util_dynarray_init(&pipeline->executables, pipeline->mem_ctx);
|
||||
|
||||
assert(pCreateInfo->stage.stage == VK_SHADER_STAGE_COMPUTE_BIT);
|
||||
pipeline->active_stages |= VK_SHADER_STAGE_COMPUTE_BIT;
|
||||
|
Reference in New Issue
Block a user