gallivm: add swizzle support where one channel isn't defined.
authorDave Airlie <airlied@redhat.com>
Thu, 5 Sep 2019 05:41:05 +0000 (15:41 +1000)
committerDave Airlie <airlied@redhat.com>
Thu, 28 Nov 2019 04:49:16 +0000 (14:49 +1000)
NIR doesn't always define all output channels
relies on outputs being memset to 0

Reviewed-by: Roland Scheidegger <sroland@vmware.com>
src/gallium/auxiliary/draw/draw_llvm.c
src/gallium/auxiliary/gallivm/lp_bld_swizzle.c

index ac3eaf11b2787342ec0cdc0db242745d4a6c50e3..ad0ba8b1015491df6fbf87f26a5773bb9a1effd8 100644 (file)
@@ -1673,7 +1673,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
    struct lp_bld_tgsi_system_values system_values;
 
    memset(&system_values, 0, sizeof(system_values));
-
+   memset(&outputs, 0, sizeof(outputs));
    snprintf(func_name, sizeof(func_name), "draw_llvm_vs_variant%u",
             variant->shader->variants_cached);
 
@@ -2416,6 +2416,7 @@ draw_gs_llvm_generate(struct draw_llvm *llvm,
    unsigned vector_length = variant->shader->base.vector_length;
 
    memset(&system_values, 0, sizeof(system_values));
+   memset(&outputs, 0, sizeof(outputs));
 
    snprintf(func_name, sizeof(func_name), "draw_llvm_gs_variant%u",
             variant->shader->variants_cached);
index f3253cf04a2c9c158266d5f15eacf1e13444c16b..24fbd9a5a782737c52cbe28b71211537c0b01a30 100644 (file)
@@ -652,7 +652,7 @@ lp_build_transpose_aos(struct gallivm_state *gallivm,
    struct lp_type double_type_lp = single_type_lp;
    LLVMTypeRef single_type;
    LLVMTypeRef double_type;
-   LLVMValueRef t0, t1, t2, t3;
+   LLVMValueRef t0 = NULL, t1 = NULL, t2 = NULL, t3 = NULL;
 
    double_type_lp.length >>= 1;
    double_type_lp.width  <<= 1;
@@ -660,17 +660,39 @@ lp_build_transpose_aos(struct gallivm_state *gallivm,
    double_type = lp_build_vec_type(gallivm, double_type_lp);
    single_type = lp_build_vec_type(gallivm, single_type_lp);
 
+   LLVMValueRef double_type_zero = LLVMConstNull(double_type);
    /* Interleave x, y, z, w -> xy and zw */
-   t0 = lp_build_interleave2_half(gallivm, single_type_lp, src[0], src[1], 0);
-   t1 = lp_build_interleave2_half(gallivm, single_type_lp, src[2], src[3], 0);
-   t2 = lp_build_interleave2_half(gallivm, single_type_lp, src[0], src[1], 1);
-   t3 = lp_build_interleave2_half(gallivm, single_type_lp, src[2], src[3], 1);
-
-   /* Cast to double width type for second interleave */
-   t0 = LLVMBuildBitCast(gallivm->builder, t0, double_type, "t0");
-   t1 = LLVMBuildBitCast(gallivm->builder, t1, double_type, "t1");
-   t2 = LLVMBuildBitCast(gallivm->builder, t2, double_type, "t2");
-   t3 = LLVMBuildBitCast(gallivm->builder, t3, double_type, "t3");
+   if (src[0]) {
+      LLVMValueRef src1 = src[1];
+      if (!src1)
+         src1 = LLVMConstNull(single_type);
+      t0 = lp_build_interleave2_half(gallivm, single_type_lp, src[0], src1, 0);
+      t2 = lp_build_interleave2_half(gallivm, single_type_lp, src[0], src1, 1);
+
+      /* Cast to double width type for second interleave */
+      t0 = LLVMBuildBitCast(gallivm->builder, t0, double_type, "t0");
+      t2 = LLVMBuildBitCast(gallivm->builder, t2, double_type, "t2");
+   }
+   if (src[2]) {
+      LLVMValueRef src3 = src[3];
+      if (!src3)
+         src3 = LLVMConstNull(single_type);
+      t1 = lp_build_interleave2_half(gallivm, single_type_lp, src[2], src3, 0);
+      t3 = lp_build_interleave2_half(gallivm, single_type_lp, src[2], src3, 1);
+
+      /* Cast to double width type for second interleave */
+      t1 = LLVMBuildBitCast(gallivm->builder, t1, double_type, "t1");
+      t3 = LLVMBuildBitCast(gallivm->builder, t3, double_type, "t3");
+   }
+
+   if (!t0)
+      t0 = double_type_zero;
+   if (!t1)
+      t1 = double_type_zero;
+   if (!t2)
+      t2 = double_type_zero;
+   if (!t3)
+      t3 = double_type_zero;
 
    /* Interleave xy, zw -> xyzw */
    dst[0] = lp_build_interleave2_half(gallivm, double_type_lp, t0, t1, 0);