st/xorg: add yuv shaders
authorZack Rusin <zackr@vmware.com>
Fri, 23 Oct 2009 20:18:10 +0000 (16:18 -0400)
committerZack Rusin <zackr@vmware.com>
Mon, 26 Oct 2009 12:15:48 +0000 (08:15 -0400)
src/gallium/state_trackers/xorg/xorg_exa_tgsi.c
src/gallium/state_trackers/xorg/xorg_exa_tgsi.h
src/gallium/state_trackers/xorg/xorg_xv.c

index 3c90dab3c5d9a3e9d65fc19bc6688d0f62dcf932..950389170184b5be5a86ea75f938106dd79bc24a 100644 (file)
@@ -277,6 +277,70 @@ create_vs(struct pipe_context *pipe,
    return ureg_create_shader_and_destroy(ureg, pipe);
 }
 
+static void *
+create_yuv_shader(struct pipe_context *pipe, struct ureg_program *ureg)
+{
+   struct ureg_src y_sampler, u_sampler, v_sampler;
+   struct ureg_src pos;
+   struct ureg_src matrow0, matrow1, matrow2;
+   struct ureg_dst y, u, v, rgb;
+   struct ureg_dst out = ureg_DECL_output(ureg,
+                                          TGSI_SEMANTIC_COLOR,
+                                          0);
+
+   pos = ureg_DECL_fs_input(ureg,
+                            TGSI_SEMANTIC_GENERIC,
+                            0,
+                            TGSI_INTERPOLATE_PERSPECTIVE);
+
+   rgb = ureg_DECL_temporary(ureg);
+   y = ureg_DECL_temporary(ureg);
+   u = ureg_DECL_temporary(ureg);
+   v = ureg_DECL_temporary(ureg);
+
+   y_sampler = ureg_DECL_sampler(ureg, 0);
+   u_sampler = ureg_DECL_sampler(ureg, 1);
+   v_sampler = ureg_DECL_sampler(ureg, 2);
+
+   matrow0 = ureg_DECL_constant(ureg, 0);
+   matrow1 = ureg_DECL_constant(ureg, 1);
+   matrow2 = ureg_DECL_constant(ureg, 2);
+
+   ureg_TEX(ureg, y,
+            TGSI_TEXTURE_2D, pos, y_sampler);
+   ureg_TEX(ureg, u,
+            TGSI_TEXTURE_2D, pos, u_sampler);
+   ureg_TEX(ureg, v,
+            TGSI_TEXTURE_2D, pos, v_sampler);
+
+   ureg_MUL(ureg, rgb,
+            ureg_scalar(ureg_src(y), TGSI_SWIZZLE_X),
+            matrow0);
+   ureg_MAD(ureg, rgb,
+            ureg_scalar(ureg_src(u), TGSI_SWIZZLE_X),
+            matrow1,
+            ureg_src(rgb));
+   ureg_MAD(ureg, rgb,
+            ureg_scalar(ureg_src(v), TGSI_SWIZZLE_X),
+            matrow2,
+            ureg_src(rgb));
+
+   /* rgb.a = 1; */
+   ureg_MOV(ureg, ureg_writemask(rgb, TGSI_WRITEMASK_W),
+            ureg_scalar(matrow0, TGSI_SWIZZLE_X));
+
+   ureg_MOV(ureg, out, ureg_src(rgb));
+
+   ureg_release_temporary(ureg, rgb);
+   ureg_release_temporary(ureg, y);
+   ureg_release_temporary(ureg, u);
+   ureg_release_temporary(ureg, v);
+
+   ureg_END(ureg);
+
+   return ureg_create_shader_and_destroy(ureg, pipe);
+}
+
 static void *
 create_fs(struct pipe_context *pipe,
           unsigned fs_traits)
