keys[MESA_SHADER_FRAGMENT].fs.num_samples = key->num_samples;
}
+static void
+radv_fill_shader_info(struct radv_pipeline *pipeline,
+ struct radv_shader_variant_key *keys,
+ struct radv_shader_info *infos,
+ nir_shader **nir)
+{
+ unsigned active_stages = 0;
+ unsigned filled_stages = 0;
+
+ for (int i = 0; i < MESA_SHADER_STAGES; i++) {
+ if (nir[i])
+ active_stages |= (1 << i);
+ }
+
+ if (nir[MESA_SHADER_FRAGMENT]) {
+ radv_nir_shader_info_init(&infos[MESA_SHADER_FRAGMENT]);
+ radv_nir_shader_info_pass(nir[MESA_SHADER_FRAGMENT],
+ pipeline->layout,
+ &keys[MESA_SHADER_FRAGMENT],
+ &infos[MESA_SHADER_FRAGMENT]);
+
+ /* TODO: These are no longer used as keys we should refactor this */
+ keys[MESA_SHADER_VERTEX].vs_common_out.export_prim_id =
+ infos[MESA_SHADER_FRAGMENT].ps.prim_id_input;
+ keys[MESA_SHADER_VERTEX].vs_common_out.export_layer_id =
+ infos[MESA_SHADER_FRAGMENT].ps.layer_input;
+ keys[MESA_SHADER_VERTEX].vs_common_out.export_clip_dists =
+ !!infos[MESA_SHADER_FRAGMENT].ps.num_input_clips_culls;
+ keys[MESA_SHADER_TESS_EVAL].vs_common_out.export_prim_id =
+ infos[MESA_SHADER_FRAGMENT].ps.prim_id_input;
+ keys[MESA_SHADER_TESS_EVAL].vs_common_out.export_layer_id =
+ infos[MESA_SHADER_FRAGMENT].ps.layer_input;
+ keys[MESA_SHADER_TESS_EVAL].vs_common_out.export_clip_dists =
+ !!infos[MESA_SHADER_FRAGMENT].ps.num_input_clips_culls;
+
+ filled_stages |= (1 << MESA_SHADER_FRAGMENT);
+ }
+
+ if (pipeline->device->physical_device->rad_info.chip_class >= GFX9 &&
+ nir[MESA_SHADER_TESS_CTRL]) {
+ struct nir_shader *combined_nir[] = {nir[MESA_SHADER_VERTEX], nir[MESA_SHADER_TESS_CTRL]};
+ struct radv_shader_variant_key key = keys[MESA_SHADER_TESS_CTRL];
+ key.tcs.vs_key = keys[MESA_SHADER_VERTEX].vs;
+
+ radv_nir_shader_info_init(&infos[MESA_SHADER_TESS_CTRL]);
+
+ for (int i = 0; i < 2; i++) {
+ radv_nir_shader_info_pass(combined_nir[i],
+ pipeline->layout, &key,
+ &infos[MESA_SHADER_TESS_CTRL]);
+ }
+
+ keys[MESA_SHADER_TESS_EVAL].tes.num_patches =
+ infos[MESA_SHADER_TESS_CTRL].tcs.num_patches;
+ keys[MESA_SHADER_TESS_EVAL].tes.tcs_num_outputs =
+ util_last_bit64(infos[MESA_SHADER_TESS_CTRL].tcs.outputs_written);
+
+ filled_stages |= (1 << MESA_SHADER_VERTEX);
+ filled_stages |= (1 << MESA_SHADER_TESS_CTRL);
+ }
+
+ if (pipeline->device->physical_device->rad_info.chip_class >= GFX9 &&
+ nir[MESA_SHADER_GEOMETRY]) {
+ gl_shader_stage pre_stage = nir[MESA_SHADER_TESS_EVAL] ? MESA_SHADER_TESS_EVAL : MESA_SHADER_VERTEX;
+ struct nir_shader *combined_nir[] = {nir[pre_stage], nir[MESA_SHADER_GEOMETRY]};
+
+ radv_nir_shader_info_init(&infos[MESA_SHADER_GEOMETRY]);
+
+ for (int i = 0; i < 2; i++) {
+ radv_nir_shader_info_pass(combined_nir[i],
+ pipeline->layout,
+ &keys[pre_stage],
+ &infos[MESA_SHADER_GEOMETRY]);
+ }
+
+ filled_stages |= (1 << pre_stage);
+ filled_stages |= (1 << MESA_SHADER_GEOMETRY);
+ }
+
+ active_stages ^= filled_stages;
+ while (active_stages) {
+ int i = u_bit_scan(&active_stages);
+
+ if (i == MESA_SHADER_TESS_CTRL) {
+ keys[MESA_SHADER_TESS_CTRL].tcs.num_inputs =
+ util_last_bit64(infos[MESA_SHADER_VERTEX].vs.ls_outputs_written);
+ }
+
+ if (i == MESA_SHADER_TESS_EVAL) {
+ keys[MESA_SHADER_TESS_EVAL].tes.num_patches =
+ infos[MESA_SHADER_TESS_CTRL].tcs.num_patches;
+ keys[MESA_SHADER_TESS_EVAL].tes.tcs_num_outputs =
+ util_last_bit64(infos[MESA_SHADER_TESS_CTRL].tcs.outputs_written);
+ }
+
+ radv_nir_shader_info_init(&infos[i]);
+ radv_nir_shader_info_pass(nir[i], pipeline->layout,
+ &keys[i], &infos[i]);
+ }
+}
+
static void
merge_tess_info(struct shader_info *tes_info,
const struct shader_info *tcs_info)
nir_shader *nir[MESA_SHADER_STAGES] = {0};
struct radv_shader_binary *binaries[MESA_SHADER_STAGES] = {NULL};
struct radv_shader_variant_key keys[MESA_SHADER_STAGES] = {{{{{0}}}}};
+ struct radv_shader_info infos[MESA_SHADER_STAGES] = {0};
unsigned char hash[20], gs_copy_hash[20];
bool keep_executable_info = (flags & VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR) || device->keep_shader_info;
radv_fill_shader_keys(device, keys, key, nir);
+ radv_fill_shader_info(pipeline, keys, infos, nir);
+
if (nir[MESA_SHADER_FRAGMENT]) {
if (!pipeline->shaders[MESA_SHADER_FRAGMENT]) {
radv_start_feedback(stage_feedbacks[MESA_SHADER_FRAGMENT]);
pipeline->shaders[MESA_SHADER_FRAGMENT] =
radv_shader_variant_compile(device, modules[MESA_SHADER_FRAGMENT], &nir[MESA_SHADER_FRAGMENT], 1,
pipeline->layout, keys + MESA_SHADER_FRAGMENT,
+ infos + MESA_SHADER_FRAGMENT,
keep_executable_info, &binaries[MESA_SHADER_FRAGMENT]);
radv_stop_feedback(stage_feedbacks[MESA_SHADER_FRAGMENT], false);
pipeline->shaders[MESA_SHADER_TESS_CTRL] = radv_shader_variant_compile(device, modules[MESA_SHADER_TESS_CTRL], combined_nir, 2,
pipeline->layout,
- &key, keep_executable_info,
+ &key, &infos[MESA_SHADER_TESS_CTRL], keep_executable_info,
&binaries[MESA_SHADER_TESS_CTRL]);
radv_stop_feedback(stage_feedbacks[MESA_SHADER_TESS_CTRL], false);
pipeline->shaders[MESA_SHADER_GEOMETRY] = radv_shader_variant_compile(device, modules[MESA_SHADER_GEOMETRY], combined_nir, 2,
pipeline->layout,
- &keys[pre_stage], keep_executable_info,
+ &keys[pre_stage], &infos[MESA_SHADER_GEOMETRY], keep_executable_info,
&binaries[MESA_SHADER_GEOMETRY]);
radv_stop_feedback(stage_feedbacks[MESA_SHADER_GEOMETRY], false);
pipeline->shaders[i] = radv_shader_variant_compile(device, modules[i], &nir[i], 1,
pipeline->layout,
- keys + i, keep_executable_info,
+ keys + i, infos + i,keep_executable_info,
&binaries[i]);
radv_stop_feedback(stage_feedbacks[i], false);
struct radv_shader_binary *gs_copy_binary = NULL;
if (!pipeline->gs_copy_shader &&
!radv_pipeline_has_ngg(pipeline)) {
+ struct radv_shader_info info = {};
+ struct radv_shader_variant_key key = {};
+
+ key.has_multiview_view_index =
+ keys[MESA_SHADER_GEOMETRY].has_multiview_view_index;
+
+ radv_nir_shader_info_pass(nir[MESA_SHADER_GEOMETRY],
+ pipeline->layout, &key,
+ &info);
+
pipeline->gs_copy_shader = radv_create_gs_copy_shader(
- device, nir[MESA_SHADER_GEOMETRY], &gs_copy_binary,
- keep_executable_info,
+ device, nir[MESA_SHADER_GEOMETRY], &info,
+ &gs_copy_binary, keep_executable_info,
keys[MESA_SHADER_GEOMETRY].has_multiview_view_index);
}
struct nir_shader * const *shaders,
int shader_count,
gl_shader_stage stage,
+ struct radv_shader_info *info,
struct radv_nir_compiler_options *options,
bool gs_copy_shader,
bool keep_shader_info,
enum ac_target_machine_options tm_options = 0;
struct ac_llvm_compiler ac_llvm;
struct radv_shader_binary *binary = NULL;
- struct radv_shader_info info = {0};
bool thread_compiler;
options->family = chip_family;
if (gs_copy_shader) {
assert(shader_count == 1);
radv_compile_gs_copy_shader(&ac_llvm, *shaders, &binary,
- &info, options);
+ info, options);
} else {
- radv_compile_nir_shader(&ac_llvm, &binary, &info,
+ radv_compile_nir_shader(&ac_llvm, &binary, info,
shaders, shader_count, options);
}
- binary->info = info;
+ binary->info = *info;
radv_destroy_llvm_compiler(&ac_llvm, thread_compiler);
int shader_count,
struct radv_pipeline_layout *layout,
const struct radv_shader_variant_key *key,
+ struct radv_shader_info *info,
bool keep_shader_info,
struct radv_shader_binary **binary_out)
{
options.supports_spill = true;
options.robust_buffer_access = device->robust_buffer_access;
- return shader_variant_compile(device, module, shaders, shader_count, shaders[shader_count - 1]->info.stage,
+ return shader_variant_compile(device, module, shaders, shader_count, shaders[shader_count - 1]->info.stage, info,
&options, false, keep_shader_info, binary_out);
}
struct radv_shader_variant *
radv_create_gs_copy_shader(struct radv_device *device,
struct nir_shader *shader,
+ struct radv_shader_info *info,
struct radv_shader_binary **binary_out,
bool keep_shader_info,
bool multiview)
options.key.has_multiview_view_index = multiview;
return shader_variant_compile(device, NULL, &shader, 1, MESA_SHADER_VERTEX,
- &options, true, keep_shader_info, binary_out);
+ info, &options, true, keep_shader_info, binary_out);
}
void