static void
handle_vs_outputs_post(struct nir_to_llvm_context *ctx,
+ bool export_prim_id,
struct ac_vs_output_info *outinfo)
{
uint32_t param_count = 0;
ac_build_export(&ctx->ac, &pos_args[i]);
}
+
+ if (export_prim_id) {
+ LLVMValueRef values[4];
+ target = V_008DFC_SQ_EXP_PARAM + param_count;
+ outinfo->vs_output_param_offset[VARYING_SLOT_PRIMITIVE_ID] = param_count;
+ param_count++;
+
+ values[0] = ctx->vs_prim_id;
+ ctx->shader_info->vs.vgpr_comp_cnt = MAX2(2,
+ ctx->shader_info->vs.vgpr_comp_cnt);
+ for (unsigned j = 1; j < 4; j++)
+ values[j] = ctx->f32zero;
+ si_llvm_init_export_args(ctx, values, target, &args);
+ ac_build_export(&ctx->ac, &args);
+ outinfo->export_prim_id = true;
+ }
+
outinfo->pos_exports = num_pos_exports;
outinfo->param_exports = param_count;
}
else if (ctx->options->key.vs.as_es)
handle_es_outputs_post(ctx, &ctx->shader_info->vs.es_info);
else
- handle_vs_outputs_post(ctx, &ctx->shader_info->vs.outinfo);
+ handle_vs_outputs_post(ctx, ctx->options->key.vs.export_prim_id,
+ &ctx->shader_info->vs.outinfo);
break;
case MESA_SHADER_FRAGMENT:
handle_fs_outputs_post(ctx);
if (ctx->options->key.tes.as_es)
handle_es_outputs_post(ctx, &ctx->shader_info->tes.es_info);
else
- handle_vs_outputs_post(ctx, &ctx->shader_info->tes.outinfo);
+ handle_vs_outputs_post(ctx, ctx->options->key.tes.export_prim_id,
+ &ctx->shader_info->tes.outinfo);
break;
default:
break;
}
idx += slot_inc;
}
- handle_vs_outputs_post(ctx, &ctx->shader_info->vs.outinfo);
+ handle_vs_outputs_post(ctx, false, &ctx->shader_info->vs.outinfo);
}
void ac_create_gs_copy_shader(LLVMTargetMachineRef tm,
}
static union ac_shader_variant_key
-radv_compute_tes_key(bool as_es)
+radv_compute_tes_key(bool as_es, bool export_prim_id)
{
union ac_shader_variant_key key;
memset(&key, 0, sizeof(key));
key.tes.as_es = as_es;
+ /* export prim id only happens when no geom shader */
+ if (!as_es)
+ key.tes.export_prim_id = export_prim_id;
return key;
}
nir_shader *tes_nir, *tcs_nir;
void *tes_code = NULL, *tcs_code = NULL;
unsigned tes_code_size = 0, tcs_code_size = 0;
- union ac_shader_variant_key tes_key = radv_compute_tes_key(radv_pipeline_has_gs(pipeline));
+ union ac_shader_variant_key tes_key;
union ac_shader_variant_key tcs_key;
bool dump = (pipeline->device->debug_flags & RADV_DEBUG_DUMP_SHADERS);
+ tes_key = radv_compute_tes_key(radv_pipeline_has_gs(pipeline),
+ pipeline->shaders[MESA_SHADER_FRAGMENT]->info.fs.prim_id_input);
if (tes_module->nir)
_mesa_sha1_compute(tes_module->nir->info.name,
strlen(tes_module->nir->info.name),
}
static union ac_shader_variant_key
-radv_compute_vs_key(const VkGraphicsPipelineCreateInfo *pCreateInfo, bool as_es, bool as_ls)
+radv_compute_vs_key(const VkGraphicsPipelineCreateInfo *pCreateInfo, bool as_es, bool as_ls, bool export_prim_id)
{
union ac_shader_variant_key key;
const VkPipelineVertexInputStateCreateInfo *input_state =
key.vs.instance_rate_inputs = 0;
key.vs.as_es = as_es;
key.vs.as_ls = as_ls;
+ key.vs.export_prim_id = export_prim_id;
for (unsigned i = 0; i < input_state->vertexAttributeDescriptionCount; ++i) {
unsigned binding;
S_028A40_GS_WRITE_OPTIMIZE(1);
}
+static void calculate_vgt_gs_mode(struct radv_pipeline *pipeline)
+{
+ struct radv_shader_variant *vs;
+ vs = radv_pipeline_has_gs(pipeline) ? pipeline->gs_copy_shader : (radv_pipeline_has_tess(pipeline) ? pipeline->shaders[MESA_SHADER_TESS_EVAL] : pipeline->shaders[MESA_SHADER_VERTEX]);
+
+ struct ac_vs_output_info *outinfo = &vs->info.vs.outinfo;
+
+ pipeline->graphics.vgt_primitiveid_en = false;
+ pipeline->graphics.vgt_gs_mode = 0;
+
+ if (radv_pipeline_has_gs(pipeline)) {
+ pipeline->graphics.vgt_gs_mode = si_vgt_gs_mode(pipeline->shaders[MESA_SHADER_GEOMETRY]);
+ } else if (outinfo->export_prim_id) {
+ pipeline->graphics.vgt_gs_mode = S_028A40_MODE(V_028A40_GS_SCENARIO_A);
+ pipeline->graphics.vgt_primitiveid_en = true;
+ }
+}
+
static void calculate_pa_cl_vs_out_cntl(struct radv_pipeline *pipeline)
{
struct radv_shader_variant *vs;
if (modules[MESA_SHADER_VERTEX]) {
bool as_es = false;
bool as_ls = false;
+ bool export_prim_id = false;
if (modules[MESA_SHADER_TESS_CTRL])
as_ls = true;
else if (modules[MESA_SHADER_GEOMETRY])
as_es = true;
- union ac_shader_variant_key key = radv_compute_vs_key(pCreateInfo, as_es, as_ls);
+ else if (pipeline->shaders[MESA_SHADER_FRAGMENT]->info.fs.prim_id_input)
+ export_prim_id = true;
+ union ac_shader_variant_key key = radv_compute_vs_key(pCreateInfo, as_es, as_ls, export_prim_id);
pipeline->shaders[MESA_SHADER_VERTEX] =
radv_pipeline_compile(pipeline, cache, modules[MESA_SHADER_VERTEX],
}
if (modules[MESA_SHADER_GEOMETRY]) {
- union ac_shader_variant_key key = radv_compute_vs_key(pCreateInfo, false, false);
+ union ac_shader_variant_key key = radv_compute_vs_key(pCreateInfo, false, false, false);
pipeline->shaders[MESA_SHADER_GEOMETRY] =
radv_pipeline_compile(pipeline, cache, modules[MESA_SHADER_GEOMETRY],
pipeline->layout, &key);
pipeline->active_stages |= mesa_to_vk_shader_stage(MESA_SHADER_GEOMETRY);
-
- pipeline->graphics.vgt_gs_mode = si_vgt_gs_mode(pipeline->shaders[MESA_SHADER_GEOMETRY]);
- } else
- pipeline->graphics.vgt_gs_mode = 0;
+ }
if (modules[MESA_SHADER_TESS_EVAL]) {
assert(modules[MESA_SHADER_TESS_CTRL]);
ps->info.fs.writes_z ? V_028710_SPI_SHADER_32_R :
V_028710_SPI_SHADER_ZERO;
+ calculate_vgt_gs_mode(pipeline);
calculate_pa_cl_vs_out_cntl(pipeline);
calculate_ps_inputs(pipeline);