radv: export implicit primitive ID in NIR for legacy VS or TES
It's implicit for VS or TES, while it's required for GS or MS. Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Reviewed-by: Timur Kristóf <timur.kristof@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16404>
This commit is contained in:

committed by
Marge Bot

parent
d711e9813c
commit
95d4e5435b
@@ -8872,6 +8872,9 @@ visit_intrinsic(isel_context* ctx, nir_intrinsic_instr* instr)
|
|||||||
* even if there is no SW GS. */
|
* even if there is no SW GS. */
|
||||||
bld.copy(Definition(dst), get_arg(ctx, ctx->args->ac.gs_prim_id));
|
bld.copy(Definition(dst), get_arg(ctx, ctx->args->ac.gs_prim_id));
|
||||||
break;
|
break;
|
||||||
|
} else if (ctx->shader->info.stage == MESA_SHADER_VERTEX) {
|
||||||
|
bld.copy(Definition(dst), get_arg(ctx, ctx->args->ac.vs_prim_id));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
unreachable("Unimplemented shader stage for nir_intrinsic_load_primitive_id");
|
unreachable("Unimplemented shader stage for nir_intrinsic_load_primitive_id");
|
||||||
}
|
}
|
||||||
@@ -10632,16 +10635,6 @@ create_vs_exports(isel_context* ctx)
|
|||||||
assert(outinfo);
|
assert(outinfo);
|
||||||
ctx->block->kind |= block_kind_export_end;
|
ctx->block->kind |= block_kind_export_end;
|
||||||
|
|
||||||
if (outinfo->export_prim_id && ctx->stage.hw != HWStage::NGG) {
|
|
||||||
ctx->outputs.mask[VARYING_SLOT_PRIMITIVE_ID] |= 0x1;
|
|
||||||
if (ctx->stage.has(SWStage::TES))
|
|
||||||
ctx->outputs.temps[VARYING_SLOT_PRIMITIVE_ID * 4u] =
|
|
||||||
get_arg(ctx, ctx->args->ac.tes_patch_id);
|
|
||||||
else
|
|
||||||
ctx->outputs.temps[VARYING_SLOT_PRIMITIVE_ID * 4u] =
|
|
||||||
get_arg(ctx, ctx->args->ac.vs_prim_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Hardware requires position data to always be exported, even if the
|
/* Hardware requires position data to always be exported, even if the
|
||||||
* application did not write gl_Position.
|
* application did not write gl_Position.
|
||||||
*/
|
*/
|
||||||
|
@@ -3684,6 +3684,8 @@ static void visit_intrinsic(struct ac_nir_context *ctx, nir_intrinsic_instr *ins
|
|||||||
} else if (ctx->stage == MESA_SHADER_TESS_EVAL) {
|
} else if (ctx->stage == MESA_SHADER_TESS_EVAL) {
|
||||||
result = ctx->tes_patch_id_replaced ? ctx->tes_patch_id_replaced
|
result = ctx->tes_patch_id_replaced ? ctx->tes_patch_id_replaced
|
||||||
: ac_get_arg(&ctx->ac, ctx->args->tes_patch_id);
|
: ac_get_arg(&ctx->ac, ctx->args->tes_patch_id);
|
||||||
|
} else if (ctx->stage == MESA_SHADER_VERTEX) {
|
||||||
|
result = ac_get_arg(&ctx->ac, ctx->args->vs_prim_id);
|
||||||
} else
|
} else
|
||||||
fprintf(stderr, "Unknown primitive id intrinsic: %d", ctx->stage);
|
fprintf(stderr, "Unknown primitive id intrinsic: %d", ctx->stage);
|
||||||
break;
|
break;
|
||||||
|
@@ -1046,7 +1046,7 @@ handle_vs_outputs_post(struct radv_shader_context *ctx, bool export_prim_id, boo
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate a temporary array for the output values. */
|
/* Allocate a temporary array for the output values. */
|
||||||
unsigned num_outputs = util_bitcount64(ctx->output_mask) + export_prim_id;
|
unsigned num_outputs = util_bitcount64(ctx->output_mask);
|
||||||
outputs = malloc(num_outputs * sizeof(outputs[0]));
|
outputs = malloc(num_outputs * sizeof(outputs[0]));
|
||||||
|
|
||||||
for (unsigned i = 0; i < AC_LLVM_MAX_OUTPUTS; ++i) {
|
for (unsigned i = 0; i < AC_LLVM_MAX_OUTPUTS; ++i) {
|
||||||
@@ -1072,20 +1072,6 @@ handle_vs_outputs_post(struct radv_shader_context *ctx, bool export_prim_id, boo
|
|||||||
noutput++;
|
noutput++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Export PrimitiveID. */
|
|
||||||
if (export_prim_id) {
|
|
||||||
outputs[noutput].slot_name = VARYING_SLOT_PRIMITIVE_ID;
|
|
||||||
outputs[noutput].slot_index = 0;
|
|
||||||
outputs[noutput].usage_mask = 0x1;
|
|
||||||
if (ctx->stage == MESA_SHADER_TESS_EVAL)
|
|
||||||
outputs[noutput].values[0] = ac_get_arg(&ctx->ac, ctx->args->ac.tes_patch_id);
|
|
||||||
else
|
|
||||||
outputs[noutput].values[0] = ac_get_arg(&ctx->ac, ctx->args->ac.vs_prim_id);
|
|
||||||
for (unsigned j = 1; j < 4; j++)
|
|
||||||
outputs[noutput].values[j] = ctx->ac.f32_0;
|
|
||||||
noutput++;
|
|
||||||
}
|
|
||||||
|
|
||||||
radv_llvm_export_vs(ctx, outputs, noutput, outinfo, export_clip_dists);
|
radv_llvm_export_vs(ctx, outputs, noutput, outinfo, export_clip_dists);
|
||||||
|
|
||||||
free(outputs);
|
free(outputs);
|
||||||
|
@@ -2769,6 +2769,29 @@ radv_lower_multiview(nir_shader *nir)
|
|||||||
return progress;
|
return progress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
radv_export_implicit_primitive_id(nir_shader *nir)
|
||||||
|
{
|
||||||
|
nir_function_impl *impl = nir_shader_get_entrypoint(nir);
|
||||||
|
nir_builder b;
|
||||||
|
nir_builder_init(&b, impl);
|
||||||
|
|
||||||
|
b.cursor = nir_after_cf_list(&impl->body);
|
||||||
|
|
||||||
|
nir_variable *var = nir_variable_create(nir, nir_var_shader_out, glsl_int_type(), NULL);
|
||||||
|
var->data.location = VARYING_SLOT_PRIMITIVE_ID;
|
||||||
|
var->data.interpolation = INTERP_MODE_NONE;
|
||||||
|
|
||||||
|
nir_store_var(&b, var, nir_load_primitive_id(&b), 1);
|
||||||
|
|
||||||
|
/* Update outputs_written to reflect that the pass added a new output. */
|
||||||
|
nir->info.outputs_written |= BITFIELD64_BIT(VARYING_SLOT_PRIMITIVE_ID);
|
||||||
|
|
||||||
|
nir_metadata_preserve(impl, nir_metadata_block_index | nir_metadata_dominance);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
radv_link_shaders(struct radv_pipeline *pipeline,
|
radv_link_shaders(struct radv_pipeline *pipeline,
|
||||||
const struct radv_pipeline_key *pipeline_key,
|
const struct radv_pipeline_key *pipeline_key,
|
||||||
@@ -2876,6 +2899,19 @@ radv_link_shaders(struct radv_pipeline *pipeline,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Export the primitive ID when VS or TES don't export it because it's implicit, while it's
|
||||||
|
* required for GS or MS. The primitive ID is added during lowering for NGG.
|
||||||
|
*/
|
||||||
|
if (stages[MESA_SHADER_FRAGMENT].nir &&
|
||||||
|
(stages[MESA_SHADER_FRAGMENT].nir->info.inputs_read & VARYING_BIT_PRIMITIVE_ID) &&
|
||||||
|
!(stages[pipeline->graphics.last_vgt_api_stage].nir->info.outputs_written & VARYING_BIT_PRIMITIVE_ID) &&
|
||||||
|
((pipeline->graphics.last_vgt_api_stage == MESA_SHADER_VERTEX &&
|
||||||
|
!stages[MESA_SHADER_VERTEX].info.is_ngg) ||
|
||||||
|
(pipeline->graphics.last_vgt_api_stage == MESA_SHADER_TESS_EVAL &&
|
||||||
|
!stages[MESA_SHADER_TESS_EVAL].info.is_ngg))) {
|
||||||
|
radv_export_implicit_primitive_id(stages[pipeline->graphics.last_vgt_api_stage].nir);
|
||||||
|
}
|
||||||
|
|
||||||
if (!optimize_conservatively) {
|
if (!optimize_conservatively) {
|
||||||
bool uses_xfb = pipeline->graphics.last_vgt_api_stage != -1 &&
|
bool uses_xfb = pipeline->graphics.last_vgt_api_stage != -1 &&
|
||||||
radv_nir_stage_uses_xfb(stages[pipeline->graphics.last_vgt_api_stage].nir);
|
radv_nir_stage_uses_xfb(stages[pipeline->graphics.last_vgt_api_stage].nir);
|
||||||
|
Reference in New Issue
Block a user