@@ -293,13 +357,14 @@ create_fs(struct pipe_context *pipe,
    boolean is_lingrad = fs_traits & FS_LINGRAD_FILL;
    boolean is_radgrad = fs_traits & FS_RADGRAD_FILL;
    unsigned comp_alpha = fs_traits & FS_COMPONENT_ALPHA;
+   boolean is_yuv = fs_traits & FS_YUV;
 
    ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
    if (ureg == NULL)
       return 0;
 
-   /* it has to be either a fill or a composite op */
-   debug_assert(is_fill ^ is_composite);
+   /* it has to be either a fill, a composite op or a yuv conversion */
+   debug_assert((is_fill ^ is_composite) ^ is_yuv);
 
    out = ureg_DECL_output(ureg,
                           TGSI_SEMANTIC_COLOR,
@@ -311,8 +376,7 @@ create_fs(struct pipe_context *pipe,
                                      TGSI_SEMANTIC_GENERIC,
                                      0,
                                      TGSI_INTERPOLATE_PERSPECTIVE);
-   } else {
-      debug_assert(is_fill);
+   } else if (is_fill) {
       if (is_solid)
          src_input = ureg_DECL_fs_input(ureg,
                                         TGSI_SEMANTIC_COLOR,
@@ -323,6 +387,9 @@ create_fs(struct pipe_context *pipe,
                                         TGSI_SEMANTIC_POSITION,
                                         0,
                                         TGSI_INTERPOLATE_PERSPECTIVE);
+   } else {
+      debug_assert(is_yuv);
+      return create_yuv_shader(pipe, ureg);
    }
 
    if (has_mask) {
index 0ea44fa137ec9e186a502f961ce8516ec61d43a1..b373d1357bbfbf17d57e359cd6d6775120481386 100644 (file)
@@ -21,13 +21,13 @@ enum xorg_fs_traits {
    FS_SOLID_FILL       = 1 << 2,
    FS_LINGRAD_FILL     = 1 << 3,
    FS_RADGRAD_FILL     = 1 << 4,
+   FS_CA_FULL          = 1 << 5, /* src.rgba * mask.rgba */
+   FS_CA_SRCALPHA      = 1 << 6, /* src.aaaa * mask.rgba */
+   FS_YUV              = 1<<  7,
+
    FS_FILL             = (FS_SOLID_FILL |
                           FS_LINGRAD_FILL |
                           FS_RADGRAD_FILL),
-   /* src.rgba * mask.rgba */
-   FS_CA_FULL          = 1 << 5,
-   /* src.aaaa * mask.rgba */
-   FS_CA_SRCALPHA      = 1 << 6,
    FS_COMPONENT_ALPHA  = (FS_CA_FULL |
                           FS_CA_SRCALPHA)
 };
index efac9275b2659876be6381e804ce6957cf98e794..6d057b4c75f03c5681030c3852d0c329a3891a80 100644 (file)
 
 /* The ITU-R BT.601 conversion matrix for SDTV. */
 static const float bt_601[] = {
-    1.0, 0.0, 1.4075,
-    1.0, -0.3455, -0.7169,
-    1.0, 1.7790, 0.
+    1.0, 0.0, 1.4075,   0,
+    1.0, -0.3455, -0.7169, 0,
+    1.0, 1.7790, 0., 0,
 };
 
 /* The ITU-R BT.709 conversion matrix for HDTV. */
 static const float bt_709[] = {
-    1.0, 0.0, 1.581,
-    1.0, -0.1881, -0.47,
-    1.0, 1.8629, 0.
+    1.0, 0.0, 1.581, 0,
+    1.0, -0.1881, -0.47, 0,
+    1.0, 1.8629, 0., 0,
 };
 
 #define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
@@ -284,8 +284,8 @@ static void
 setup_video_constants(struct xorg_renderer *r, boolean hdtv)
 {
    struct pipe_context *pipe = r->pipe;
-   const int param_bytes = 9 * sizeof(float);
-   struct pipe_constant_buffer *cbuf = &r->vs_const_buffer;
+   const int param_bytes = 12 * sizeof(float);
+   struct pipe_constant_buffer *cbuf = &r->fs_const_buffer;
 
    pipe_buffer_reference(&cbuf->buffer, NULL);
    cbuf->buffer = pipe_buffer_create(pipe->screen, 16,