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>
- 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);
* of various prog_data pointers. Make them NULL by default.
*/
memset(pipeline->shaders, 0, sizeof(pipeline->shaders));
* 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) {
result = anv_pipeline_compile_graphics(pipeline, cache, pCreateInfo);
if (result != VK_SUCCESS) {
ANV_FROM_HANDLE(anv_pipeline, pipeline, pPipelineInfo->pipeline);
VK_OUTARRAY_MAKE(out, pProperties, pExecutableCount);
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) {
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);
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",
if (stage == MESA_SHADER_FRAGMENT) {
WRITE_STR(props->name, "%s%d %s",
simd_width ? "SIMD" : "vec",
return vk_outarray_status(&out);
}
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,
VkResult anv_GetPipelineExecutableStatisticsKHR(
VkDevice device,
const VkPipelineExecutableInfoKHR* pExecutableInfo,
ANV_FROM_HANDLE(anv_pipeline, pipeline, pExecutableInfo->pipeline);
VK_OUTARRAY_MAKE(out, pStatistics, pStatisticCount);
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 =
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;
const struct brw_stage_prog_data *prog_data =
pipeline->shaders[exe->stage]->prog_data;
pInternalRepresentationCount);
bool incomplete_text = false;
pInternalRepresentationCount);
bool incomplete_text = false;
- assert(pExecutableInfo->executableIndex < pipeline->num_executables);
const struct anv_pipeline_executable *exe =
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) {
if (exe->nir) {
vk_outarray_append(&out, ir) {
anv_shader_bin_destroy(device, 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;
struct anv_pipeline_executable {
gl_shader_stage stage;
struct anv_shader_bin * shaders[MESA_SHADER_STAGES];
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;
const struct gen_l3_config * l3_config;
* of various prog_data pointers. Make them NULL by default.
*/
memset(pipeline->shaders, 0, sizeof(pipeline->shaders));
* 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;
assert(pCreateInfo->stage.stage == VK_SHADER_STAGE_COMPUTE_BIT);
pipeline->active_stages |= VK_SHADER_STAGE_COMPUTE_BIT;