if (ctx->screen->b.chip_class >= GFX9) {
if (target == TGSI_TEXTURE_1D) {
coords[1] = ctx->i32_0;
num_coords++;
} else if (target == TGSI_TEXTURE_1D_ARRAY) {
coords[2] = coords[1];
coords[1] = ctx->i32_0;
num_coords++;
+ } else if (target == TGSI_TEXTURE_2D) {
+ /* The hw can't bind a slice of a 3D image as a 2D
+ * image, because it ignores BASE_ARRAY if the target
+ * is 3D. The workaround is to read BASE_ARRAY and set
+ * it as the 3rd address operand for all 2D images.
+ */
+ LLVMValueRef first_layer, const5, mask;
+
+ const5 = LLVMConstInt(ctx->i32, 5, 0);
+ mask = LLVMConstInt(ctx->i32, S_008F24_BASE_ARRAY(~0),
0);
+ first_layer = LLVMBuildExtractElement(builder, desc, const5,
"");
+ first_layer = LLVMBuildAnd(builder, first_layer, mask,
"");
+
+ coords[2] = first_layer;
+ num_coords++;
}
}
if (num_coords == 1)
return coords[0];
if (num_coords == 3) {
/* LLVM has difficulties lowering 3-element vectors. */
coords[3] = bld_base->uint_bld.undef;
num_coords = 4;
@@ -3533,21 +3548,21 @@ static void load_fetch_args(
tmp = lp_build_emit_fetch(bld_base, inst, 1, 0);
offset = LLVMBuildBitCast(builder, tmp, ctx->i32, "");
buffer_append_args(ctx, emit_data, rsrc, ctx->i32_0,
offset, false, false);
} else if (inst->Src[0].Register.File == TGSI_FILE_IMAGE) {
LLVMValueRef coords;
image_fetch_rsrc(bld_base, &inst->Src[0], false, target, &rsrc);
- coords = image_fetch_coords(bld_base, inst, 1);
+ coords = image_fetch_coords(bld_base, inst, 1, rsrc);
if (target == TGSI_TEXTURE_BUFFER) {
buffer_append_args(ctx, emit_data, rsrc, coords,
ctx->i32_0, false, false);
} else {
emit_data->args[0] = coords;
emit_data->args[1] = rsrc;
emit_data->args[2] = LLVMConstInt(ctx->i32, 15, 0); /*
dmask */
emit_data->arg_count = 3;
@@ -3808,30 +3823,29 @@ static void store_fetch_args(
LLVMValueRef coords;
/* 8bit/16bit TC L1 write corruption bug on SI.
* All store opcodes not aligned to a dword are affected.
*
* The only way to get unaligned stores in radeonsi is through
* shader images.
*/
bool force_glc = ctx->screen->b.chip_class == SI;
- coords = image_fetch_coords(bld_base, inst, 0);
+ image_fetch_rsrc(bld_base, &memory, true, target, &rsrc);
+ coords = image_fetch_coords(bld_base, inst, 0, rsrc);
if (target == TGSI_TEXTURE_BUFFER) {
- image_fetch_rsrc(bld_base, &memory, true, target,
&rsrc);
buffer_append_args(ctx, emit_data, rsrc, coords,
ctx->i32_0, false, force_glc);
} else {
emit_data->args[1] = coords;
- image_fetch_rsrc(bld_base, &memory, true, target,
- &emit_data->args[2]);
+ emit_data->args[2] = rsrc;
emit_data->args[3] = LLVMConstInt(ctx->i32, 15, 0); /*
dmask */
emit_data->arg_count = 4;
image_append_args(ctx, emit_data, target, false,
force_glc);
}
}
}
static void store_emit_buffer(
struct si_shader_context *ctx,
@@ -4021,21 +4035,21 @@ static void atomic_fetch_args(
tmp = lp_build_emit_fetch(bld_base, inst, 1, 0);
offset = LLVMBuildBitCast(builder, tmp, ctx->i32, "");
buffer_append_args(ctx, emit_data, rsrc, ctx->i32_0,
offset, true, false);
} else if (inst->Src[0].Register.File == TGSI_FILE_IMAGE) {
unsigned target = inst->Memory.Texture;
LLVMValueRef coords;
image_fetch_rsrc(bld_base, &inst->Src[0], true, target, &rsrc);
- coords = image_fetch_coords(bld_base, inst, 1);
+ coords = image_fetch_coords(bld_base, inst, 1, rsrc);
if (target == TGSI_TEXTURE_BUFFER) {
buffer_append_args(ctx, emit_data, rsrc, coords,
ctx->i32_0, true, false);
} else {
emit_data->args[emit_data->arg_count++] = coords;
emit_data->args[emit_data->arg_count++] = rsrc;
image_append_args(ctx, emit_data, target, true, false);
}