mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-28 19:00:13 +01:00
amd: lower load_barycentric_pixel/centroid/sample in NIR
radeonsi needs to preserve interp_mode in the arg load. Reviewed-by: Timur Kristóf <timur.kristof@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32782>
This commit is contained in:
parent
a15e733a81
commit
16ab05fad1
6 changed files with 40 additions and 112 deletions
|
|
@ -275,6 +275,36 @@ lower_intrinsic_to_arg(nir_builder *b, nir_instr *instr, void *state)
|
|||
case nir_intrinsic_load_front_face_fsign:
|
||||
replacement = ac_nir_load_arg(b, s->args, s->args->front_face);
|
||||
break;
|
||||
case nir_intrinsic_load_barycentric_pixel:
|
||||
if (nir_intrinsic_interp_mode(intrin) == INTERP_MODE_NOPERSPECTIVE)
|
||||
replacement = ac_nir_load_arg(b, s->args, s->args->linear_center);
|
||||
else
|
||||
replacement = ac_nir_load_arg(b, s->args, s->args->persp_center);
|
||||
nir_intrinsic_set_flags(nir_instr_as_intrinsic(replacement->parent_instr),
|
||||
AC_VECTOR_ARG_FLAG(AC_VECTOR_ARG_INTERP_MODE,
|
||||
nir_intrinsic_interp_mode(intrin)));
|
||||
break;
|
||||
case nir_intrinsic_load_barycentric_centroid:
|
||||
if (nir_intrinsic_interp_mode(intrin) == INTERP_MODE_NOPERSPECTIVE)
|
||||
replacement = ac_nir_load_arg(b, s->args, s->args->linear_centroid);
|
||||
else
|
||||
replacement = ac_nir_load_arg(b, s->args, s->args->persp_centroid);
|
||||
nir_intrinsic_set_flags(nir_instr_as_intrinsic(replacement->parent_instr),
|
||||
AC_VECTOR_ARG_FLAG(AC_VECTOR_ARG_INTERP_MODE,
|
||||
nir_intrinsic_interp_mode(intrin)));
|
||||
break;
|
||||
case nir_intrinsic_load_barycentric_sample:
|
||||
if (nir_intrinsic_interp_mode(intrin) == INTERP_MODE_NOPERSPECTIVE)
|
||||
replacement = ac_nir_load_arg(b, s->args, s->args->linear_sample);
|
||||
else
|
||||
replacement = ac_nir_load_arg(b, s->args, s->args->persp_sample);
|
||||
nir_intrinsic_set_flags(nir_instr_as_intrinsic(replacement->parent_instr),
|
||||
AC_VECTOR_ARG_FLAG(AC_VECTOR_ARG_INTERP_MODE,
|
||||
nir_intrinsic_interp_mode(intrin)));
|
||||
break;
|
||||
case nir_intrinsic_load_barycentric_model:
|
||||
replacement = ac_nir_load_arg(b, s->args, s->args->pull_model);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7945,21 +7945,6 @@ Temp merged_wave_info_to_mask(isel_context* ctx, unsigned i);
|
|||
Temp lanecount_to_mask(isel_context* ctx, Temp count, unsigned bit_offset);
|
||||
void pops_await_overlapped_waves(isel_context* ctx);
|
||||
|
||||
Temp
|
||||
get_interp_param(isel_context* ctx, nir_intrinsic_op intrin, enum glsl_interp_mode interp)
|
||||
{
|
||||
bool linear = interp == INTERP_MODE_NOPERSPECTIVE;
|
||||
if (intrin == nir_intrinsic_load_barycentric_pixel ||
|
||||
intrin == nir_intrinsic_load_barycentric_at_offset) {
|
||||
return get_arg(ctx, linear ? ctx->args->linear_center : ctx->args->persp_center);
|
||||
} else if (intrin == nir_intrinsic_load_barycentric_centroid) {
|
||||
return get_arg(ctx, linear ? ctx->args->linear_centroid : ctx->args->persp_centroid);
|
||||
} else {
|
||||
assert(intrin == nir_intrinsic_load_barycentric_sample);
|
||||
return get_arg(ctx, linear ? ctx->args->linear_sample : ctx->args->persp_sample);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ds_ordered_count_offsets(isel_context* ctx, unsigned index_operand, unsigned wave_release,
|
||||
unsigned wave_done, unsigned* offset0, unsigned* offset1)
|
||||
|
|
@ -8057,32 +8042,14 @@ visit_intrinsic(isel_context* ctx, nir_intrinsic_instr* instr)
|
|||
{
|
||||
Builder bld(ctx->program, ctx->block);
|
||||
switch (instr->intrinsic) {
|
||||
case nir_intrinsic_load_barycentric_sample:
|
||||
case nir_intrinsic_load_barycentric_pixel:
|
||||
case nir_intrinsic_load_barycentric_centroid: {
|
||||
glsl_interp_mode mode = (glsl_interp_mode)nir_intrinsic_interp_mode(instr);
|
||||
Temp bary = get_interp_param(ctx, instr->intrinsic, mode);
|
||||
assert(bary.size() == 2);
|
||||
Temp dst = get_ssa_temp(ctx, &instr->def);
|
||||
bld.copy(Definition(dst), bary);
|
||||
emit_split_vector(ctx, dst, 2);
|
||||
break;
|
||||
}
|
||||
case nir_intrinsic_load_barycentric_model: {
|
||||
Temp model = get_arg(ctx, ctx->args->pull_model);
|
||||
assert(model.size() == 3);
|
||||
Temp dst = get_ssa_temp(ctx, &instr->def);
|
||||
bld.copy(Definition(dst), model);
|
||||
emit_split_vector(ctx, dst, 3);
|
||||
break;
|
||||
}
|
||||
case nir_intrinsic_load_barycentric_at_offset: {
|
||||
Temp offset = get_ssa_temp(ctx, instr->src[0].ssa);
|
||||
RegClass rc = RegClass(offset.type(), 1);
|
||||
Temp pos1 = bld.tmp(rc), pos2 = bld.tmp(rc);
|
||||
bld.pseudo(aco_opcode::p_split_vector, Definition(pos1), Definition(pos2), offset);
|
||||
Temp bary = get_interp_param(ctx, instr->intrinsic,
|
||||
(glsl_interp_mode)nir_intrinsic_interp_mode(instr));
|
||||
Temp bary = get_arg(ctx, nir_intrinsic_interp_mode(instr) == INTERP_MODE_NOPERSPECTIVE
|
||||
? ctx->args->linear_center
|
||||
: ctx->args->persp_center);
|
||||
emit_interp_center(ctx, get_ssa_temp(ctx, &instr->def), bary, pos1, pos2);
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -550,10 +550,6 @@ init_context(isel_context* ctx, nir_shader* shader)
|
|||
case nir_intrinsic_load_per_vertex_input:
|
||||
case nir_intrinsic_load_per_vertex_output:
|
||||
case nir_intrinsic_load_vertex_id_zero_base:
|
||||
case nir_intrinsic_load_barycentric_sample:
|
||||
case nir_intrinsic_load_barycentric_pixel:
|
||||
case nir_intrinsic_load_barycentric_model:
|
||||
case nir_intrinsic_load_barycentric_centroid:
|
||||
case nir_intrinsic_load_barycentric_at_offset:
|
||||
case nir_intrinsic_load_interpolated_input:
|
||||
case nir_intrinsic_load_local_invocation_index:
|
||||
|
|
|
|||
|
|
@ -2657,44 +2657,12 @@ static LLVMValueRef visit_var_atomic(struct ac_nir_context *ctx, const nir_intri
|
|||
return result;
|
||||
}
|
||||
|
||||
static LLVMValueRef lookup_interp_param(struct ac_nir_context *ctx, enum glsl_interp_mode interp,
|
||||
unsigned location)
|
||||
{
|
||||
switch (interp) {
|
||||
case INTERP_MODE_FLAT:
|
||||
default:
|
||||
return NULL;
|
||||
case INTERP_MODE_SMOOTH:
|
||||
case INTERP_MODE_NONE:
|
||||
if (location == INTERP_CENTER)
|
||||
return ac_get_arg(&ctx->ac, ctx->args->persp_center);
|
||||
else if (location == INTERP_CENTROID)
|
||||
return ac_get_arg(&ctx->ac, ctx->args->persp_centroid);
|
||||
else if (location == INTERP_SAMPLE)
|
||||
return ac_get_arg(&ctx->ac, ctx->args->persp_sample);
|
||||
break;
|
||||
case INTERP_MODE_NOPERSPECTIVE:
|
||||
if (location == INTERP_CENTER)
|
||||
return ac_get_arg(&ctx->ac, ctx->args->linear_center);
|
||||
else if (location == INTERP_CENTROID)
|
||||
return ac_get_arg(&ctx->ac, ctx->args->linear_centroid);
|
||||
else if (location == INTERP_SAMPLE)
|
||||
return ac_get_arg(&ctx->ac, ctx->args->linear_sample);
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static LLVMValueRef barycentric_center(struct ac_nir_context *ctx, unsigned mode)
|
||||
{
|
||||
LLVMValueRef interp_param = lookup_interp_param(ctx, mode, INTERP_CENTER);
|
||||
return LLVMBuildBitCast(ctx->ac.builder, interp_param, ctx->ac.v2i32, "");
|
||||
}
|
||||
|
||||
static LLVMValueRef barycentric_offset(struct ac_nir_context *ctx, unsigned mode,
|
||||
LLVMValueRef offset)
|
||||
{
|
||||
LLVMValueRef interp_param = lookup_interp_param(ctx, mode, INTERP_CENTER);
|
||||
LLVMValueRef interp_param = mode == INTERP_MODE_NOPERSPECTIVE ?
|
||||
ac_get_arg(&ctx->ac, ctx->args->linear_center) :
|
||||
ac_get_arg(&ctx->ac, ctx->args->persp_center);
|
||||
LLVMValueRef src_c0 =
|
||||
ac_to_float(&ctx->ac, LLVMBuildExtractElement(ctx->ac.builder, offset, ctx->ac.i32_0, ""));
|
||||
LLVMValueRef src_c1 =
|
||||
|
|
@ -2730,24 +2698,6 @@ static LLVMValueRef barycentric_offset(struct ac_nir_context *ctx, unsigned mode
|
|||
return LLVMBuildBitCast(ctx->ac.builder, interp_param, ctx->ac.v2i32, "");
|
||||
}
|
||||
|
||||
static LLVMValueRef barycentric_centroid(struct ac_nir_context *ctx, unsigned mode)
|
||||
{
|
||||
LLVMValueRef interp_param = lookup_interp_param(ctx, mode, INTERP_CENTROID);
|
||||
return LLVMBuildBitCast(ctx->ac.builder, interp_param, ctx->ac.v2i32, "");
|
||||
}
|
||||
|
||||
static LLVMValueRef barycentric_sample(struct ac_nir_context *ctx, unsigned mode)
|
||||
{
|
||||
LLVMValueRef interp_param = lookup_interp_param(ctx, mode, INTERP_SAMPLE);
|
||||
return LLVMBuildBitCast(ctx->ac.builder, interp_param, ctx->ac.v2i32, "");
|
||||
}
|
||||
|
||||
static LLVMValueRef barycentric_model(struct ac_nir_context *ctx)
|
||||
{
|
||||
return LLVMBuildBitCast(ctx->ac.builder, ac_get_arg(&ctx->ac, ctx->args->pull_model),
|
||||
ctx->ac.v3i32, "");
|
||||
}
|
||||
|
||||
static LLVMValueRef load_interpolated_input(struct ac_nir_context *ctx, LLVMValueRef interp_param,
|
||||
unsigned index, unsigned comp_start,
|
||||
unsigned num_components, unsigned bitsize,
|
||||
|
|
@ -3060,18 +3010,6 @@ static bool visit_intrinsic(struct ac_nir_context *ctx, nir_intrinsic_instr *ins
|
|||
result = visit_var_atomic(ctx, instr, ptr, 1);
|
||||
break;
|
||||
}
|
||||
case nir_intrinsic_load_barycentric_pixel:
|
||||
result = barycentric_center(ctx, nir_intrinsic_interp_mode(instr));
|
||||
break;
|
||||
case nir_intrinsic_load_barycentric_centroid:
|
||||
result = barycentric_centroid(ctx, nir_intrinsic_interp_mode(instr));
|
||||
break;
|
||||
case nir_intrinsic_load_barycentric_sample:
|
||||
result = barycentric_sample(ctx, nir_intrinsic_interp_mode(instr));
|
||||
break;
|
||||
case nir_intrinsic_load_barycentric_model:
|
||||
result = barycentric_model(ctx);
|
||||
break;
|
||||
case nir_intrinsic_load_barycentric_at_offset: {
|
||||
LLVMValueRef offset = ac_to_float(&ctx->ac, get_src(ctx, instr->src[0]));
|
||||
result = barycentric_offset(ctx, nir_intrinsic_interp_mode(instr), offset);
|
||||
|
|
|
|||
|
|
@ -15,16 +15,10 @@
|
|||
#include <stdbool.h>
|
||||
|
||||
struct nir_shader;
|
||||
struct nir_variable;
|
||||
struct ac_llvm_context;
|
||||
struct ac_shader_abi;
|
||||
struct ac_shader_args;
|
||||
|
||||
/* Interpolation locations */
|
||||
#define INTERP_CENTER 0
|
||||
#define INTERP_CENTROID 1
|
||||
#define INTERP_SAMPLE 2
|
||||
|
||||
static inline unsigned ac_llvm_reg_index_soa(unsigned index, unsigned chan)
|
||||
{
|
||||
return (index * 4) + chan;
|
||||
|
|
|
|||
|
|
@ -66,8 +66,11 @@ static void scan_io_usage(const nir_shader *nir, struct si_shader_info *info,
|
|||
nir_instr *src_instr = intr->src[0].ssa->parent_instr;
|
||||
if (src_instr->type == nir_instr_type_intrinsic) {
|
||||
nir_intrinsic_instr *baryc = nir_instr_as_intrinsic(src_instr);
|
||||
if (nir_intrinsic_infos[baryc->intrinsic].index_map[NIR_INTRINSIC_INTERP_MODE] > 0)
|
||||
if (nir_intrinsic_has_interp_mode(baryc))
|
||||
interp = nir_intrinsic_interp_mode(baryc);
|
||||
else if (nir_intrinsic_has_flags(baryc) &&
|
||||
AC_VECTOR_ARG_FLAG_GET_NAME(baryc) == AC_VECTOR_ARG_INTERP_MODE)
|
||||
interp = AC_VECTOR_ARG_FLAG_GET_VALUE(baryc);
|
||||
else
|
||||
unreachable("unknown barycentric intrinsic");
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue