From 8c3c9c36f33d2bcb44893ec9ad450d60ce799229 Mon Sep 17 00:00:00 2001 From: Italo Nicola Date: Thu, 9 Feb 2023 11:32:12 +0000 Subject: [PATCH] mesa/main: add PIPE_FORMAT_YVYU and PIPE_FORMAT_R8B8_R8G8 Signed-off-by: Italo Nicola Reviewed-by: Daniel Stone Part-of: --- src/gallium/auxiliary/gallivm/lp_bld_format_yuv.c | 23 +++ src/gallium/frontends/dri/dri2.c | 16 ++ src/gallium/frontends/dri/dri_helpers.c | 4 + src/mesa/main/format_info.py | 2 +- src/mesa/main/formats.c | 1 + src/mesa/main/formats.csv | 1 + src/mesa/main/formats.h | 1 + src/mesa/state_tracker/st_atom_sampler.c | 2 + src/mesa/state_tracker/st_atom_texture.c | 4 +- src/mesa/state_tracker/st_cb_eglimage.c | 15 ++ src/mesa/state_tracker/st_program.c | 10 +- src/mesa/state_tracker/st_program.h | 9 + src/mesa/state_tracker/st_sampler_view.c | 2 + src/util/format/u_format.c | 1 + src/util/format/u_format.csv | 2 + src/util/format/u_format_table.py | 1 + src/util/format/u_format_tests.c | 4 + src/util/format/u_format_yuv.c | 216 ++++++++++++++++++++++ src/util/format/u_format_yuv.h | 24 +++ src/util/format/u_formats.h | 3 + 20 files changed, 336 insertions(+), 5 deletions(-) diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format_yuv.c b/src/gallium/auxiliary/gallivm/lp_bld_format_yuv.c index 5cc46af..8aec9cb 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_format_yuv.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_format_yuv.c @@ -398,6 +398,26 @@ yuyv_to_rgba_aos(struct gallivm_state *gallivm, return rgba; } +/** + * Convert from packed YUYV to <4n x i8> RGBA AoS + */ +static LLVMValueRef +yvyu_to_rgba_aos(struct gallivm_state *gallivm, + unsigned n, + LLVMValueRef packed, + LLVMValueRef i) +{ + LLVMValueRef y, u, v; + LLVMValueRef r, g, b; + LLVMValueRef rgba; + + /* YVYU is YUYV with U/V swapped */ + yuyv_to_yuv_soa(gallivm, n, packed, i, &y, &v, &u); + yuv_to_rgb_soa(gallivm, n, y, u, v, &r, &g, &b); + rgba = rgb_to_rgba_aos(gallivm, n, r, g, b); + + return rgba; +} /** * Convert from packed RG_BG to <4n x i8> RGBA AoS @@ -509,6 +529,9 @@ lp_build_fetch_subsampled_rgba_aos(struct gallivm_state *gallivm, case PIPE_FORMAT_YUYV: rgba = yuyv_to_rgba_aos(gallivm, n, packed, i); break; + case PIPE_FORMAT_YVYU: + rgba = yvyu_to_rgba_aos(gallivm, n, packed, i); + break; case PIPE_FORMAT_R8G8_B8G8_UNORM: rgba = rgbg_to_rgba_aos(gallivm, n, packed, i); break; diff --git a/src/gallium/frontends/dri/dri2.c b/src/gallium/frontends/dri/dri2.c index 1983b0b..e268897 100644 --- a/src/gallium/frontends/dri/dri2.c +++ b/src/gallium/frontends/dri/dri2.c @@ -878,6 +878,15 @@ static const struct dri2_format_mapping r8g8_r8b8_mapping = { { 0, 1, 0, __DRI_IMAGE_FORMAT_ARGB8888 } } }; +static const struct dri2_format_mapping r8b8_r8g8_mapping = { + DRM_FORMAT_YVYU, + __DRI_IMAGE_FORMAT_NONE, + __DRI_IMAGE_COMPONENTS_Y_XUXV, + PIPE_FORMAT_R8B8_R8G8_UNORM, 2, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88 }, + { 0, 1, 0, __DRI_IMAGE_FORMAT_ARGB8888 } } +}; + static const struct dri2_format_mapping g8r8_b8r8_mapping = { DRM_FORMAT_UYVY, __DRI_IMAGE_FORMAT_NONE, @@ -936,6 +945,13 @@ dri2_create_image_from_winsys(__DRIscreen *_screen, tex_usage |= PIPE_BIND_SAMPLER_VIEW; } + if (!tex_usage && map->pipe_format == PIPE_FORMAT_YVYU && + pscreen->is_format_supported(pscreen, PIPE_FORMAT_R8B8_R8G8_UNORM, + screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) { + map = &r8b8_r8g8_mapping; + tex_usage |= PIPE_BIND_SAMPLER_VIEW; + } + if (!tex_usage && map->pipe_format == PIPE_FORMAT_UYVY && pscreen->is_format_supported(pscreen, PIPE_FORMAT_G8R8_B8R8_UNORM, screen->target, 0, 0, PIPE_BIND_SAMPLER_VIEW)) { diff --git a/src/gallium/frontends/dri/dri_helpers.c b/src/gallium/frontends/dri/dri_helpers.c index c30a026..8ac9587 100644 --- a/src/gallium/frontends/dri/dri_helpers.c +++ b/src/gallium/frontends/dri/dri_helpers.c @@ -639,6 +639,10 @@ static const struct dri2_format_mapping dri2_format_table[] = { __DRI_IMAGE_COMPONENTS_Y_XUXV, PIPE_FORMAT_YUYV, 2, { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88 }, { 0, 1, 0, __DRI_IMAGE_FORMAT_ARGB8888 } } }, + { DRM_FORMAT_YVYU, __DRI_IMAGE_FORMAT_NONE, + __DRI_IMAGE_COMPONENTS_Y_XUXV, PIPE_FORMAT_YVYU, 2, + { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88 }, + { 0, 1, 0, __DRI_IMAGE_FORMAT_ARGB8888 } } }, { DRM_FORMAT_UYVY, __DRI_IMAGE_FORMAT_NONE, __DRI_IMAGE_COMPONENTS_Y_UXVX, PIPE_FORMAT_UYVY, 2, { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88 }, diff --git a/src/mesa/main/format_info.py b/src/mesa/main/format_info.py index 37b46a2..7df0b11 100644 --- a/src/mesa/main/format_info.py +++ b/src/mesa/main/format_info.py @@ -126,7 +126,7 @@ def get_channel_bits(fmat, chan_name): return bits if fmat.has_channel(chan_name) else 0 elif fmat.layout == 'atc': return 8 if fmat.has_channel(chan_name) else 0 - elif fmat.layout == 'other' and ('RG_RB' in fmat.name or 'GR_BR' in fmat.name): + elif fmat.layout == 'other' and any(s in fmat.name for s in {'RG_RB', 'GR_BR', 'RB_RG'}): return 8 if fmat.has_channel(chan_name) else 0 else: assert False diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c index 9c58e53..e71d7d2 100644 --- a/src/mesa/main/formats.c +++ b/src/mesa/main/formats.c @@ -1020,6 +1020,7 @@ _mesa_uncompressed_format_to_type_and_comps(mesa_format format, case MESA_FORMAT_YCBCR: case MESA_FORMAT_YCBCR_REV: case MESA_FORMAT_RG_RB_UNORM8: + case MESA_FORMAT_RB_RG_UNORM8: case MESA_FORMAT_GR_BR_UNORM8: *datatype = GL_UNSIGNED_SHORT; *comps = 2; diff --git a/src/mesa/main/formats.csv b/src/mesa/main/formats.csv index 21cdea2..70c041c 100644 --- a/src/mesa/main/formats.csv +++ b/src/mesa/main/formats.csv @@ -94,6 +94,7 @@ MESA_FORMAT_YCBCR , other , 1, 1, 1, x16 , , , MESA_FORMAT_YCBCR_REV , other , 1, 1, 1, x16 , , , , xyzw, yuv MESA_FORMAT_RG_RB_UNORM8 , other , 2, 1, 1, x16 , , , , xyz1, rgb +MESA_FORMAT_RB_RG_UNORM8 , other , 2, 1, 1, x16 , , , , xyz1, rgb MESA_FORMAT_GR_BR_UNORM8 , other , 2, 1, 1, x16 , , , , xyz1, rgb # Array normalized formats diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h index 0f5e01a..c55068b 100644 --- a/src/mesa/main/formats.h +++ b/src/mesa/main/formats.h @@ -387,6 +387,7 @@ typedef enum pipe_format mesa_format; #define MESA_FORMAT_YCBCR PIPE_FORMAT_UYVY #define MESA_FORMAT_YCBCR_REV PIPE_FORMAT_YUYV #define MESA_FORMAT_RG_RB_UNORM8 PIPE_FORMAT_R8G8_R8B8_UNORM +#define MESA_FORMAT_RB_RG_UNORM8 PIPE_FORMAT_R8B8_R8G8_UNORM #define MESA_FORMAT_GR_BR_UNORM8 PIPE_FORMAT_G8R8_B8R8_UNORM #define MESA_FORMAT_A_UNORM8 PIPE_FORMAT_A8_UNORM #define MESA_FORMAT_A_UNORM16 PIPE_FORMAT_A16_UNORM diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c index 5725e1c..87e7d26 100644 --- a/src/mesa/state_tracker/st_atom_sampler.c +++ b/src/mesa/state_tracker/st_atom_sampler.c @@ -282,8 +282,10 @@ update_shader_samplers(struct st_context *st, case PIPE_FORMAT_Y212: case PIPE_FORMAT_Y216: case PIPE_FORMAT_YUYV: + case PIPE_FORMAT_YVYU: case PIPE_FORMAT_UYVY: if (stObj->pt->format == PIPE_FORMAT_R8G8_R8B8_UNORM || + stObj->pt->format == PIPE_FORMAT_R8B8_R8G8_UNORM || stObj->pt->format == PIPE_FORMAT_G8R8_B8R8_UNORM) { /* no additional views needed */ break; diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c index e74c5ef..62858a4 100644 --- a/src/mesa/state_tracker/st_atom_texture.c +++ b/src/mesa/state_tracker/st_atom_texture.c @@ -220,7 +220,9 @@ st_get_sampler_views(struct st_context *st, pipe->create_sampler_view(pipe, stObj->pt->next->next, &tmpl); break; case PIPE_FORMAT_YUYV: - if (stObj->pt->format == PIPE_FORMAT_R8G8_R8B8_UNORM) + case PIPE_FORMAT_YVYU: + if (stObj->pt->format == PIPE_FORMAT_R8G8_R8B8_UNORM || + stObj->pt->format == PIPE_FORMAT_R8B8_R8G8_UNORM) /* no additional views needed */ break; diff --git a/src/mesa/state_tracker/st_cb_eglimage.c b/src/mesa/state_tracker/st_cb_eglimage.c index 2a3a59b..a132f8a 100644 --- a/src/mesa/state_tracker/st_cb_eglimage.c +++ b/src/mesa/state_tracker/st_cb_eglimage.c @@ -114,6 +114,17 @@ is_format_supported(struct pipe_screen *screen, enum pipe_format format, PIPE_TEXTURE_2D, nr_samples, nr_storage_samples, usage)); break; + case PIPE_FORMAT_YVYU: + supported = screen->is_format_supported(screen, PIPE_FORMAT_R8B8_R8G8_UNORM, + PIPE_TEXTURE_2D, nr_samples, + nr_storage_samples, usage) || + (screen->is_format_supported(screen, PIPE_FORMAT_RG88_UNORM, + PIPE_TEXTURE_2D, nr_samples, + nr_storage_samples, usage) && + screen->is_format_supported(screen, PIPE_FORMAT_BGRA8888_UNORM, + PIPE_TEXTURE_2D, nr_samples, + nr_storage_samples, usage)); + break; case PIPE_FORMAT_UYVY: supported = screen->is_format_supported(screen, PIPE_FORMAT_G8R8_B8R8_UNORM, PIPE_TEXTURE_2D, nr_samples, @@ -354,10 +365,14 @@ st_bind_egl_image(struct gl_context *ctx, texObj->RequiredTextureImageUnits = 3; break; case PIPE_FORMAT_YUYV: + case PIPE_FORMAT_YVYU: case PIPE_FORMAT_UYVY: if (stimg->texture->format == PIPE_FORMAT_R8G8_R8B8_UNORM) { texFormat = MESA_FORMAT_RG_RB_UNORM8; texObj->RequiredTextureImageUnits = 1; + } else if (stimg->texture->format == PIPE_FORMAT_R8B8_R8G8_UNORM) { + texFormat = MESA_FORMAT_RB_RG_UNORM8; + texObj->RequiredTextureImageUnits = 1; } else if (stimg->texture->format == PIPE_FORMAT_G8R8_B8R8_UNORM) { texFormat = MESA_FORMAT_GR_BR_UNORM8; texObj->RequiredTextureImageUnits = 1; diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index e1c32a4..ee78aa6 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -1002,8 +1002,9 @@ st_create_fp_variant(struct st_context *st, if (unlikely(key->external.lower_nv12 || key->external.lower_nv21 || key->external.lower_iyuv || key->external.lower_xy_uxvx || key->external.lower_yx_xuxv || - key->external.lower_ayuv || key->external.lower_xyuv || - key->external.lower_yuv || key->external.lower_yu_yv || + key->external.lower_yx_xvxu || key->external.lower_ayuv || + key->external.lower_xyuv || key->external.lower_yuv || + key->external.lower_yu_yv || key->external.lower_yv_yu || key->external.lower_y41x)) { st_nir_lower_samplers(st->screen, state.ir.nir, @@ -1015,10 +1016,12 @@ st_create_fp_variant(struct st_context *st, options.lower_y_u_v_external = key->external.lower_iyuv; options.lower_xy_uxvx_external = key->external.lower_xy_uxvx; options.lower_yx_xuxv_external = key->external.lower_yx_xuxv; + options.lower_yx_xvxu_external = key->external.lower_yx_xvxu; options.lower_ayuv_external = key->external.lower_ayuv; options.lower_xyuv_external = key->external.lower_xyuv; options.lower_yuv_external = key->external.lower_yuv; options.lower_yu_yv_external = key->external.lower_yu_yv; + options.lower_yv_yu_external = key->external.lower_yv_yu; options.lower_y41x_external = key->external.lower_y41x; options.bt709_external = key->external.bt709; options.bt2020_external = key->external.bt2020; @@ -1039,7 +1042,8 @@ st_create_fp_variant(struct st_context *st, NIR_PASS_V(state.ir.nir, st_nir_lower_tex_src_plane, ~fp->SamplersUsed, key->external.lower_nv12 | key->external.lower_nv21 | - key->external.lower_xy_uxvx | key->external.lower_yx_xuxv, + key->external.lower_xy_uxvx | key->external.lower_yx_xuxv | + key->external.lower_yx_xvxu, key->external.lower_iyuv); finalize = true; } diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index 44c1ccb..61af1d3 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -52,10 +52,12 @@ struct st_external_sampler_key GLuint lower_iyuv; /**< bitmask of 3 plane YUV samplers */ GLuint lower_xy_uxvx; /**< bitmask of 2 plane YUV samplers */ GLuint lower_yx_xuxv; /**< bitmask of 2 plane YUV samplers */ + GLuint lower_yx_xvxu; /**< bitmask of 2 plane YUV samplers */ GLuint lower_ayuv; GLuint lower_xyuv; GLuint lower_yuv; GLuint lower_yu_yv; + GLuint lower_yv_yu; GLuint lower_y41x; GLuint bt709; GLuint bt2020; @@ -121,6 +123,13 @@ st_get_external_sampler_key(struct st_context *st, struct gl_program *prog) } key.lower_xy_uxvx |= (1 << unit); break; + case PIPE_FORMAT_YVYU: + if (stObj->pt->format == PIPE_FORMAT_R8B8_R8G8_UNORM) { + key.lower_yv_yu |= (1 << unit); + break; + } + key.lower_yx_xvxu |= (1 << unit); + break; case PIPE_FORMAT_AYUV: key.lower_ayuv |= (1 << unit); break; diff --git a/src/mesa/state_tracker/st_sampler_view.c b/src/mesa/state_tracker/st_sampler_view.c index d39341a..9f66112 100644 --- a/src/mesa/state_tracker/st_sampler_view.c +++ b/src/mesa/state_tracker/st_sampler_view.c @@ -414,8 +414,10 @@ st_get_sampler_view_format(const struct st_context *st, format = PIPE_FORMAT_R16G16B16A16_UNORM; break; case PIPE_FORMAT_YUYV: + case PIPE_FORMAT_YVYU: case PIPE_FORMAT_UYVY: if (texObj->pt->format == PIPE_FORMAT_R8G8_R8B8_UNORM || + texObj->pt->format == PIPE_FORMAT_R8B8_R8G8_UNORM || texObj->pt->format == PIPE_FORMAT_G8R8_B8R8_UNORM) { format = texObj->pt->format; break; diff --git a/src/util/format/u_format.c b/src/util/format/u_format.c index 59dba8b..c34b023 100644 --- a/src/util/format/u_format.c +++ b/src/util/format/u_format.c @@ -632,6 +632,7 @@ util_format_fits_8unorm(const struct util_format_description *format_desc) case PIPE_FORMAT_R1_UNORM: case PIPE_FORMAT_UYVY: case PIPE_FORMAT_YUYV: + case PIPE_FORMAT_YVYU: case PIPE_FORMAT_R8G8_B8G8_UNORM: case PIPE_FORMAT_G8R8_G8B8_UNORM: return true; diff --git a/src/util/format/u_format.csv b/src/util/format/u_format.csv index ef00ec7..e0668cd 100644 --- a/src/util/format/u_format.csv +++ b/src/util/format/u_format.csv @@ -179,6 +179,7 @@ PIPE_FORMAT_Z24_UNORM_S8_UINT_AS_R8G8B8A8 , plain, 1, 1, 1, un8 , un8 , un8 , un PIPE_FORMAT_UYVY , subsampled, 2, 1, 1, un8 , un8 , un8 , un8 , xyz1, yuv # http://www.fourcc.org/yuv.php#YUYV (a.k.a http://www.fourcc.org/yuv.php#YUY2) PIPE_FORMAT_YUYV , subsampled, 2, 1, 1, un8 , un8 , un8 , un8 , xyz1, yuv +PIPE_FORMAT_YVYU , subsampled, 2, 1, 1, un8 , un8 , un8 , un8 , xyz1, yuv PIPE_FORMAT_AYUV , other, 4, 4, 1, un8 , , , , xyzw, yuv PIPE_FORMAT_XYUV , other, 4, 4, 1, un8 , , , , xyz1, yuv @@ -188,6 +189,7 @@ PIPE_FORMAT_R8G8_B8G8_UNORM , subsampled, 2, 1, 1, x32 , , , PIPE_FORMAT_G8R8_G8B8_UNORM , subsampled, 2, 1, 1, x32 , , , , xyz1, rgb PIPE_FORMAT_G8R8_B8R8_UNORM , subsampled, 2, 1, 1, x32 , , , , zyx1, rgb PIPE_FORMAT_R8G8_R8B8_UNORM , subsampled, 2, 1, 1, x32 , , , , zyx1, rgb +PIPE_FORMAT_R8B8_R8G8_UNORM , subsampled, 2, 1, 1, x32 , , , , yxz1, rgb # some special formats not fitting anywhere else PIPE_FORMAT_R11G11B10_FLOAT , other, 1, 1, 1, f11 , f11 , f10 , , xyz1, rgb diff --git a/src/util/format/u_format_table.py b/src/util/format/u_format_table.py index 667c271..b14b01c 100644 --- a/src/util/format/u_format_table.py +++ b/src/util/format/u_format_table.py @@ -100,6 +100,7 @@ def has_access(format): 'xyuv', 'ayuv', 'r8g8_r8b8_unorm', + 'r8b8_r8g8_unorm', 'g8r8_b8r8_unorm', 'g8r8_g8b8_unorm', 'y8_400_unorm', diff --git a/src/util/format/u_format_tests.c b/src/util/format/u_format_tests.c index 3f52429..7a01151 100644 --- a/src/util/format/u_format_tests.c +++ b/src/util/format/u_format_tests.c @@ -443,6 +443,10 @@ util_format_test_cases[] = {PIPE_FORMAT_YUYV, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0xeb, 0x80, 0x10, 0x80), UNPACKED_2x1(1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0)}, {PIPE_FORMAT_YUYV, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x10, 0x80, 0xeb, 0x80), UNPACKED_2x1(0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0)}, + {PIPE_FORMAT_YVYU, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x10, 0x80, 0x10, 0x80), UNPACKED_2x1(0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0)}, + {PIPE_FORMAT_YVYU, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0xeb, 0x80, 0x10, 0x80), UNPACKED_2x1(1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0)}, + {PIPE_FORMAT_YVYU, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x10, 0x80, 0xeb, 0x80), UNPACKED_2x1(0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0)}, + /* * Compressed formats */ diff --git a/src/util/format/u_format_yuv.c b/src/util/format/u_format_yuv.c index 80022e4..cbccbc8 100644 --- a/src/util/format/u_format_yuv.c +++ b/src/util/format/u_format_yuv.c @@ -751,6 +751,53 @@ util_format_yuyv_unpack_rgba_float(void *restrict dst_row, unsigned dst_stride, } } +void +util_format_yvyu_unpack_rgba_float(void *restrict dst_row, unsigned dst_stride, + const uint8_t *restrict src_row, unsigned src_stride, + unsigned width, unsigned height) +{ + unsigned x, y; + + for (y = 0; y < height; y += 1) { + float *dst = dst_row; + const uint32_t *src = (const uint32_t *)src_row; + uint32_t value; + uint8_t y0, y1, u, v; + + for (x = 0; x + 1 < width; x += 2) { + value = util_cpu_to_le32(*src++); + + y0 = (value >> 0) & 0xff; + u = (value >> 24) & 0xff; + y1 = (value >> 16) & 0xff; + v = (value >> 8) & 0xff; + + util_format_yuv_to_rgb_float(y0, u, v, &dst[0], &dst[1], &dst[2]); + dst[3] = 1.0f; /* a */ + dst += 4; + + util_format_yuv_to_rgb_float(y1, u, v, &dst[0], &dst[1], &dst[2]); + dst[3] = 1.0f; /* a */ + dst += 4; + } + + if (x < width) { + value = util_cpu_to_le32(*src); + + y0 = (value >> 0) & 0xff; + u = (value >> 24) & 0xff; + y1 = (value >> 16) & 0xff; + v = (value >> 8) & 0xff; + + util_format_yuv_to_rgb_float(y0, u, v, &dst[0], &dst[1], &dst[2]); + dst[3] = 1.0f; /* a */ + } + + src_row = (uint8_t *)src_row + src_stride; + dst_row = (uint8_t *)dst_row + dst_stride; + } +} + void util_format_yuyv_unpack_rgba_8unorm(uint8_t *restrict dst_row, unsigned dst_stride, @@ -799,6 +846,53 @@ util_format_yuyv_unpack_rgba_8unorm(uint8_t *restrict dst_row, unsigned dst_stri } } +void +util_format_yvyu_unpack_rgba_8unorm(uint8_t *restrict dst_row, unsigned dst_stride, + const uint8_t *restrict src_row, unsigned src_stride, + unsigned width, unsigned height) +{ + unsigned x, y; + + for (y = 0; y < height; y += 1) { + uint8_t *dst = dst_row; + const uint32_t *src = (const uint32_t *)src_row; + uint32_t value; + uint8_t y0, y1, u, v; + + for (x = 0; x + 1 < width; x += 2) { + value = util_cpu_to_le32(*src++); + + y0 = (value >> 0) & 0xff; + v = (value >> 8) & 0xff; + y1 = (value >> 16) & 0xff; + u = (value >> 24) & 0xff; + + util_format_yuv_to_rgb_8unorm(y0, u, v, &dst[0], &dst[1], &dst[2]); + dst[3] = 0xff; /* a */ + dst += 4; + + util_format_yuv_to_rgb_8unorm(y1, u, v, &dst[0], &dst[1], &dst[2]); + dst[3] = 0xff; /* a */ + dst += 4; + } + + if (x < width) { + value = util_cpu_to_le32(*src); + + y0 = (value >> 0) & 0xff; + v = (value >> 8) & 0xff; + y1 = (value >> 16) & 0xff; + u = (value >> 24) & 0xff; + + util_format_yuv_to_rgb_8unorm(y0, u, v, &dst[0], &dst[1], &dst[2]); + dst[3] = 0xff; /* a */ + } + + src_row += src_stride/sizeof(*src_row); + dst_row += dst_stride/sizeof(*dst_row); + } +} + void util_format_yuyv_pack_rgba_float(uint8_t *restrict dst_row, unsigned dst_stride, @@ -852,6 +946,57 @@ util_format_yuyv_pack_rgba_float(uint8_t *restrict dst_row, unsigned dst_stride, } } +void +util_format_yvyu_pack_rgba_float(uint8_t *restrict dst_row, unsigned dst_stride, + const float *restrict src_row, unsigned src_stride, + unsigned width, unsigned height) +{ + unsigned x, y; + + for (y = 0; y < height; y += 1) { + const float *src = src_row; + uint32_t *dst = (uint32_t *)dst_row; + uint8_t y0, y1, u, v; + uint32_t value; + + for (x = 0; x + 1 < width; x += 2) { + uint8_t y0, y1, u0, u1, v0, v1, u, v; + + util_format_rgb_float_to_yuv(src[0], src[1], src[2], + &y0, &u0, &v0); + util_format_rgb_float_to_yuv(src[4], src[5], src[6], + &y1, &u1, &v1); + + u = (u0 + u1 + 1) >> 1; + v = (v0 + v1 + 1) >> 1; + + value = y0; + value |= (uint32_t)v << 8; + value |= (uint32_t)y1 << 16; + value |= (uint32_t)u << 24; + + *dst++ = util_le32_to_cpu(value); + + src += 8; + } + + if (x < width) { + util_format_rgb_float_to_yuv(src[0], src[1], src[2], + &y0, &u, &v); + y1 = 0; + + value = y0; + value |= (uint32_t)v << 8; + value |= (uint32_t)y1 << 16; + value |= (uint32_t)u << 24; + + *dst = util_le32_to_cpu(value); + } + + dst_row += dst_stride/sizeof(*dst_row); + src_row += src_stride/sizeof(*src_row); + } +} void util_format_yuyv_pack_rgba_8unorm(uint8_t *restrict dst_row, unsigned dst_stride, @@ -905,6 +1050,58 @@ util_format_yuyv_pack_rgba_8unorm(uint8_t *restrict dst_row, unsigned dst_stride } } +void +util_format_yvyu_pack_rgba_8unorm(uint8_t *restrict dst_row, unsigned dst_stride, + const uint8_t *restrict src_row, unsigned src_stride, + unsigned width, unsigned height) +{ + unsigned x, y; + + for (y = 0; y < height; y += 1) { + const uint8_t *src = src_row; + uint32_t *dst = (uint32_t *)dst_row; + uint8_t y0, y1, u, v; + uint32_t value; + + for (x = 0; x + 1 < width; x += 2) { + uint8_t y0, y1, u0, u1, v0, v1, u, v; + + util_format_rgb_8unorm_to_yuv(src[0], src[1], src[2], + &y0, &u0, &v0); + util_format_rgb_8unorm_to_yuv(src[4], src[5], src[6], + &y1, &u1, &v1); + + u = (u0 + u1 + 1) >> 1; + v = (v0 + v1 + 1) >> 1; + + value = y0; + value |= (uint32_t)v << 8; + value |= (uint32_t)y1 << 16; + value |= (uint32_t)u << 24; + + *dst++ = util_le32_to_cpu(value); + + src += 8; + } + + if (x < width) { + util_format_rgb_8unorm_to_yuv(src[0], src[1], src[2], + &y0, &u, &v); + y1 = 0; + + value = y0; + value |= (uint32_t)v << 8; + value |= (uint32_t)y1 << 16; + value |= (uint32_t)u << 24; + + *dst = util_le32_to_cpu(value); + } + + dst_row += dst_stride/sizeof(*dst_row); + src_row += src_stride/sizeof(*src_row); + } +} + void util_format_yuyv_fetch_rgba(void *restrict in_dst, const uint8_t *restrict src, @@ -924,3 +1121,22 @@ util_format_yuyv_fetch_rgba(void *restrict in_dst, const uint8_t *restrict src, dst[3] = 1.0f; } + +void +util_format_yvyu_fetch_rgba(void *restrict in_dst, const uint8_t *restrict src, + unsigned i, ASSERTED unsigned j) +{ + float *dst = in_dst; + uint8_t y, u, v; + + assert(i < 2); + assert(j < 1); + + y = src[0 + i*2]; + u = src[3]; + v = src[1]; + + util_format_yuv_to_rgb_float(y, u, v, &dst[0], &dst[1], &dst[2]); + + dst[3] = 1.0f; +} diff --git a/src/util/format/u_format_yuv.h b/src/util/format/u_format_yuv.h index d73527d..293df1b 100644 --- a/src/util/format/u_format_yuv.h +++ b/src/util/format/u_format_yuv.h @@ -171,6 +171,30 @@ util_format_yuyv_fetch_rgba(void *restrict dst, const uint8_t *restrict src, unsigned i, unsigned j); void +util_format_yvyu_unpack_rgba_float(void *restrict dst_row, unsigned dst_stride, + const uint8_t *restrict src_row, unsigned src_stride, + unsigned width, unsigned height); + +void +util_format_yvyu_unpack_rgba_8unorm(uint8_t *restrict dst_row, unsigned dst_stride, + const uint8_t *restrict src_row, unsigned src_stride, + unsigned width, unsigned height); + +void +util_format_yvyu_pack_rgba_float(uint8_t *restrict dst_row, unsigned dst_stride, + const float *restrict src_row, unsigned src_stride, + unsigned width, unsigned height); + +void +util_format_yvyu_pack_rgba_8unorm(uint8_t *restrict dst_row, unsigned dst_stride, + const uint8_t *restrict src_row, unsigned src_stride, + unsigned width, unsigned height); + +void +util_format_yvyu_fetch_rgba(void *restrict dst, const uint8_t *restrict src, + unsigned i, unsigned j); + +void util_format_r8g8_b8g8_unorm_unpack_rgba_float(void *restrict dst_row, unsigned dst_stride, const uint8_t *restrict src_row, unsigned src_stride, unsigned width, unsigned height); diff --git a/src/util/format/u_formats.h b/src/util/format/u_formats.h index 19c9b9a..32ea6bc 100644 --- a/src/util/format/u_formats.h +++ b/src/util/format/u_formats.h @@ -189,6 +189,7 @@ enum pipe_format { PIPE_FORMAT_L16_UNORM, /**< ushort luminance */ PIPE_FORMAT_UYVY, PIPE_FORMAT_YUYV, + PIPE_FORMAT_YVYU, PIPE_FORMAT_Z16_UNORM, PIPE_FORMAT_Z16_UNORM_S8_UINT, PIPE_FORMAT_Z32_UNORM, @@ -363,6 +364,7 @@ enum pipe_format { PIPE_FORMAT_ETC1_RGB8, PIPE_FORMAT_R8G8_R8B8_UNORM, + PIPE_FORMAT_R8B8_R8G8_UNORM, PIPE_FORMAT_G8R8_B8R8_UNORM, PIPE_FORMAT_R8G8B8X8_SNORM, @@ -630,6 +632,7 @@ pipe_format_to_chroma_format(enum pipe_format format) return PIPE_VIDEO_CHROMA_FORMAT_420; case PIPE_FORMAT_UYVY: case PIPE_FORMAT_YUYV: + case PIPE_FORMAT_YVYU: case PIPE_FORMAT_YV16: case PIPE_FORMAT_Y8_U8_V8_422_UNORM: case PIPE_FORMAT_Y8_U8V8_422_UNORM: -- 2.7.4