mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-04-22 05:20:37 +02:00
radv/llvm: implement a workaround for gl_FragCoord.z with VRS on GFX10.3
Without it, FragCoord.z will have the value of one of the fine pixels instead of the center of the coarse pixel. It's only enabled for RADV. Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7837>
This commit is contained in:
parent
7a464f4296
commit
45524afe95
4 changed files with 40 additions and 7 deletions
|
|
@ -3328,6 +3328,37 @@ emit_load_frag_shading_rate(struct ac_nir_context *ctx)
|
|||
return LLVMBuildOr(ctx->ac.builder, x_rate, y_rate, "");
|
||||
}
|
||||
|
||||
static LLVMValueRef
|
||||
emit_load_frag_coord(struct ac_nir_context *ctx)
|
||||
{
|
||||
LLVMValueRef values[4] = {
|
||||
ac_get_arg(&ctx->ac, ctx->args->frag_pos[0]), ac_get_arg(&ctx->ac, ctx->args->frag_pos[1]),
|
||||
ac_get_arg(&ctx->ac, ctx->args->frag_pos[2]),
|
||||
ac_build_fdiv(&ctx->ac, ctx->ac.f32_1, ac_get_arg(&ctx->ac, ctx->args->frag_pos[3]))};
|
||||
|
||||
if (ctx->abi->adjust_frag_coord_z) {
|
||||
/* Adjust gl_FragCoord.z for VRS due to a hw bug on some GFX10.3 chips. */
|
||||
LLVMValueRef frag_z = values[2];
|
||||
|
||||
/* dFdx fine */
|
||||
LLVMValueRef adjusted_frag_z = emit_ddxy(ctx, nir_op_fddx_fine, frag_z);
|
||||
|
||||
/* adjusted_frag_z * 0.0625 + frag_z */
|
||||
adjusted_frag_z = LLVMBuildFAdd(ctx->ac.builder, frag_z,
|
||||
LLVMBuildFMul(ctx->ac.builder, adjusted_frag_z,
|
||||
LLVMConstReal(ctx->ac.f32, 0.0625), ""), "");
|
||||
|
||||
/* VRS Rate X = Ancillary[2:3] */
|
||||
LLVMValueRef x_rate = ac_unpack_param(&ctx->ac, ac_get_arg(&ctx->ac, ctx->args->ancillary), 2, 2);
|
||||
|
||||
/* xRate = xRate == 0x1 ? adjusted_frag_z : frag_z. */
|
||||
LLVMValueRef cond = LLVMBuildICmp(ctx->ac.builder, LLVMIntEQ, x_rate, ctx->ac.i32_1, "");
|
||||
values[2] = LLVMBuildSelect(ctx->ac.builder, cond, adjusted_frag_z, frag_z, "");
|
||||
}
|
||||
|
||||
return ac_to_integer(&ctx->ac, ac_build_gather_values(&ctx->ac, values, 4));
|
||||
}
|
||||
|
||||
static void visit_intrinsic(struct ac_nir_context *ctx, nir_intrinsic_instr *instr)
|
||||
{
|
||||
LLVMValueRef result = NULL;
|
||||
|
|
@ -3421,14 +3452,9 @@ static void visit_intrinsic(struct ac_nir_context *ctx, nir_intrinsic_instr *ins
|
|||
case nir_intrinsic_load_sample_mask_in:
|
||||
result = ctx->abi->load_sample_mask_in(ctx->abi);
|
||||
break;
|
||||
case nir_intrinsic_load_frag_coord: {
|
||||
LLVMValueRef values[4] = {
|
||||
ac_get_arg(&ctx->ac, ctx->args->frag_pos[0]), ac_get_arg(&ctx->ac, ctx->args->frag_pos[1]),
|
||||
ac_get_arg(&ctx->ac, ctx->args->frag_pos[2]),
|
||||
ac_build_fdiv(&ctx->ac, ctx->ac.f32_1, ac_get_arg(&ctx->ac, ctx->args->frag_pos[3]))};
|
||||
result = ac_to_integer(&ctx->ac, ac_build_gather_values(&ctx->ac, values, 4));
|
||||
case nir_intrinsic_load_frag_coord:
|
||||
result = emit_load_frag_coord(ctx);
|
||||
break;
|
||||
}
|
||||
case nir_intrinsic_load_frag_shading_rate:
|
||||
result = emit_load_frag_shading_rate(ctx);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -165,6 +165,11 @@ struct ac_shader_abi {
|
|||
|
||||
/* Clamp div by 0 (so it won't produce NaN) */
|
||||
bool clamp_div_by_zero;
|
||||
|
||||
/* Whether gl_FragCoord.z should be adjusted for VRS due to a hw bug on
|
||||
* some GFX10.3 chips.
|
||||
*/
|
||||
bool adjust_frag_coord_z;
|
||||
};
|
||||
|
||||
#endif /* AC_SHADER_ABI_H */
|
||||
|
|
|
|||
|
|
@ -3896,6 +3896,7 @@ LLVMModuleRef ac_translate_nir_to_llvm(struct ac_llvm_compiler *ac_llvm,
|
|||
ctx.abi.load_sampler_desc = radv_get_sampler_desc;
|
||||
ctx.abi.load_resource = radv_load_resource;
|
||||
ctx.abi.clamp_shadow_reference = false;
|
||||
ctx.abi.adjust_frag_coord_z = args->options->adjust_frag_coord_z;
|
||||
ctx.abi.robust_buffer_access = args->options->robust_buffer_access;
|
||||
|
||||
bool is_ngg = is_pre_gs_stage(shaders[0]->info.stage) && args->options->key.vs_common_out.as_ngg;
|
||||
|
|
|
|||
|
|
@ -487,6 +487,7 @@ static bool si_nir_build_llvm(struct si_shader_context *ctx, struct nir_shader *
|
|||
ctx->abi.robust_buffer_access = true;
|
||||
ctx->abi.convert_undef_to_zero = true;
|
||||
ctx->abi.clamp_div_by_zero = ctx->screen->options.clamp_div_by_zero;
|
||||
ctx->abi.adjust_frag_coord_z = false;
|
||||
|
||||
const struct si_shader_info *info = &ctx->shader->selector->info;
|
||||
for (unsigned i = 0; i < info->num_outputs; i++) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue