diff options
6 files changed, 74 insertions, 35 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format.h b/src/gallium/auxiliary/gallivm/lp_bld_format.h index 3608a68202f..8fb173bce1e 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_format.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_format.h @@ -93,7 +93,7 @@ lp_build_unpack_rgba_soa(struct gallivm_state *gallivm, LLVMValueRef rgba_out[4]); void -lp_build_rgba8_to_f32_soa(struct gallivm_state *gallivm, +lp_build_rgba8_to_fi32_soa(struct gallivm_state *gallivm, struct lp_type dst_type, LLVMValueRef packed, LLVMValueRef *rgba); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format_aos.c b/src/gallium/auxiliary/gallivm/lp_bld_format_aos.c index e5c93f0c918..6a1bf6765d7 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_format_aos.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_format_aos.c @@ -710,6 +710,8 @@ lp_build_fetch_rgba_aos(struct gallivm_state *gallivm, return res; } + assert(!util_format_is_pure_integer(format_desc->format)); + assert(0); return lp_build_undef(gallivm, type); } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format_aos_array.c b/src/gallium/auxiliary/gallivm/lp_bld_format_aos_array.c index 9642b9ecfed..3402a0b1530 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_format_aos_array.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_format_aos_array.c @@ -148,7 +148,7 @@ lp_build_fetch_rgba_aos_array(struct gallivm_state *gallivm, tmp_type = dst_type; if (pure_integer) { - assert(dst_type.floating); + /* some callers expect (fake) floats other real ints. */ tmp_type.floating = 0; tmp_type.sign = src_type.sign; } @@ -160,8 +160,8 @@ lp_build_fetch_rgba_aos_array(struct gallivm_state *gallivm, lp_build_context_init(&bld, gallivm, tmp_type); res = lp_build_format_swizzle_aos(format_desc, &bld, res); - /* Bitcast to floats (for pure integers) */ - if (pure_integer) { + /* Bitcast to floats (for pure integers) when requested */ + if (pure_integer && dst_type.floating) { res = LLVMBuildBitCast(builder, res, lp_build_vec_type(gallivm, dst_type), ""); } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c index afeb34079bf..9eb6ef5438d 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c @@ -114,7 +114,6 @@ lp_build_unpack_rgba_soa(struct gallivm_state *gallivm, assert(format_desc->block.height == 1); assert(format_desc->block.bits <= type.width); /* FIXME: Support more output types */ - assert(type.floating); assert(type.width == 32); lp_build_context_init(&bld, gallivm, type); @@ -162,10 +161,11 @@ lp_build_unpack_rgba_soa(struct gallivm_state *gallivm, input = LLVMBuildSIToFP(builder, input, lp_build_vec_type(gallivm, type), ""); } - else { - /* FIXME */ - assert(0); - input = lp_build_undef(gallivm, type); + else if (format_desc->channel[chan].pure_integer) { + /* Nothing to do */ + } else { + /* FIXME */ + assert(0); } break; @@ -203,10 +203,11 @@ lp_build_unpack_rgba_soa(struct gallivm_state *gallivm, input = LLVMBuildFMul(builder, input, scale_val, ""); } } - else { - /* FIXME */ - assert(0); - input = lp_build_undef(gallivm, type); + else if (format_desc->channel[chan].pure_integer) { + /* Nothing to do */ + } else { + /* FIXME */ + assert(0); } break; @@ -254,16 +255,28 @@ lp_build_unpack_rgba_soa(struct gallivm_state *gallivm, } +/** + * Convert a vector of rgba8 values into 32bit wide SoA vectors. + * + * \param dst_type The desired return type. For pure integer formats + * this should be a 32bit wide int or uint vector type, + * otherwise a float vector type. + * + * \param packed The rgba8 values to pack. + * + * \param rgba The 4 SoA return vectors. + */ void -lp_build_rgba8_to_f32_soa(struct gallivm_state *gallivm, - struct lp_type dst_type, - LLVMValueRef packed, - LLVMValueRef *rgba) +lp_build_rgba8_to_fi32_soa(struct gallivm_state *gallivm, + struct lp_type dst_type, + LLVMValueRef packed, + LLVMValueRef *rgba) { LLVMBuilderRef builder = gallivm->builder; LLVMValueRef mask = lp_build_const_int_vec(gallivm, dst_type, 0xff); unsigned chan; + /* XXX technically shouldn't use that for uint dst_type */ packed = LLVMBuildBitCast(builder, packed, lp_build_int_vec_type(gallivm, dst_type), ""); @@ -282,7 +295,8 @@ lp_build_rgba8_to_f32_soa(struct gallivm_state *gallivm, if (stop < 32) input = LLVMBuildAnd(builder, input, mask, ""); - input = lp_build_unsigned_norm_to_float(gallivm, 8, dst_type, input); + if (dst_type.floating) + input = lp_build_unsigned_norm_to_float(gallivm, 8, dst_type, input); rgba[chan] = input; } @@ -372,7 +386,7 @@ lp_build_fetch_rgba_soa(struct gallivm_state *gallivm, tmp = lp_build_fetch_rgba_aos(gallivm, format_desc, tmp_type, base_ptr, offset, i, j); - lp_build_rgba8_to_f32_soa(gallivm, + lp_build_rgba8_to_fi32_soa(gallivm, type, tmp, rgba_out); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c index 7d7e351d21d..9371e1c2818 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_aos.c @@ -1673,7 +1673,7 @@ lp_build_sample_aos(struct lp_build_sample_context *bld, /* * Convert to SoA and swizzle. */ - lp_build_rgba8_to_f32_soa(bld->gallivm, + lp_build_rgba8_to_fi32_soa(bld->gallivm, bld->texel_type, packed, unswizzled); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c index f1d2f513661..57298a47ffa 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c @@ -1448,6 +1448,19 @@ lp_build_sample_soa(struct gallivm_state *gallivm, bld.perquadf_type.length = type.length > 4 ? ((type.length + 15) / 16) * 4 : 1; bld.perquadi_type = lp_int_type(bld.perquadf_type); + /* always using the first channel hopefully should be safe, + * if not things WILL break in other places anyway. + */ + if (bld.format_desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB && + bld.format_desc->channel[0].pure_integer) { + if (bld.format_desc->channel[0].type == UTIL_FORMAT_TYPE_SIGNED) { + bld.texel_type = lp_type_int_vec(type.width, type.width * type.length); + } + else if (bld.format_desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED) { + bld.texel_type = lp_type_uint_vec(type.width, type.width * type.length); + } + } + /* * There are other situations where at least the multiple int lods could be * avoided like min and max lod being equal. @@ -1516,6 +1529,13 @@ lp_build_sample_soa(struct gallivm_state *gallivm, coords, texel_out); } + + else if (is_fetch) { + lp_build_fetch_texel(&bld, unit, coords, + explicit_lod, offsets, + texel_out); + } + else { LLVMValueRef lod_ipart = NULL, lod_fpart = NULL; LLVMValueRef ilevel0 = NULL, ilevel1 = NULL; @@ -1535,18 +1555,6 @@ lp_build_sample_soa(struct gallivm_state *gallivm, static_state->wrap_t); } - if (is_fetch) { - lp_build_fetch_texel(&bld, unit, coords, - explicit_lod, offsets, - texel_out); - - if (static_state->target != PIPE_BUFFER) { - apply_sampler_swizzle(&bld, texel_out); - } - - return; - } - lp_build_sample_common(&bld, unit, &s, &t, &r, derivs, lod_bias, explicit_lod, @@ -1620,7 +1628,8 @@ lp_build_sample_soa(struct gallivm_state *gallivm, bld4.float_size_in_type = lp_type_float(32); bld4.float_size_in_type.length = dims > 1 ? 4 : 1; bld4.int_size_in_type = lp_int_type(bld4.float_size_in_type); - bld4.texel_type = type4; + bld4.texel_type = bld.texel_type; + bld4.texel_type.length = 4; bld4.perquadf_type = type4; /* we want native vector size to be able to use our intrinsics */ bld4.perquadf_type.length = 1; @@ -1684,11 +1693,25 @@ lp_build_sample_soa(struct gallivm_state *gallivm, texel_out[j] = lp_build_concat(gallivm, texelouttmp[j], type4, num_quads); } } + + lp_build_sample_compare(&bld, coords, texel_out); } - lp_build_sample_compare(&bld, coords, texel_out); + if (static_state->target != PIPE_BUFFER) { + apply_sampler_swizzle(&bld, texel_out); + } - apply_sampler_swizzle(&bld, texel_out); + /* + * texel type can be a (32bit) int/uint (for pure int formats only), + * however we are expected to always return floats (storage is untyped). + */ + if (!bld.texel_type.floating) { + unsigned chan; + for (chan = 0; chan < 4; chan++) { + texel_out[chan] = LLVMBuildBitCast(builder, texel_out[chan], + lp_build_vec_type(gallivm, type), ""); + } + } } void |