radv: handle multi-component shared load/stores.
authorDave Airlie <airlied@redhat.com>
Fri, 23 Dec 2016 05:41:18 +0000 (05:41 +0000)
committerDave Airlie <airlied@gmail.com>
Mon, 26 Dec 2016 00:31:20 +0000 (10:31 +1000)
This was seen in doom shaders, so handle it properly.

Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Signed-off-by: Dave AIrlie <airlied@redhat.com>
src/amd/common/ac_nir_to_llvm.c

index 90ee917d13b47a1a0a0484baef42c6acee3d6a4e..f214fcd006ac19bd17b76b2ded473f4ea081a5c1 100644 (file)
@@ -2244,13 +2244,15 @@ static LLVMValueRef visit_load_var(struct nir_to_llvm_context *ctx,
                                      &const_index, &indir_index);
                LLVMValueRef ptr = get_shared_memory_ptr(ctx, idx, ctx->i32);
                LLVMValueRef derived_ptr;
-               LLVMValueRef index = ctx->i32zero;
-               if (indir_index)
-                       index = LLVMBuildAdd(ctx->builder, index, indir_index, "");
-               derived_ptr = LLVMBuildGEP(ctx->builder, ptr, &index, 1, "");
 
-               return to_integer(ctx, LLVMBuildLoad(ctx->builder, derived_ptr, ""));
-               break;
+               for (unsigned chan = 0; chan < ve; chan++) {
+                       LLVMValueRef index = LLVMConstInt(ctx->i32, chan, false);
+                       if (indir_index)
+                               index = LLVMBuildAdd(ctx->builder, index, indir_index, "");
+                       derived_ptr = LLVMBuildGEP(ctx->builder, ptr, &index, 1, "");
+                       values[chan] = LLVMBuildLoad(ctx->builder, derived_ptr, "");
+               }
+               return to_integer(ctx, build_gather_values(ctx, values, ve));
        }
        default:
                break;
@@ -2345,14 +2347,29 @@ visit_store_var(struct nir_to_llvm_context *ctx,
                                      &const_index, &indir_index);
 
                ptr = get_shared_memory_ptr(ctx, idx, ctx->i32);
-               LLVMValueRef index = ctx->i32zero;
                LLVMValueRef derived_ptr;
 
-               if (indir_index)
-                       index = LLVMBuildAdd(ctx->builder, index, indir_index, "");
-               derived_ptr = LLVMBuildGEP(ctx->builder, ptr, &index, 1, "");
-               LLVMBuildStore(ctx->builder,
-                              to_integer(ctx, src), derived_ptr);
+               for (unsigned chan = 0; chan < 4; chan++) {
+                       if (!(writemask & (1 << chan)))
+                               continue;
+
+                       LLVMValueRef index = LLVMConstInt(ctx->i32, chan, false);
+
+                       if (get_llvm_num_components(src) == 1)
+                               value = src;
+                       else
+                               value = LLVMBuildExtractElement(ctx->builder, src,
+                                                               LLVMConstInt(ctx->i32,
+                                                                            chan, false),
+                                                               "");
+
+                       if (indir_index)
+                               index = LLVMBuildAdd(ctx->builder, index, indir_index, "");
+
+                       derived_ptr = LLVMBuildGEP(ctx->builder, ptr, &index, 1, "");
+                       LLVMBuildStore(ctx->builder,
+                                      to_integer(ctx, value), derived_ptr);
+               }
                break;
        }
        default: