diff options
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_conv.c | 19 | ||||
-rw-r--r-- | src/gallium/auxiliary/gallivm/lp_bld_pack.c | 18 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_test_conv.c | 2 |
3 files changed, 31 insertions, 8 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_conv.c b/src/gallium/auxiliary/gallivm/lp_bld_conv.c index 5e7260dc214..44428f884d1 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_conv.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_conv.c @@ -330,15 +330,24 @@ lp_build_conv(LLVMBuilderRef builder, /* * Truncate or expand bit width + * + * No data conversion should happen here, although the sign bits are + * crucial to avoid bad clamping. */ - assert(!tmp_type.floating || tmp_type.width == dst_type.width); + { + struct lp_type new_type; + + new_type = tmp_type; + new_type.sign = dst_type.sign; + new_type.width = dst_type.width; + new_type.length = dst_type.length; - lp_build_resize(builder, tmp_type, dst_type, tmp, num_srcs, tmp, num_dsts); + lp_build_resize(builder, tmp_type, new_type, tmp, num_srcs, tmp, num_dsts); - tmp_type.width = dst_type.width; - tmp_type.length = dst_type.length; - num_tmps = num_dsts; + tmp_type = new_type; + num_tmps = num_dsts; + } /* * Scale to the widest range diff --git a/src/gallium/auxiliary/gallivm/lp_bld_pack.c b/src/gallium/auxiliary/gallivm/lp_bld_pack.c index dfe83b36c42..7748f8f0999 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_pack.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_pack.c @@ -430,7 +430,10 @@ lp_build_pack(LLVMBuilderRef builder, /** - * Truncate or expand the bitwidth + * Truncate or expand the bitwidth. + * + * NOTE: Getting the right sign flags is crucial here, as we employ some + * intrinsics that do saturation. */ void lp_build_resize(LLVMBuilderRef builder, @@ -442,7 +445,18 @@ lp_build_resize(LLVMBuilderRef builder, LLVMValueRef tmp[LP_MAX_VECTOR_LENGTH]; unsigned i; - assert(!src_type.floating || src_type.width == dst_type.width); + /* + * We don't support float <-> int conversion here. That must be done + * before/after calling this function. + */ + assert(src_type.floating == dst_type.floating); + + /* + * We don't support double <-> float conversion yet, although it could be + * added with little effort. + */ + assert((!src_type.floating && !dst_type.floating) || + src_type.width == dst_type.width); /* We must not loose or gain channels. Only precision */ assert(src_type.length * num_srcs == dst_type.length * num_dsts); diff --git a/src/gallium/drivers/llvmpipe/lp_test_conv.c b/src/gallium/drivers/llvmpipe/lp_test_conv.c index 081f2d324b2..cf41b40581f 100644 --- a/src/gallium/drivers/llvmpipe/lp_test_conv.c +++ b/src/gallium/drivers/llvmpipe/lp_test_conv.c @@ -167,7 +167,7 @@ test_one(unsigned verbose, unsigned i, j; void *code; - if (src_type.width * src_type.length != dst_type.width * dst_type.length || + if (src_type.width * src_type.length != dst_type.width * dst_type.length && src_type.length != dst_type.length) { return TRUE; } |