[PATCH 5/6] wined3d: Add support for I420 textures

Martin Storsjo martin at martin.st
Tue Feb 11 05:14:58 CST 2014


I420 is similar to YV12, but the chroma planes are
swapped.
---
 dlls/wined3d/arb_program_shader.c | 23 +++++++++++++++++++----
 dlls/wined3d/utils.c              | 13 +++++++++++++
 dlls/wined3d/wined3d_private.h    |  1 +
 include/wine/wined3d.h            |  1 +
 4 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index ddf64b0..779d8e5 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -6937,9 +6937,22 @@ static BOOL gen_planar_yuv_read(struct wined3d_shader_buffer *buffer, enum compl
     return TRUE;
 }
 
-static BOOL gen_yv12_read(struct wined3d_shader_buffer *buffer, GLenum textype, char *luminance)
+static BOOL gen_yv12_read(struct wined3d_shader_buffer *buffer, enum complex_fixup fixup,
+        GLenum textype, char *luminance)
 {
     const char *tex;
+    char chroma_first, chroma_second;
+
+    if (fixup == COMPLEX_FIXUP_YV12)
+    {
+        chroma_first = 'x';
+        chroma_second = 'y';
+    }
+    else
+    {
+        chroma_first = 'y';
+        chroma_second = 'x';
+    }
     static const float yv12_coef[]
             = {2.0f / 3.0f, 1.0f / 6.0f, (2.0f / 3.0f) + (1.0f / 6.0f), 1.0f / 3.0f};
 
@@ -7048,7 +7061,7 @@ static BOOL gen_yv12_read(struct wined3d_shader_buffer *buffer, GLenum textype,
     }
     /* Read the texture, put the result into the output register */
     shader_addline(buffer, "TEX temp, texcrd, texture[0], %s;\n", tex);
-    shader_addline(buffer, "MOV chroma.x, temp.w;\n");
+    shader_addline(buffer, "MOV chroma.%c, temp.w;\n", chroma_first);
 
     /* The other chroma value is 1/6th of the texture lower, from 5/6th to 6/6th
      * No need to clamp because we're just reusing the already clamped value from above
@@ -7059,7 +7072,7 @@ static BOOL gen_yv12_read(struct wined3d_shader_buffer *buffer, GLenum textype,
         shader_addline(buffer, "MAD texcrd.y, size.y, coef.w, texcrd.y;\n");
     }
     shader_addline(buffer, "TEX temp, texcrd, texture[0], %s;\n", tex);
-    shader_addline(buffer, "MOV chroma.y, temp.w;\n");
+    shader_addline(buffer, "MOV chroma.%c, temp.w;\n", chroma_second);
 
     /* Sample the luminance value. It is in the top 2/3rd of the texture, so scale the y coordinate.
      * Clamp the y coordinate to prevent the chroma values from bleeding into the sampled luminance
@@ -7430,7 +7443,8 @@ static GLuint gen_yuv_shader(struct arbfp_blit_priv *priv, const struct wined3d_
             break;
 
         case COMPLEX_FIXUP_YV12:
-            if (!gen_yv12_read(&buffer, textype, &luminance_component))
+        case COMPLEX_FIXUP_I420:
+            if (!gen_yv12_read(&buffer, yuv_fixup, textype, &luminance_component))
             {
                 shader_buffer_free(&buffer);
                 return 0;
@@ -7652,6 +7666,7 @@ static BOOL arbfp_blit_supported(const struct wined3d_gl_info *gl_info, enum win
         case COMPLEX_FIXUP_YUY2:
         case COMPLEX_FIXUP_UYVY:
         case COMPLEX_FIXUP_YV12:
+        case COMPLEX_FIXUP_I420:
         case COMPLEX_FIXUP_NV12:
         case COMPLEX_FIXUP_P8:
             TRACE("[OK]\n");
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 32426d9..c1d678b 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -51,6 +51,7 @@ static const struct wined3d_format_channels formats[] =
     {WINED3DFMT_UYVY,                       0,  0,  0,  0,   0,  0,  0,  0,    2,   0,     0},
     {WINED3DFMT_YUY2,                       0,  0,  0,  0,   0,  0,  0,  0,    2,   0,     0},
     {WINED3DFMT_YV12,                       0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
+    {WINED3DFMT_I420,                       0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
     {WINED3DFMT_NV12,                       0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
     {WINED3DFMT_DXT1,                       0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
     {WINED3DFMT_DXT2,                       0,  0,  0,  0,   0,  0,  0,  0,    1,   0,     0},
@@ -667,6 +668,10 @@ static const struct wined3d_format_texture_info format_texture_info[] =
             GL_ALPHA,                   GL_UNSIGNED_BYTE,                 0,
             WINED3DFMT_FLAG_FILTERING,
             WINED3D_GL_EXT_NONE,        NULL},
+    {WINED3DFMT_I420,                   GL_ALPHA,                         GL_ALPHA,                               0,
+            GL_ALPHA,                   GL_UNSIGNED_BYTE,                 0,
+            WINED3DFMT_FLAG_FILTERING,
+            WINED3D_GL_EXT_NONE,        NULL},
     {WINED3DFMT_NV12,                   GL_ALPHA,                         GL_ALPHA,                               0,
             GL_ALPHA,                   GL_UNSIGNED_BYTE,                 0,
             WINED3DFMT_FLAG_FILTERING,
@@ -1838,6 +1843,12 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_
     gl_info->formats[idx].height_scale.denominator = 2;
     gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_YV12);
 
+    idx = getFmtIdx(WINED3DFMT_I420);
+    gl_info->formats[idx].flags |= WINED3DFMT_FLAG_HEIGHT_SCALE;
+    gl_info->formats[idx].height_scale.numerator = 3;
+    gl_info->formats[idx].height_scale.denominator = 2;
+    gl_info->formats[idx].color_fixup = create_complex_fixup_desc(COMPLEX_FIXUP_I420);
+
     idx = getFmtIdx(WINED3DFMT_NV12);
     gl_info->formats[idx].flags |= WINED3DFMT_FLAG_HEIGHT_SCALE;
     gl_info->formats[idx].height_scale.numerator = 3;
@@ -2080,6 +2091,7 @@ const char *debug_d3dformat(enum wined3d_format_id format_id)
         FMT_TO_STR(WINED3DFMT_UYVY);
         FMT_TO_STR(WINED3DFMT_YUY2);
         FMT_TO_STR(WINED3DFMT_YV12);
+        FMT_TO_STR(WINED3DFMT_I420);
         FMT_TO_STR(WINED3DFMT_NV12);
         FMT_TO_STR(WINED3DFMT_DXT1);
         FMT_TO_STR(WINED3DFMT_DXT2);
@@ -2784,6 +2796,7 @@ static const char *debug_complex_fixup(enum complex_fixup fixup)
         WINED3D_TO_STR(COMPLEX_FIXUP_YUY2);
         WINED3D_TO_STR(COMPLEX_FIXUP_UYVY);
         WINED3D_TO_STR(COMPLEX_FIXUP_YV12);
+        WINED3D_TO_STR(COMPLEX_FIXUP_I420);
         WINED3D_TO_STR(COMPLEX_FIXUP_NV12);
         WINED3D_TO_STR(COMPLEX_FIXUP_P8);
 #undef WINED3D_TO_STR
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 9446bb8..0d34953 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -86,6 +86,7 @@ enum complex_fixup
     COMPLEX_FIXUP_YV12 = 3,
     COMPLEX_FIXUP_P8   = 4,
     COMPLEX_FIXUP_NV12 = 5,
+    COMPLEX_FIXUP_I420 = 6,
 };
 
 #include <pshpack2.h>
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 3496c5d..0849698 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -250,6 +250,7 @@ enum wined3d_format_id
     WINED3DFMT_R16                          = WINEMAKEFOURCC(' ','R','1','6'),
     WINED3DFMT_AL16                         = WINEMAKEFOURCC('A','L','1','6'),
     WINED3DFMT_NV12                         = WINEMAKEFOURCC('N','V','1','2'),
+    WINED3DFMT_I420                         = WINEMAKEFOURCC('I','4','2','0'),
 
     WINED3DFMT_FORCE_DWORD = 0xffffffff
 };
-- 
1.8.3.4 (Apple Git-47)




More information about the wine-patches mailing list