llvmpipe: clamp color storage for integer types.
authorDave Airlie <airlied@redhat.com>
Tue, 21 Apr 2020 05:28:38 +0000 (15:28 +1000)
committerDave Airlie <airlied@redhat.com>
Mon, 27 Apr 2020 02:35:24 +0000 (12:35 +1000)
If storing to an integer for lower bit size (i.e. 16-bit uint to
10-bit uint), we need to clamp to the maximum value not truncate.

Fixes:
dEQP-VK.api.copy_and_blit.core.blit_image.all_formats.color.r16_uint.a2b10g10r10_uint_pack32.optimal_optimal_nearest

Reviewed-by: Roland Scheidegger <sroland@vmware.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4574>

src/gallium/drivers/llvmpipe/lp_state_fs.c

index f55cfa9a85db3526092624af4ba1415e3281ca69..8826d499b47d7b70217846fc3c0a467f88a3ab30 100644 (file)
@@ -1590,6 +1590,7 @@ convert_from_blend_type(struct gallivm_state *gallivm,
       for (j = 0; j < src_fmt->nr_channels; ++j) {
          unsigned mask = 0;
          unsigned sa = src_fmt->channel[j].shift;
+         unsigned sz_a = src_fmt->channel[j].size;
 #if UTIL_ARCH_LITTLE_ENDIAN
          unsigned from_lsb = j;
 #else
@@ -1618,6 +1619,10 @@ convert_from_blend_type(struct gallivm_state *gallivm,
          if (src_type.norm) {
             chans[j] = scale_bits(gallivm, blend_type.width,
                                   src_fmt->channel[j].size, chans[j], src_type);
+         } else if (!src_type.floating && sz_a < blend_type.width) {
+            LLVMValueRef mask_val = lp_build_const_int_vec(gallivm, src_type, (1UL << sz_a) - 1);
+            LLVMValueRef mask = LLVMBuildICmp(builder, LLVMIntUGT, chans[j], mask_val, "");
+            chans[j] = LLVMBuildSelect(builder, mask, mask_val, chans[j], "");
          }
 
          /* Insert bits */