From: Marek Olšák <marek.ol...@amd.com> Cc: 17.1 <mesa-sta...@lists.freedesktop.org> --- src/gallium/drivers/radeonsi/si_shader.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-)
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index c5c994d..840742c 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -3393,21 +3393,21 @@ image_fetch_rsrc( } *rsrc = load_image_desc(ctx, rsrc_ptr, index, target); if (dcc_off && target != TGSI_TEXTURE_BUFFER) *rsrc = force_dcc_off(ctx, *rsrc); } static LLVMValueRef image_fetch_coords( struct lp_build_tgsi_context *bld_base, const struct tgsi_full_instruction *inst, - unsigned src) + unsigned src, LLVMValueRef desc) { struct si_shader_context *ctx = si_shader_context(bld_base); struct gallivm_state *gallivm = &ctx->gallivm; LLVMBuilderRef builder = gallivm->builder; unsigned target = inst->Memory.Texture; unsigned num_coords = tgsi_util_get_texture_coord_dim(target); LLVMValueRef coords[4]; LLVMValueRef tmp; int chan; @@ -3419,20 +3419,35 @@ static LLVMValueRef image_fetch_coords( /* 1D textures are allocated and used as 2D on GFX9. */ 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); } -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev