radv: Implement buffer stores with less than 4 components.
authorBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Mon, 24 Dec 2018 14:41:56 +0000 (15:41 +0100)
committerBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Mon, 7 Jan 2019 13:54:14 +0000 (14:54 +0100)
We started using it in the btoi paths for r32g32b32, and the LLVM IR
checker will complain about it because we end up with intrinsics with
the wrong type extension in the name.

Fixes: 593996bc02 ("radv: implement buffer to image operations for R32G32B32")
Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
src/amd/common/ac_nir_to_llvm.c

index 84dbe1745756f8ad5c8cb84c17e1d060a26bf1d7..8dea35178b36827195ba46c2e246384aae4d3982 100644 (file)
@@ -2392,24 +2392,33 @@ static void visit_image_store(struct ac_nir_context *ctx,
                glc = ctx->ac.i1true;
 
        if (dim == GLSL_SAMPLER_DIM_BUF) {
+               char name[48];
+               const char *types[] = { "f32", "v2f32", "v4f32" };
                LLVMValueRef rsrc = get_image_buffer_descriptor(ctx, instr, true);
+               LLVMValueRef src = ac_to_float(&ctx->ac, get_src(ctx, instr->src[3]));
+               unsigned src_channels = ac_get_llvm_num_components(src);
 
-               params[0] = ac_to_float(&ctx->ac, get_src(ctx, instr->src[3])); /* data */
+               if (src_channels == 3)
+                       src = ac_build_expand(&ctx->ac, src, 3, 4);
+
+               params[0] = src; /* data */
                params[1] = rsrc;
                params[2] = LLVMBuildExtractElement(ctx->ac.builder, get_src(ctx, instr->src[1]),
                                                    ctx->ac.i32_0, ""); /* vindex */
                params[3] = ctx->ac.i32_0; /* voffset */
+               snprintf(name, sizeof(name), "%s.%s",
+                        HAVE_LLVM >= 0x800 ? "llvm.amdgcn.struct.buffer.store.format"
+                                           : "llvm.amdgcn.buffer.store.format",
+                        types[CLAMP(src_channels, 1, 3) - 1]);
+
                if (HAVE_LLVM >= 0x800) {
                        params[4] = ctx->ac.i32_0; /* soffset */
                        params[5] = glc ? ctx->ac.i32_1 : ctx->ac.i32_0;
-                       ac_build_intrinsic(&ctx->ac, "llvm.amdgcn.struct.buffer.store.format.v4f32", ctx->ac.voidt,
-                                          params, 6, 0);
                } else {
                        params[4] = glc;  /* glc */
                        params[5] = ctx->ac.i1false;  /* slc */
-                       ac_build_intrinsic(&ctx->ac, "llvm.amdgcn.buffer.store.format.v4f32", ctx->ac.voidt,
-                                          params, 6, 0);
                }
+               ac_build_intrinsic(&ctx->ac, name, ctx->ac.voidt, params, 6, 0);
        } else {
                struct ac_image_args args = {};
                args.opcode = ac_image_store;