summaryrefslogtreecommitdiff
path: root/lib/mesa/src/amd/common/ac_nir_to_llvm.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mesa/src/amd/common/ac_nir_to_llvm.c')
-rw-r--r--lib/mesa/src/amd/common/ac_nir_to_llvm.c83
1 files changed, 61 insertions, 22 deletions
diff --git a/lib/mesa/src/amd/common/ac_nir_to_llvm.c b/lib/mesa/src/amd/common/ac_nir_to_llvm.c
index 827cb5d85..593ca7100 100644
--- a/lib/mesa/src/amd/common/ac_nir_to_llvm.c
+++ b/lib/mesa/src/amd/common/ac_nir_to_llvm.c
@@ -2072,7 +2072,7 @@ visit_store_var(struct ac_nir_context *ctx,
int writemask = instr->const_index[0];
LLVMValueRef address = get_src(ctx, instr->src[0]);
LLVMValueRef val = get_src(ctx, instr->src[1]);
- if (util_is_power_of_two_nonzero(writemask)) {
+ if (writemask == (1u << ac_get_llvm_num_components(val)) - 1) {
val = LLVMBuildBitCast(
ctx->ac.builder, val,
LLVMGetElementType(LLVMTypeOf(address)), "");
@@ -2802,15 +2802,16 @@ static LLVMValueRef visit_interp(struct ac_nir_context *ctx,
const nir_intrinsic_instr *instr)
{
LLVMValueRef result[4];
- LLVMValueRef interp_param, attr_number;
+ LLVMValueRef interp_param;
unsigned location;
unsigned chan;
LLVMValueRef src_c0 = NULL;
LLVMValueRef src_c1 = NULL;
LLVMValueRef src0 = NULL;
- nir_variable *var = nir_deref_instr_get_variable(nir_instr_as_deref(instr->src[0].ssa->parent_instr));
- int input_index = ctx->abi->fs_input_attr_indices[var->data.location - VARYING_SLOT_VAR0];
+ nir_deref_instr *deref_instr = nir_instr_as_deref(instr->src[0].ssa->parent_instr);
+ nir_variable *var = nir_deref_instr_get_variable(deref_instr);
+ int input_base = ctx->abi->fs_input_attr_indices[var->data.location - VARYING_SLOT_VAR0];
switch (instr->intrinsic) {
case nir_intrinsic_interp_deref_at_centroid:
location = INTERP_CENTROID;
@@ -2840,7 +2841,6 @@ static LLVMValueRef visit_interp(struct ac_nir_context *ctx,
src_c1 = LLVMBuildFSub(ctx->ac.builder, src_c1, halfval, "");
}
interp_param = ctx->abi->lookup_interp_param(ctx->abi, var->data.interpolation, location);
- attr_number = LLVMConstInt(ctx->ac.i32, input_index, false);
if (location == INTERP_CENTER) {
LLVMValueRef ij_out[2];
@@ -2878,26 +2878,65 @@ static LLVMValueRef visit_interp(struct ac_nir_context *ctx,
}
+ LLVMValueRef array_idx = ctx->ac.i32_0;
+ while(deref_instr->deref_type != nir_deref_type_var) {
+ if (deref_instr->deref_type == nir_deref_type_array) {
+ unsigned array_size = glsl_get_aoa_size(deref_instr->type);
+ if (!array_size)
+ array_size = 1;
+
+ LLVMValueRef offset;
+ nir_const_value *const_value = nir_src_as_const_value(deref_instr->arr.index);
+ if (const_value) {
+ offset = LLVMConstInt(ctx->ac.i32, array_size * const_value->u32[0], false);
+ } else {
+ LLVMValueRef indirect = get_src(ctx, deref_instr->arr.index);
+
+ offset = LLVMBuildMul(ctx->ac.builder, indirect,
+ LLVMConstInt(ctx->ac.i32, array_size, false), "");
+ }
+
+ array_idx = LLVMBuildAdd(ctx->ac.builder, array_idx, offset, "");
+ deref_instr = nir_src_as_deref(deref_instr->parent);
+ } else {
+ unreachable("Unsupported deref type");
+ }
+
+ }
+
+ unsigned input_array_size = glsl_get_aoa_size(var->type);
+ if (!input_array_size)
+ input_array_size = 1;
+
for (chan = 0; chan < 4; chan++) {
+ LLVMValueRef gather = LLVMGetUndef(LLVMVectorType(ctx->ac.f32, input_array_size));
LLVMValueRef llvm_chan = LLVMConstInt(ctx->ac.i32, chan, false);
- if (interp_param) {
- interp_param = LLVMBuildBitCast(ctx->ac.builder,
+ for (unsigned idx = 0; idx < input_array_size; ++idx) {
+ LLVMValueRef v, attr_number;
+
+ attr_number = LLVMConstInt(ctx->ac.i32, input_base + idx, false);
+ if (interp_param) {
+ interp_param = LLVMBuildBitCast(ctx->ac.builder,
interp_param, ctx->ac.v2f32, "");
- LLVMValueRef i = LLVMBuildExtractElement(
- ctx->ac.builder, interp_param, ctx->ac.i32_0, "");
- LLVMValueRef j = LLVMBuildExtractElement(
- ctx->ac.builder, interp_param, ctx->ac.i32_1, "");
-
- result[chan] = ac_build_fs_interp(&ctx->ac,
- llvm_chan, attr_number,
- ctx->abi->prim_mask, i, j);
- } else {
- result[chan] = ac_build_fs_interp_mov(&ctx->ac,
- LLVMConstInt(ctx->ac.i32, 2, false),
- llvm_chan, attr_number,
- ctx->abi->prim_mask);
+ LLVMValueRef i = LLVMBuildExtractElement(
+ ctx->ac.builder, interp_param, ctx->ac.i32_0, "");
+ LLVMValueRef j = LLVMBuildExtractElement(
+ ctx->ac.builder, interp_param, ctx->ac.i32_1, "");
+
+ v = ac_build_fs_interp(&ctx->ac, llvm_chan, attr_number,
+ ctx->abi->prim_mask, i, j);
+ } else {
+ v = ac_build_fs_interp_mov(&ctx->ac, LLVMConstInt(ctx->ac.i32, 2, false),
+ llvm_chan, attr_number, ctx->abi->prim_mask);
+ }
+
+ gather = LLVMBuildInsertElement(ctx->ac.builder, gather, v,
+ LLVMConstInt(ctx->ac.i32, idx, false), "");
}
+
+ result[chan] = LLVMBuildExtractElement(ctx->ac.builder, gather, array_idx, "");
+
}
return ac_build_varying_gather_values(&ctx->ac, result, instr->num_components,
var->data.location_frac);
@@ -3460,7 +3499,7 @@ static void visit_tex(struct ac_nir_context *ctx, nir_tex_instr *instr)
* It's unnecessary if the original texture format was
* Z32_FLOAT, but we don't know that here.
*/
- if (args.compare && ctx->ac.chip_class == VI && ctx->abi->clamp_shadow_reference)
+ if (args.compare && ctx->ac.chip_class >= VI && ctx->abi->clamp_shadow_reference)
args.compare = ac_build_clamp(&ctx->ac, ac_to_float(&ctx->ac, args.compare));
/* pack derivatives */
@@ -3851,7 +3890,7 @@ ac_handle_shader_output_decl(struct ac_llvm_context *ctx,
}
}
- bool is_16bit = glsl_type_is_16bit(variable->type);
+ bool is_16bit = glsl_type_is_16bit(glsl_without_array(variable->type));
LLVMTypeRef type = is_16bit ? ctx->f16 : ctx->f32;
for (unsigned i = 0; i < attrib_count; ++i) {
for (unsigned chan = 0; chan < 4; chan++) {