X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fauxiliary%2Fgallivm%2Flp_bld_format_yuv.c;h=fa0e8b656bb133fd2613cc54785a392165ccee34;hb=f72de6f3863049106288b7dd66efeb64c822fb17;hp=2bce2895551fb04e710141975d089f649230ec35;hpb=1218430e1200a08cd64b6555d3fd1fd0274ad9e5;p=mesa.git diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format_yuv.c b/src/gallium/auxiliary/gallivm/lp_bld_format_yuv.c index 2bce2895551..fa0e8b656bb 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_format_yuv.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_format_yuv.c @@ -43,6 +43,7 @@ #include "lp_bld_conv.h" #include "lp_bld_gather.h" #include "lp_bld_format.h" +#include "lp_bld_init.h" #include "lp_bld_logic.h" /** @@ -51,7 +52,7 @@ * @param i is a vector with the x pixel coordinate (0 or 1) */ static void -uyvy_to_yuv_soa(LLVMBuilderRef builder, +uyvy_to_yuv_soa(struct gallivm_state *gallivm, unsigned n, LLVMValueRef packed, LLVMValueRef i, @@ -59,6 +60,7 @@ uyvy_to_yuv_soa(LLVMBuilderRef builder, LLVMValueRef *u, LLVMValueRef *v) { + LLVMBuilderRef builder = gallivm->builder; struct lp_type type; LLVMValueRef mask; @@ -70,9 +72,15 @@ uyvy_to_yuv_soa(LLVMBuilderRef builder, assert(lp_check_value(type, i)); /* + * Little endian: * y = (uyvy >> (16*i + 8)) & 0xff * u = (uyvy ) & 0xff * v = (uyvy >> 16 ) & 0xff + * + * Big endian: + * y = (uyvy >> (-16*i + 16)) & 0xff + * u = (uyvy >> 24) & 0xff + * v = (uyvy >> 8) & 0xff */ #if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) @@ -82,29 +90,39 @@ uyvy_to_yuv_soa(LLVMBuilderRef builder, * per element. Didn't measure performance but cuts shader size * by quite a bit (less difference if cpu has no sse4.1 support). */ - if (util_cpu_caps.has_sse2 && n == 4) { + if (util_cpu_caps.has_sse2 && n > 1) { LLVMValueRef sel, tmp, tmp2; struct lp_build_context bld32; - lp_build_context_init(&bld32, builder, type); + lp_build_context_init(&bld32, gallivm, type); - tmp = LLVMBuildLShr(builder, packed, lp_build_const_int_vec(type, 8), ""); - tmp2 = LLVMBuildLShr(builder, tmp, lp_build_const_int_vec(type, 16), ""); - sel = lp_build_compare(builder, type, PIPE_FUNC_EQUAL, i, lp_build_const_int_vec(type, 0)); + tmp = LLVMBuildLShr(builder, packed, lp_build_const_int_vec(gallivm, type, 8), ""); + tmp2 = LLVMBuildLShr(builder, tmp, lp_build_const_int_vec(gallivm, type, 16), ""); + sel = lp_build_compare(gallivm, type, PIPE_FUNC_EQUAL, i, lp_build_const_int_vec(gallivm, type, 0)); *y = lp_build_select(&bld32, sel, tmp, tmp2); } else #endif { LLVMValueRef shift; - shift = LLVMBuildMul(builder, i, lp_build_const_int_vec(type, 16), ""); - shift = LLVMBuildAdd(builder, shift, lp_build_const_int_vec(type, 8), ""); +#ifdef PIPE_ARCH_LITTLE_ENDIAN + shift = LLVMBuildMul(builder, i, lp_build_const_int_vec(gallivm, type, 16), ""); + shift = LLVMBuildAdd(builder, shift, lp_build_const_int_vec(gallivm, type, 8), ""); +#else + shift = LLVMBuildMul(builder, i, lp_build_const_int_vec(gallivm, type, -16), ""); + shift = LLVMBuildAdd(builder, shift, lp_build_const_int_vec(gallivm, type, 16), ""); +#endif *y = LLVMBuildLShr(builder, packed, shift, ""); } +#ifdef PIPE_ARCH_LITTLE_ENDIAN *u = packed; - *v = LLVMBuildLShr(builder, packed, lp_build_const_int_vec(type, 16), ""); + *v = LLVMBuildLShr(builder, packed, lp_build_const_int_vec(gallivm, type, 16), ""); +#else + *u = LLVMBuildLShr(builder, packed, lp_build_const_int_vec(gallivm, type, 24), ""); + *v = LLVMBuildLShr(builder, packed, lp_build_const_int_vec(gallivm, type, 8), ""); +#endif - mask = lp_build_const_int_vec(type, 0xff); + mask = lp_build_const_int_vec(gallivm, type, 0xff); *y = LLVMBuildAnd(builder, *y, mask, "y"); *u = LLVMBuildAnd(builder, *u, mask, "u"); @@ -118,7 +136,7 @@ uyvy_to_yuv_soa(LLVMBuilderRef builder, * @param i is a vector with the x pixel coordinate (0 or 1) */ static void -yuyv_to_yuv_soa(LLVMBuilderRef builder, +yuyv_to_yuv_soa(struct gallivm_state *gallivm, unsigned n, LLVMValueRef packed, LLVMValueRef i, @@ -126,6 +144,7 @@ yuyv_to_yuv_soa(LLVMBuilderRef builder, LLVMValueRef *u, LLVMValueRef *v) { + LLVMBuilderRef builder = gallivm->builder; struct lp_type type; LLVMValueRef mask; @@ -137,9 +156,15 @@ yuyv_to_yuv_soa(LLVMBuilderRef builder, assert(lp_check_value(type, i)); /* + * Little endian: * y = (yuyv >> 16*i) & 0xff * u = (yuyv >> 8 ) & 0xff * v = (yuyv >> 24 ) & 0xff + * + * Big endian: + * y = (yuyv >> (-16*i + 24) & 0xff + * u = (yuyv >> 16) & 0xff + * v = (yuyv) & 0xff */ #if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) @@ -149,27 +174,37 @@ yuyv_to_yuv_soa(LLVMBuilderRef builder, * per element. Didn't measure performance but cuts shader size * by quite a bit (less difference if cpu has no sse4.1 support). */ - if (util_cpu_caps.has_sse2 && n == 4) { + if (util_cpu_caps.has_sse2 && n > 1) { LLVMValueRef sel, tmp; struct lp_build_context bld32; - lp_build_context_init(&bld32, builder, type); + lp_build_context_init(&bld32, gallivm, type); - tmp = LLVMBuildLShr(builder, packed, lp_build_const_int_vec(type, 16), ""); - sel = lp_build_compare(builder, type, PIPE_FUNC_EQUAL, i, lp_build_const_int_vec(type, 0)); + tmp = LLVMBuildLShr(builder, packed, lp_build_const_int_vec(gallivm, type, 16), ""); + sel = lp_build_compare(gallivm, type, PIPE_FUNC_EQUAL, i, lp_build_const_int_vec(gallivm, type, 0)); *y = lp_build_select(&bld32, sel, packed, tmp); } else #endif { LLVMValueRef shift; - shift = LLVMBuildMul(builder, i, lp_build_const_int_vec(type, 16), ""); +#ifdef PIPE_ARCH_LITTLE_ENDIAN + shift = LLVMBuildMul(builder, i, lp_build_const_int_vec(gallivm, type, 16), ""); +#else + shift = LLVMBuildMul(builder, i, lp_build_const_int_vec(gallivm, type, -16), ""); + shift = LLVMBuildAdd(builder, shift, lp_build_const_int_vec(gallivm, type, 24), ""); +#endif *y = LLVMBuildLShr(builder, packed, shift, ""); } - *u = LLVMBuildLShr(builder, packed, lp_build_const_int_vec(type, 8), ""); - *v = LLVMBuildLShr(builder, packed, lp_build_const_int_vec(type, 24), ""); +#ifdef PIPE_ARCH_LITTLE_ENDIAN + *u = LLVMBuildLShr(builder, packed, lp_build_const_int_vec(gallivm, type, 8), ""); + *v = LLVMBuildLShr(builder, packed, lp_build_const_int_vec(gallivm, type, 24), ""); +#else + *u = LLVMBuildLShr(builder, packed, lp_build_const_int_vec(gallivm, type, 16), ""); + *v = packed; +#endif - mask = lp_build_const_int_vec(type, 0xff); + mask = lp_build_const_int_vec(gallivm, type, 0xff); *y = LLVMBuildAnd(builder, *y, mask, "y"); *u = LLVMBuildAnd(builder, *u, mask, "u"); @@ -177,12 +212,13 @@ yuyv_to_yuv_soa(LLVMBuilderRef builder, } -static INLINE void -yuv_to_rgb_soa(LLVMBuilderRef builder, +static inline void +yuv_to_rgb_soa(struct gallivm_state *gallivm, unsigned n, LLVMValueRef y, LLVMValueRef u, LLVMValueRef v, LLVMValueRef *r, LLVMValueRef *g, LLVMValueRef *b) { + LLVMBuilderRef builder = gallivm->builder; struct lp_type type; struct lp_build_context bld; @@ -203,7 +239,7 @@ yuv_to_rgb_soa(LLVMBuilderRef builder, type.width = 32; type.length = n; - lp_build_context_init(&bld, builder, type); + lp_build_context_init(&bld, gallivm, type); assert(lp_check_value(type, y)); assert(lp_check_value(type, u)); @@ -213,17 +249,17 @@ yuv_to_rgb_soa(LLVMBuilderRef builder, * Constants */ - c0 = lp_build_const_int_vec(type, 0); - c8 = lp_build_const_int_vec(type, 8); - c16 = lp_build_const_int_vec(type, 16); - c128 = lp_build_const_int_vec(type, 128); - c255 = lp_build_const_int_vec(type, 255); + c0 = lp_build_const_int_vec(gallivm, type, 0); + c8 = lp_build_const_int_vec(gallivm, type, 8); + c16 = lp_build_const_int_vec(gallivm, type, 16); + c128 = lp_build_const_int_vec(gallivm, type, 128); + c255 = lp_build_const_int_vec(gallivm, type, 255); - cy = lp_build_const_int_vec(type, 298); - cug = lp_build_const_int_vec(type, -100); - cub = lp_build_const_int_vec(type, 516); - cvr = lp_build_const_int_vec(type, 409); - cvg = lp_build_const_int_vec(type, -208); + cy = lp_build_const_int_vec(gallivm, type, 298); + cug = lp_build_const_int_vec(gallivm, type, -100); + cub = lp_build_const_int_vec(gallivm, type, 516); + cvr = lp_build_const_int_vec(gallivm, type, 409); + cvg = lp_build_const_int_vec(gallivm, type, -208); /* * y -= 16; @@ -276,10 +312,11 @@ yuv_to_rgb_soa(LLVMBuilderRef builder, static LLVMValueRef -rgb_to_rgba_aos(LLVMBuilderRef builder, +rgb_to_rgba_aos(struct gallivm_state *gallivm, unsigned n, LLVMValueRef r, LLVMValueRef g, LLVMValueRef b) { + LLVMBuilderRef builder = gallivm->builder; struct lp_type type; LLVMValueRef a; LLVMValueRef rgba; @@ -297,10 +334,17 @@ rgb_to_rgba_aos(LLVMBuilderRef builder, * Make a 4 x unorm8 vector */ +#ifdef PIPE_ARCH_LITTLE_ENDIAN r = r; - g = LLVMBuildShl(builder, g, lp_build_const_int_vec(type, 8), ""); - b = LLVMBuildShl(builder, b, lp_build_const_int_vec(type, 16), ""); - a = lp_build_const_int_vec(type, 0xff000000); + g = LLVMBuildShl(builder, g, lp_build_const_int_vec(gallivm, type, 8), ""); + b = LLVMBuildShl(builder, b, lp_build_const_int_vec(gallivm, type, 16), ""); + a = lp_build_const_int_vec(gallivm, type, 0xff000000); +#else + r = LLVMBuildShl(builder, r, lp_build_const_int_vec(gallivm, type, 24), ""); + g = LLVMBuildShl(builder, g, lp_build_const_int_vec(gallivm, type, 16), ""); + b = LLVMBuildShl(builder, b, lp_build_const_int_vec(gallivm, type, 8), ""); + a = lp_build_const_int_vec(gallivm, type, 0x000000ff); +#endif rgba = r; rgba = LLVMBuildOr(builder, rgba, g, ""); @@ -308,7 +352,7 @@ rgb_to_rgba_aos(LLVMBuilderRef builder, rgba = LLVMBuildOr(builder, rgba, a, ""); rgba = LLVMBuildBitCast(builder, rgba, - LLVMVectorType(LLVMInt8Type(), 4*n), ""); + LLVMVectorType(LLVMInt8TypeInContext(gallivm->context), 4*n), ""); return rgba; } @@ -318,7 +362,7 @@ rgb_to_rgba_aos(LLVMBuilderRef builder, * Convert from packed UYVY to <4n x i8> RGBA AoS */ static LLVMValueRef -uyvy_to_rgba_aos(LLVMBuilderRef builder, +uyvy_to_rgba_aos(struct gallivm_state *gallivm, unsigned n, LLVMValueRef packed, LLVMValueRef i) @@ -327,9 +371,9 @@ uyvy_to_rgba_aos(LLVMBuilderRef builder, LLVMValueRef r, g, b; LLVMValueRef rgba; - uyvy_to_yuv_soa(builder, n, packed, i, &y, &u, &v); - yuv_to_rgb_soa(builder, n, y, u, v, &r, &g, &b); - rgba = rgb_to_rgba_aos(builder, n, r, g, b); + uyvy_to_yuv_soa(gallivm, n, packed, i, &y, &u, &v); + yuv_to_rgb_soa(gallivm, n, y, u, v, &r, &g, &b); + rgba = rgb_to_rgba_aos(gallivm, n, r, g, b); return rgba; } @@ -339,7 +383,7 @@ uyvy_to_rgba_aos(LLVMBuilderRef builder, * Convert from packed YUYV to <4n x i8> RGBA AoS */ static LLVMValueRef -yuyv_to_rgba_aos(LLVMBuilderRef builder, +yuyv_to_rgba_aos(struct gallivm_state *gallivm, unsigned n, LLVMValueRef packed, LLVMValueRef i) @@ -348,9 +392,9 @@ yuyv_to_rgba_aos(LLVMBuilderRef builder, LLVMValueRef r, g, b; LLVMValueRef rgba; - yuyv_to_yuv_soa(builder, n, packed, i, &y, &u, &v); - yuv_to_rgb_soa(builder, n, y, u, v, &r, &g, &b); - rgba = rgb_to_rgba_aos(builder, n, r, g, b); + yuyv_to_yuv_soa(gallivm, n, packed, i, &y, &u, &v); + yuv_to_rgb_soa(gallivm, n, y, u, v, &r, &g, &b); + rgba = rgb_to_rgba_aos(gallivm, n, r, g, b); return rgba; } @@ -360,7 +404,7 @@ yuyv_to_rgba_aos(LLVMBuilderRef builder, * Convert from packed RG_BG to <4n x i8> RGBA AoS */ static LLVMValueRef -rgbg_to_rgba_aos(LLVMBuilderRef builder, +rgbg_to_rgba_aos(struct gallivm_state *gallivm, unsigned n, LLVMValueRef packed, LLVMValueRef i) @@ -368,8 +412,8 @@ rgbg_to_rgba_aos(LLVMBuilderRef builder, LLVMValueRef r, g, b; LLVMValueRef rgba; - uyvy_to_yuv_soa(builder, n, packed, i, &g, &r, &b); - rgba = rgb_to_rgba_aos(builder, n, r, g, b); + uyvy_to_yuv_soa(gallivm, n, packed, i, &g, &r, &b); + rgba = rgb_to_rgba_aos(gallivm, n, r, g, b); return rgba; } @@ -379,7 +423,7 @@ rgbg_to_rgba_aos(LLVMBuilderRef builder, * Convert from packed GR_GB to <4n x i8> RGBA AoS */ static LLVMValueRef -grgb_to_rgba_aos(LLVMBuilderRef builder, +grgb_to_rgba_aos(struct gallivm_state *gallivm, unsigned n, LLVMValueRef packed, LLVMValueRef i) @@ -387,13 +431,49 @@ grgb_to_rgba_aos(LLVMBuilderRef builder, LLVMValueRef r, g, b; LLVMValueRef rgba; - yuyv_to_yuv_soa(builder, n, packed, i, &g, &r, &b); - rgba = rgb_to_rgba_aos(builder, n, r, g, b); + yuyv_to_yuv_soa(gallivm, n, packed, i, &g, &r, &b); + rgba = rgb_to_rgba_aos(gallivm, n, r, g, b); + + return rgba; +} + +/** + * Convert from packed GR_BR to <4n x i8> RGBA AoS + */ +static LLVMValueRef +grbr_to_rgba_aos(struct gallivm_state *gallivm, + unsigned n, + LLVMValueRef packed, + LLVMValueRef i) +{ + LLVMValueRef r, g, b; + LLVMValueRef rgba; + + uyvy_to_yuv_soa(gallivm, n, packed, i, &r, &g, &b); + rgba = rgb_to_rgba_aos(gallivm, n, r, g, b); return rgba; } +/** + * Convert from packed RG_RB to <4n x i8> RGBA AoS + */ +static LLVMValueRef +rgrb_to_rgba_aos(struct gallivm_state *gallivm, + unsigned n, + LLVMValueRef packed, + LLVMValueRef i) +{ + LLVMValueRef r, g, b; + LLVMValueRef rgba; + + yuyv_to_yuv_soa(gallivm, n, packed, i, &r, &g, &b); + rgba = rgb_to_rgba_aos(gallivm, n, r, g, b); + + return rgba; +} + /** * @param n is the number of pixels processed * @param packed is a vector with the packed YUYV blocks @@ -401,7 +481,7 @@ grgb_to_rgba_aos(LLVMBuilderRef builder, * @return a <4*n x i8> vector with the pixel RGBA values in AoS */ LLVMValueRef -lp_build_fetch_subsampled_rgba_aos(LLVMBuilderRef builder, +lp_build_fetch_subsampled_rgba_aos(struct gallivm_state *gallivm, const struct util_format_description *format_desc, unsigned n, LLVMValueRef base_ptr, @@ -417,26 +497,32 @@ lp_build_fetch_subsampled_rgba_aos(LLVMBuilderRef builder, assert(format_desc->block.width == 2); assert(format_desc->block.height == 1); - packed = lp_build_gather(builder, n, 32, 32, base_ptr, offset); + packed = lp_build_gather(gallivm, n, 32, 32, TRUE, base_ptr, offset, FALSE); (void)j; switch (format_desc->format) { case PIPE_FORMAT_UYVY: - rgba = uyvy_to_rgba_aos(builder, n, packed, i); + rgba = uyvy_to_rgba_aos(gallivm, n, packed, i); break; case PIPE_FORMAT_YUYV: - rgba = yuyv_to_rgba_aos(builder, n, packed, i); + rgba = yuyv_to_rgba_aos(gallivm, n, packed, i); break; case PIPE_FORMAT_R8G8_B8G8_UNORM: - rgba = rgbg_to_rgba_aos(builder, n, packed, i); + rgba = rgbg_to_rgba_aos(gallivm, n, packed, i); break; case PIPE_FORMAT_G8R8_G8B8_UNORM: - rgba = grgb_to_rgba_aos(builder, n, packed, i); + rgba = grgb_to_rgba_aos(gallivm, n, packed, i); + break; + case PIPE_FORMAT_G8R8_B8R8_UNORM: + rgba = grbr_to_rgba_aos(gallivm, n, packed, i); + break; + case PIPE_FORMAT_R8G8_R8B8_UNORM: + rgba = rgrb_to_rgba_aos(gallivm, n, packed, i); break; default: assert(0); - rgba = LLVMGetUndef(LLVMVectorType(LLVMInt8Type(), 4*n)); + rgba = LLVMGetUndef(LLVMVectorType(LLVMInt8TypeInContext(gallivm->context), 4*n)); break; }