Mesa (master): st/xorg: add yuv shaders

Zack Rusin zack at kemper.freedesktop.org
Mon Oct 26 12:09:31 UTC 2009


Module: Mesa
Branch: master
Commit: 6b8ce4cc4f9acdd9227e26a812dd911f45b623a5
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=6b8ce4cc4f9acdd9227e26a812dd911f45b623a5

Author: Zack Rusin <zackr at vmware.com>
Date:   Fri Oct 23 16:18:10 2009 -0400

st/xorg: add yuv shaders

---

 src/gallium/state_trackers/xorg/xorg_exa_tgsi.c |   75 +++++++++++++++++++++-
 src/gallium/state_trackers/xorg/xorg_exa_tgsi.h |    8 +-
 src/gallium/state_trackers/xorg/xorg_xv.c       |   16 +++---
 3 files changed, 83 insertions(+), 16 deletions(-)

diff --git a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c
index 3c90dab..9503891 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c
@@ -278,6 +278,70 @@ create_vs(struct pipe_context *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) {
diff --git a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.h b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.h
index 0ea44fa..b373d13 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.h
+++ b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.h
@@ -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)
 };
diff --git a/src/gallium/state_trackers/xorg/xorg_xv.c b/src/gallium/state_trackers/xorg/xorg_xv.c
index efac927..6d057b4 100644
--- a/src/gallium/state_trackers/xorg/xorg_xv.c
+++ b/src/gallium/state_trackers/xorg/xorg_xv.c
@@ -20,16 +20,16 @@
 
 /* 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,




More information about the mesa-commit mailing list