summaryrefslogtreecommitdiff
path: root/src/gallium
diff options
context:
space:
mode:
authorZack Rusin <zackr@vmware.com>2009-10-23 16:18:10 -0400
committerZack Rusin <zackr@vmware.com>2009-10-26 08:15:48 -0400
commit6b8ce4cc4f9acdd9227e26a812dd911f45b623a5 (patch)
tree73a893f639b2d7eaa6ab48d45a4ce450c52f15a6 /src/gallium
parent5241b9568c1f97eb9aca8be5eb7a3ef659d9917f (diff)
st/xorg: add yuv shaders
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa_tgsi.c75
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa_tgsi.h8
-rw-r--r--src/gallium/state_trackers/xorg/xorg_xv.c16
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 3c90dab3c5..9503891701 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 0ea44fa137..b373d1357b 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 efac9275b2..6d057b4c75 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,