From: Marek Olšák <[email protected]>

Cc: 13.0 <[email protected]>
---
 src/gallium/drivers/radeonsi/si_shader.c | 34 +++++++++++++++++++++-----------
 1 file changed, 23 insertions(+), 11 deletions(-)

diff --git a/src/gallium/drivers/radeonsi/si_shader.c 
b/src/gallium/drivers/radeonsi/si_shader.c
index 80c063a..ee2fce1 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -3375,28 +3375,30 @@ static LLVMValueRef image_fetch_coords(
        return lp_build_gather_values(gallivm, coords, num_coords);
 }
 
 /**
  * Append the extra mode bits that are used by image load and store.
  */
 static void image_append_args(
                struct si_shader_context *ctx,
                struct lp_build_emit_data * emit_data,
                unsigned target,
-               bool atomic)
+               bool atomic,
+               bool force_glc)
 {
        const struct tgsi_full_instruction *inst = emit_data->inst;
        LLVMValueRef i1false = LLVMConstInt(ctx->i1, 0, 0);
        LLVMValueRef i1true = LLVMConstInt(ctx->i1, 1, 0);
        LLVMValueRef r128 = i1false;
        LLVMValueRef da = tgsi_is_array_image(target) ? i1true : i1false;
        LLVMValueRef glc =
+               force_glc ||
                inst->Memory.Qualifier & (TGSI_MEMORY_COHERENT | 
TGSI_MEMORY_VOLATILE) ?
                i1true : i1false;
        LLVMValueRef slc = i1false;
        LLVMValueRef lwe = i1false;
 
        if (atomic || (HAVE_LLVM <= 0x0309)) {
                emit_data->args[emit_data->arg_count++] = r128;
                emit_data->args[emit_data->arg_count++] = da;
                if (!atomic) {
                        emit_data->args[emit_data->arg_count++] = glc;
@@ -3418,31 +3420,33 @@ static void image_append_args(
  * \param rsrc the v4i32 buffer resource
  * \param index index into the buffer (stride-based)
  * \param offset byte offset into the buffer
  */
 static void buffer_append_args(
                struct si_shader_context *ctx,
                struct lp_build_emit_data *emit_data,
                LLVMValueRef rsrc,
                LLVMValueRef index,
                LLVMValueRef offset,
-               bool atomic)
+               bool atomic,
+               bool force_glc)
 {
        const struct tgsi_full_instruction *inst = emit_data->inst;
        LLVMValueRef i1false = LLVMConstInt(ctx->i1, 0, 0);
        LLVMValueRef i1true = LLVMConstInt(ctx->i1, 1, 0);
 
        emit_data->args[emit_data->arg_count++] = rsrc;
        emit_data->args[emit_data->arg_count++] = index; /* vindex */
        emit_data->args[emit_data->arg_count++] = offset; /* voffset */
        if (!atomic) {
                emit_data->args[emit_data->arg_count++] =
+                       force_glc ||
                        inst->Memory.Qualifier & (TGSI_MEMORY_COHERENT | 
TGSI_MEMORY_VOLATILE) ?
                        i1true : i1false; /* glc */
        }
        emit_data->args[emit_data->arg_count++] = i1false; /* slc */
 }
 
 static void load_fetch_args(
                struct lp_build_tgsi_context * bld_base,
                struct lp_build_emit_data * emit_data)
 {
@@ -3458,37 +3462,37 @@ static void load_fetch_args(
                LLVMBuilderRef builder = gallivm->builder;
                LLVMValueRef offset;
                LLVMValueRef tmp;
 
                rsrc = shader_buffer_fetch_rsrc(ctx, &inst->Src[0]);
 
                tmp = lp_build_emit_fetch(bld_base, inst, 1, 0);
                offset = LLVMBuildBitCast(builder, tmp, 
bld_base->uint_bld.elem_type, "");
 
                buffer_append_args(ctx, emit_data, rsrc, 
bld_base->uint_bld.zero,
-                                  offset, false);
+                                  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);
 
                if (target == TGSI_TEXTURE_BUFFER) {
                        buffer_append_args(ctx, emit_data, rsrc, coords,
-                                       bld_base->uint_bld.zero, false);
+                                          bld_base->uint_bld.zero, false, 
false);
                } else {
                        emit_data->args[0] = coords;
                        emit_data->args[1] = rsrc;
                        emit_data->args[2] = lp_build_const_int32(gallivm, 15); 
/* dmask */
                        emit_data->arg_count = 3;
 
-                       image_append_args(ctx, emit_data, target, false);
+                       image_append_args(ctx, emit_data, target, false, false);
                }
        }
 }
 
 static void load_emit_buffer(struct si_shader_context *ctx,
                             struct lp_build_emit_data *emit_data)
 {
        const struct tgsi_full_instruction *inst = emit_data->inst;
        struct gallivm_state *gallivm = &ctx->gallivm;
        LLVMBuilderRef builder = gallivm->builder;
@@ -3664,39 +3668,47 @@ static void store_fetch_args(
        if (inst->Dst[0].Register.File == TGSI_FILE_BUFFER) {
                LLVMValueRef offset;
                LLVMValueRef tmp;
 
                rsrc = shader_buffer_fetch_rsrc(ctx, &memory);
 
                tmp = lp_build_emit_fetch(bld_base, inst, 0, 0);
                offset = LLVMBuildBitCast(builder, tmp, 
bld_base->uint_bld.elem_type, "");
 
                buffer_append_args(ctx, emit_data, rsrc, 
bld_base->uint_bld.zero,
-                                  offset, false);
+                                  offset, false, false);
        } else if (inst->Dst[0].Register.File == TGSI_FILE_IMAGE) {
                unsigned target = inst->Memory.Texture;
                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);
 
                if (target == TGSI_TEXTURE_BUFFER) {
                        image_fetch_rsrc(bld_base, &memory, true, target, 
&rsrc);
                        buffer_append_args(ctx, emit_data, rsrc, coords,
-                                       bld_base->uint_bld.zero, false);
+                                          bld_base->uint_bld.zero, false, 
force_glc);
                } else {
                        emit_data->args[1] = coords;
                        image_fetch_rsrc(bld_base, &memory, true, target,
                                         &emit_data->args[2]);
                        emit_data->args[3] = lp_build_const_int32(gallivm, 15); 
/* dmask */
                        emit_data->arg_count = 4;
 
-                       image_append_args(ctx, emit_data, target, false);
+                       image_append_args(ctx, emit_data, target, false, 
force_glc);
                }
        }
 }
 
 static void store_emit_buffer(
                struct si_shader_context *ctx,
                struct lp_build_emit_data *emit_data)
 {
        const struct tgsi_full_instruction *inst = emit_data->inst;
        struct gallivm_state *gallivm = &ctx->gallivm;
@@ -3866,36 +3878,36 @@ static void atomic_fetch_args(
 
        if (inst->Src[0].Register.File == TGSI_FILE_BUFFER) {
                LLVMValueRef offset;
 
                rsrc = shader_buffer_fetch_rsrc(ctx, &inst->Src[0]);
 
                tmp = lp_build_emit_fetch(bld_base, inst, 1, 0);
                offset = LLVMBuildBitCast(builder, tmp, 
bld_base->uint_bld.elem_type, "");
 
                buffer_append_args(ctx, emit_data, rsrc, 
bld_base->uint_bld.zero,
-                                  offset, true);
+                                  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);
 
                if (target == TGSI_TEXTURE_BUFFER) {
                        buffer_append_args(ctx, emit_data, rsrc, coords,
-                                          bld_base->uint_bld.zero, true);
+                                          bld_base->uint_bld.zero, 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);
+                       image_append_args(ctx, emit_data, target, true, false);
                }
        }
 }
 
 static void atomic_emit_memory(struct si_shader_context *ctx,
                                struct lp_build_emit_data *emit_data) {
        struct gallivm_state *gallivm = &ctx->gallivm;
        LLVMBuilderRef builder = gallivm->builder;
        const struct tgsi_full_instruction * inst = emit_data->inst;
        LLVMValueRef ptr, result, arg;
-- 
2.7.4

_______________________________________________
mesa-dev mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to