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);
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:
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);
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;
LLVMValueRef addr;
unsigned dmask;
bool unorm;
- bool da;
};
LLVMValueRef ac_build_image_opcode(struct ac_llvm_context *ctx,
}
}
+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)
{
{
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;
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);
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);
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;
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);
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.
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.
*
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));
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);