amd/common: pass new enum ac_image_dim to ac_build_image_opcode
authorNicolai Hähnle <nicolai.haehnle@amd.com>
Fri, 16 Feb 2018 13:21:56 +0000 (14:21 +0100)
committerNicolai Hähnle <nicolai.haehnle@amd.com>
Fri, 20 Apr 2018 07:23:40 +0000 (09:23 +0200)
This is in preparation for the new, dimension-aware LLVM image
intrinsics.

Acked-by: Marek Olšák <marek.olsak@amd.com>
src/amd/common/ac_llvm_build.c
src/amd/common/ac_llvm_build.h
src/amd/common/ac_nir_to_llvm.c
src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c

index 9a00bb11140e7720588982a7c2faeaeda85a58fb..77b07989430924ba07ff8348dc1ff8c6717db258 100644 (file)
@@ -1456,6 +1456,12 @@ LLVMValueRef ac_build_image_opcode(struct ac_llvm_context *ctx,
        bool sample = a->opcode == ac_image_sample ||
                      a->opcode == ac_image_gather4 ||
                      a->opcode == ac_image_get_lod;
+       bool da = a->dim == ac_image_cube ||
+                 a->dim == ac_image_1darray ||
+                 a->dim == ac_image_2darray ||
+                 a->dim == ac_image_2darraymsaa;
+       if (a->opcode == ac_image_get_lod)
+               da = false;
 
        if (sample)
                args[num_args++] = ac_to_float(ctx, a->addr);
@@ -1471,7 +1477,7 @@ LLVMValueRef ac_build_image_opcode(struct ac_llvm_context *ctx,
        args[num_args++] = ctx->i1false; /* glc */
        args[num_args++] = ctx->i1false; /* slc */
        args[num_args++] = ctx->i1false; /* lwe */
-       args[num_args++] = LLVMConstInt(ctx->i1, a->da, 0);
+       args[num_args++] = LLVMConstInt(ctx->i1, da, 0);
 
        switch (a->opcode) {
        case ac_image_sample:
@@ -2473,7 +2479,7 @@ void ac_apply_fmask_to_sample(struct ac_llvm_context *ac, LLVMValueRef fmask,
        fmask_load.opcode = ac_image_load;
        fmask_load.resource = fmask;
        fmask_load.dmask = 0xf;
-       fmask_load.da = is_array_tex;
+       fmask_load.dim = is_array_tex ? ac_image_2darray : ac_image_2d;
 
        LLVMValueRef fmask_addr[4];
        memcpy(fmask_addr, addr, sizeof(fmask_addr[0]) * 3);
index c583240e14bd86f2f76a4fc6552b74ce99720390..328eddc9a775d54b9595764cef27195f7ad26767 100644 (file)
@@ -317,8 +317,20 @@ enum ac_image_opcode {
        ac_image_get_resinfo,
 };
 
+enum ac_image_dim {
+       ac_image_1d,
+       ac_image_2d,
+       ac_image_3d,
+       ac_image_cube, // includes cube arrays
+       ac_image_1darray,
+       ac_image_2darray,
+       ac_image_2dmsaa,
+       ac_image_2darraymsaa,
+};
+
 struct ac_image_args {
        enum ac_image_opcode opcode;
+       enum ac_image_dim dim;
        bool level_zero;
        bool bias;
        bool lod;
@@ -331,7 +343,6 @@ struct ac_image_args {
        LLVMValueRef addr;
        unsigned dmask;
        bool unorm;
-       bool da;
 };
 
 LLVMValueRef ac_build_image_opcode(struct ac_llvm_context *ctx,
index 6b519f78e0f25dd04fc9099330e21fd381c3bef9..de3754d72beef336c7099a7e550df0ff1c48e6a4 100644 (file)
@@ -76,6 +76,45 @@ build_store_values_extended(struct ac_llvm_context *ac,
        }
 }
 
+static enum ac_image_dim
+get_ac_sampler_dim(const struct ac_llvm_context *ctx, enum glsl_sampler_dim dim,
+                  bool is_array)
+{
+       switch (dim) {
+       case GLSL_SAMPLER_DIM_1D:
+               if (ctx->chip_class >= GFX9)
+                       return is_array ? ac_image_2darray : ac_image_2d;
+               return is_array ? ac_image_1darray : ac_image_1d;
+       case GLSL_SAMPLER_DIM_2D:
+       case GLSL_SAMPLER_DIM_RECT:
+       case GLSL_SAMPLER_DIM_SUBPASS:
+       case GLSL_SAMPLER_DIM_EXTERNAL:
+               return is_array ? ac_image_2darray : ac_image_2d;
+       case GLSL_SAMPLER_DIM_3D:
+               return ac_image_3d;
+       case GLSL_SAMPLER_DIM_CUBE:
+               return ac_image_cube;
+       case GLSL_SAMPLER_DIM_MS:
+       case GLSL_SAMPLER_DIM_SUBPASS_MS:
+               return is_array ? ac_image_2darraymsaa : ac_image_2dmsaa;
+       default:
+               unreachable("bad sampler dim");
+       }
+}
+
+static enum ac_image_dim
+get_ac_image_dim(const struct ac_llvm_context *ctx, enum glsl_sampler_dim sdim,
+                bool is_array)
+{
+       enum ac_image_dim dim = get_ac_sampler_dim(ctx, sdim, is_array);
+
+       if (dim == ac_image_cube ||
+           (ctx->chip_class <= VI && dim == ac_image_3d))
+               dim = ac_image_2darray;
+
+       return dim;
+}
+
 static LLVMTypeRef get_def_type(struct ac_nir_context *ctx,
                                 const nir_ssa_def *def)
 {
@@ -1124,7 +1163,7 @@ static LLVMValueRef lower_gather4_integer(struct ac_llvm_context *ctx,
        {
                struct ac_image_args txq_args = { 0 };
 
-               txq_args.da = instr->is_array || instr->sampler_dim == GLSL_SAMPLER_DIM_CUBE;
+               txq_args.dim = get_ac_sampler_dim(ctx, instr->sampler_dim, instr->is_array);
                txq_args.opcode = ac_image_get_resinfo;
                txq_args.dmask = 0xf;
                txq_args.addr = ctx->i32_0;
@@ -2055,7 +2094,7 @@ static LLVMValueRef adjust_sample_index_using_fmask(struct ac_llvm_context *ctx,
        struct ac_image_args args = {0};
 
        args.opcode = ac_image_load;
-       args.da = coord_z ? true : false;
+       args.dim = coord_z ? ac_image_2darray : ac_image_2d;
        args.resource = fmask_desc_ptr;
        args.dmask = 0xf;
        args.addr = ac_build_gather_values(ctx, fmask_load_address, coord_z ? 4 : 2);
@@ -2402,7 +2441,8 @@ static LLVMValueRef visit_image_samples(struct ac_nir_context *ctx,
        const struct glsl_type *type = glsl_without_array(var->type);
 
        struct ac_image_args args = { 0 };
-       args.da = glsl_is_array_image(type);
+       args.dim = get_ac_sampler_dim(&ctx->ac, glsl_get_sampler_dim(type),
+                                     glsl_sampler_type_is_array(type));
        args.dmask = 0xf;
        args.resource = get_sampler_desc(ctx, instr->variables[0],
                                         AC_DESC_IMAGE, NULL, true, false);
@@ -2426,7 +2466,8 @@ static LLVMValueRef visit_image_size(struct ac_nir_context *ctx,
 
        struct ac_image_args args = { 0 };
 
-       args.da = glsl_is_array_image(type);
+       args.dim = get_ac_image_dim(&ctx->ac, glsl_get_sampler_dim(type),
+                                   glsl_sampler_type_is_array(type));
        args.dmask = 0xf;
        args.resource = get_sampler_desc(ctx, instr->variables[0], AC_DESC_IMAGE, NULL, true, false);
        args.opcode = ac_image_get_resinfo;
@@ -3185,10 +3226,7 @@ static void set_tex_fetch_args(struct ac_llvm_context *ctx,
                               unsigned dmask)
 {
        unsigned is_rect = 0;
-       bool da = instr->is_array || instr->sampler_dim == GLSL_SAMPLER_DIM_CUBE;
 
-       if (op == nir_texop_lod)
-               da = false;
        /* Pad to power of two vector */
        while (count < util_next_power_of_two(count))
                param[count++] = LLVMGetUndef(ctx->i32);
@@ -3208,7 +3246,7 @@ static void set_tex_fetch_args(struct ac_llvm_context *ctx,
 
        args->dmask = dmask;
        args->unorm = is_rect;
-       args->da = da;
+       args->dim = get_ac_sampler_dim(&ctx->ac, instr->sampler_dim, instr->is_array);
 }
 
 /* Disable anisotropic filtering if BASE_LEVEL == LAST_LEVEL.
index 6a307c4ddba99f8c0a7483f68893a7427a8d9a00..a54db9e8596f5f0b0f0f66e620fc4e8a7509b2ed 100644 (file)
@@ -101,6 +101,44 @@ static bool tgsi_is_array_image(unsigned target)
               target == TGSI_TEXTURE_2D_ARRAY_MSAA;
 }
 
+static enum ac_image_dim
+ac_texture_dim_from_tgsi_target(struct si_screen *screen, enum tgsi_texture_type target)
+{
+       switch (target) {
+       case TGSI_TEXTURE_1D:
+       case TGSI_TEXTURE_SHADOW1D:
+               if (screen->info.chip_class >= GFX9)
+                       return ac_image_2d;
+               return ac_image_1d;
+       case TGSI_TEXTURE_2D:
+       case TGSI_TEXTURE_SHADOW2D:
+       case TGSI_TEXTURE_RECT:
+       case TGSI_TEXTURE_SHADOWRECT:
+               return ac_image_2d;
+       case TGSI_TEXTURE_3D:
+               return ac_image_3d;
+       case TGSI_TEXTURE_CUBE:
+       case TGSI_TEXTURE_SHADOWCUBE:
+       case TGSI_TEXTURE_CUBE_ARRAY:
+       case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
+               return ac_image_cube;
+       case TGSI_TEXTURE_1D_ARRAY:
+       case TGSI_TEXTURE_SHADOW1D_ARRAY:
+               if (screen->info.chip_class >= GFX9)
+                       return ac_image_2darray;
+               return ac_image_1darray;
+       case TGSI_TEXTURE_2D_ARRAY:
+       case TGSI_TEXTURE_SHADOW2D_ARRAY:
+               return ac_image_2darray;
+       case TGSI_TEXTURE_2D_MSAA:
+               return ac_image_2dmsaa;
+       case TGSI_TEXTURE_2D_ARRAY_MSAA:
+               return ac_image_2darraymsaa;
+       default:
+               unreachable("unhandled texture type");
+       }
+}
+
 /**
  * Given a 256-bit resource descriptor, force the DCC enable bit to off.
  *
@@ -986,12 +1024,12 @@ static void set_tex_fetch_args(struct si_shader_context *ctx,
        else
                args.addr = param[0];
 
+       args.dim = ac_texture_dim_from_tgsi_target(ctx->screen, target);
        args.resource = res_ptr;
        args.sampler = samp_ptr;
        args.dmask = dmask;
        args.unorm = target == TGSI_TEXTURE_RECT ||
                     target == TGSI_TEXTURE_SHADOWRECT;
-       args.da = tgsi_is_array_sampler(target);
 
        /* Ugly, but we seem to have no other choice right now. */
        STATIC_ASSERT(sizeof(args) <= sizeof(emit_data->args));
@@ -1925,7 +1963,15 @@ static void si_llvm_emit_fbfetch(const struct lp_build_tgsi_action *action,
        args.resource = image;
        args.addr = addr_vec;
        args.dmask = 0xf;
-       args.da = ctx->shader->key.mono.u.ps.fbfetch_layered;
+       if (ctx->shader->key.mono.u.ps.fbfetch_msaa)
+               args.dim = ctx->shader->key.mono.u.ps.fbfetch_layered ?
+                       ac_image_2darraymsaa : ac_image_2dmsaa;
+       else if (ctx->shader->key.mono.u.ps.fbfetch_is_1D)
+               args.dim = ctx->shader->key.mono.u.ps.fbfetch_layered ?
+                       ac_image_1darray : ac_image_1d;
+       else
+               args.dim = ctx->shader->key.mono.u.ps.fbfetch_layered ?
+                       ac_image_2darray : ac_image_2d;
 
        emit_data->output[emit_data->chan] =
                ac_build_image_opcode(&ctx->ac, &args);