summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian König <deathsimple@vodafone.de>2012-02-27 16:07:51 +0100
committerChristian König <deathsimple@vodafone.de>2012-03-02 13:14:21 +0100
commitb90727bb241e4a04158d34aad078cb18e478fea7 (patch)
tree6b5bc8dbe12e79d0ea54524eabc196969367ad3e
parentd645dc65b6c5e7d46538e98208a703f0f7a5d20b (diff)
vl/compositor: add per vertex color suport
Used in subtitles, for example. Signed-off-by: Christian König <deathsimple@vodafone.de>
-rw-r--r--src/gallium/auxiliary/vl/vl_compositor.c111
-rw-r--r--src/gallium/auxiliary/vl/vl_compositor.h4
-rw-r--r--src/gallium/state_trackers/vdpau/mixer.c2
-rw-r--r--src/gallium/state_trackers/vdpau/output.c2
-rw-r--r--src/gallium/state_trackers/vdpau/presentation.c2
-rw-r--r--src/gallium/state_trackers/xvmc/surface.c2
6 files changed, 88 insertions, 35 deletions
diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c
index b0302980561..1e8d37f2be9 100644
--- a/src/gallium/auxiliary/vl/vl_compositor.c
+++ b/src/gallium/auxiliary/vl/vl_compositor.c
@@ -47,6 +47,7 @@ enum VS_OUTPUT
{
VS_O_VPOS,
VS_O_VTEX,
+ VS_O_COLOR,
VS_O_VTOP,
VS_O_VBOTTOM,
};
@@ -57,9 +58,9 @@ static void *
create_vert_shader(struct vl_compositor *c)
{
struct ureg_program *shader;
- struct ureg_src vpos, vtex;
+ struct ureg_src vpos, vtex, color;
struct ureg_dst tmp;
- struct ureg_dst o_vpos, o_vtex;
+ struct ureg_dst o_vpos, o_vtex, o_color;
struct ureg_dst o_vtop, o_vbottom;
shader = ureg_create(TGSI_PROCESSOR_VERTEX);
@@ -68,19 +69,37 @@ create_vert_shader(struct vl_compositor *c)
vpos = ureg_DECL_vs_input(shader, 0);
vtex = ureg_DECL_vs_input(shader, 1);
+ color = ureg_DECL_vs_input(shader, 2);
tmp = ureg_DECL_temporary(shader);
o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS);
o_vtex = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX);
+ o_color = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, VS_O_COLOR);
o_vtop = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTOP);
o_vbottom = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_VBOTTOM);
/*
* o_vpos = vpos
* o_vtex = vtex
+ * o_color = color
*/
ureg_MOV(shader, o_vpos, vpos);
ureg_MOV(shader, o_vtex, vtex);
+ ureg_MOV(shader, o_color, color);
+ /*
+ * tmp.x = vtex.w / 2
+ * tmp.y = vtex.w / 4
+ *
+ * o_vtop.x = vtex.x
+ * o_vtop.y = vtex.y * tmp.x + 0.25f
+ * o_vtop.z = vtex.y * tmp.y + 0.25f
+ * o_vtop.w = 1 / tmp.x
+ *
+ * o_vbottom.x = vtex.x
+ * o_vbottom.y = vtex.y * tmp.x - 0.25f
+ * o_vbottom.z = vtex.y * tmp.y - 0.25f
+ * o_vbottom.w = 1 / tmp.y
+ */
ureg_MUL(shader, ureg_writemask(tmp, TGSI_WRITEMASK_X),
ureg_scalar(vtex, TGSI_SWIZZLE_W), ureg_imm1f(shader, 0.5f));
ureg_MUL(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y),
@@ -295,22 +314,24 @@ static void *
create_frag_shader_rgba(struct vl_compositor *c)
{
struct ureg_program *shader;
- struct ureg_src tc;
- struct ureg_src sampler;
- struct ureg_dst fragment;
+ struct ureg_src tc, color, sampler;
+ struct ureg_dst texel, fragment;
shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
if (!shader)
return false;
tc = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_VTEX, TGSI_INTERPOLATE_LINEAR);
+ color = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_COLOR, VS_O_COLOR, TGSI_INTERPOLATE_LINEAR);
sampler = ureg_DECL_sampler(shader, 0);
+ texel = ureg_DECL_temporary(shader);
fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
/*
* fragment = tex(tc, sampler)
*/
- ureg_TEX(shader, fragment, TGSI_TEXTURE_2D, tc, sampler);
+ ureg_TEX(shader, texel, TGSI_TEXTURE_2D, tc, sampler);
+ ureg_MUL(shader, fragment, ureg_src(texel), color);
ureg_END(shader);
return ureg_create_shader_and_destroy(shader, c->pipe);
@@ -422,7 +443,7 @@ init_pipe_state(struct vl_compositor *c)
c->blend_add = c->pipe->create_blend_state(c->pipe, &blend);
memset(&rast, 0, sizeof rast);
- rast.flatshade = 1;
+ rast.flatshade = 0;
rast.front_ccw = 1;
rast.cull_face = PIPE_FACE_NONE;
rast.fill_back = PIPE_POLYGON_MODE_FILL;
@@ -495,14 +516,14 @@ create_vertex_buffer(struct vl_compositor *c)
static bool
init_buffers(struct vl_compositor *c)
{
- struct pipe_vertex_element vertex_elems[2];
+ struct pipe_vertex_element vertex_elems[3];
assert(c);
/*
* Create our vertex buffer and vertex buffer elements
*/
- c->vertex_buf.stride = sizeof(struct vertex2f) + sizeof(struct vertex4f);
+ c->vertex_buf.stride = sizeof(struct vertex2f) + sizeof(struct vertex4f) * 2;
c->vertex_buf.buffer_offset = 0;
create_vertex_buffer(c);
@@ -514,7 +535,11 @@ init_buffers(struct vl_compositor *c)
vertex_elems[1].instance_divisor = 0;
vertex_elems[1].vertex_buffer_index = 0;
vertex_elems[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
- c->vertex_elems_state = c->pipe->create_vertex_elements_state(c->pipe, 2, vertex_elems);
+ vertex_elems[2].src_offset = sizeof(struct vertex2f) + sizeof(struct vertex4f);
+ vertex_elems[2].instance_divisor = 0;
+ vertex_elems[2].vertex_buffer_index = 0;
+ vertex_elems[2].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ c->vertex_elems_state = c->pipe->create_vertex_elements_state(c->pipe, 3, vertex_elems);
return true;
}
@@ -574,24 +599,40 @@ gen_rect_verts(struct vertex2f *vb, struct vl_compositor_layer *layer)
vb[ 1].x = layer->src.tl.x;
vb[ 1].y = layer->src.tl.y;
vb[ 2] = layer->zw;
-
- vb[ 3].x = layer->dst.br.x;
- vb[ 3].y = layer->dst.tl.y;
- vb[ 4].x = layer->src.br.x;
- vb[ 4].y = layer->src.tl.y;
- vb[ 5] = layer->zw;
-
- vb[ 6].x = layer->dst.br.x;
- vb[ 6].y = layer->dst.br.y;
- vb[ 7].x = layer->src.br.x;
- vb[ 7].y = layer->src.br.y;
- vb[ 8] = layer->zw;
-
- vb[ 9].x = layer->dst.tl.x;
- vb[ 9].y = layer->dst.br.y;
- vb[10].x = layer->src.tl.x;
- vb[10].y = layer->src.br.y;
- vb[11] = layer->zw;
+ vb[ 3].x = layer->colors[0].x;
+ vb[ 3].y = layer->colors[0].y;
+ vb[ 4].x = layer->colors[0].z;
+ vb[ 4].y = layer->colors[0].w;
+
+ vb[ 5].x = layer->dst.br.x;
+ vb[ 5].y = layer->dst.tl.y;
+ vb[ 6].x = layer->src.br.x;
+ vb[ 6].y = layer->src.tl.y;
+ vb[ 7] = layer->zw;
+ vb[ 8].x = layer->colors[1].x;
+ vb[ 8].y = layer->colors[1].y;
+ vb[ 9].x = layer->colors[1].z;
+ vb[ 9].y = layer->colors[1].w;
+
+ vb[10].x = layer->dst.br.x;
+ vb[10].y = layer->dst.br.y;
+ vb[11].x = layer->src.br.x;
+ vb[11].y = layer->src.br.y;
+ vb[12] = layer->zw;
+ vb[13].x = layer->colors[2].x;
+ vb[13].y = layer->colors[2].y;
+ vb[14].x = layer->colors[2].z;
+ vb[14].y = layer->colors[2].w;
+
+ vb[15].x = layer->dst.tl.x;
+ vb[15].y = layer->dst.br.y;
+ vb[16].x = layer->src.tl.x;
+ vb[16].y = layer->src.br.y;
+ vb[17] = layer->zw;
+ vb[18].x = layer->colors[3].x;
+ vb[18].y = layer->colors[3].y;
+ vb[19].x = layer->colors[3].z;
+ vb[19].y = layer->colors[3].w;
}
static INLINE struct u_rect
@@ -638,7 +679,7 @@ gen_vertex_data(struct vl_compositor *c, struct vl_compositor_state *s, struct u
if (s->used_layers & (1 << i)) {
struct vl_compositor_layer *layer = &s->layers[i];
gen_rect_verts(vb, layer);
- vb += 12;
+ vb += 20;
if (dirty && layer->clearing) {
struct u_rect drawn = calc_drawn_area(s, layer);
@@ -728,11 +769,14 @@ vl_compositor_clear_layers(struct vl_compositor_state *s)
s->used_layers = 0;
for ( i = 0; i < VL_COMPOSITOR_MAX_LAYERS; ++i) {
+ struct vertex4f v_one = { 1.0f, 1.0f, 1.0f, 1.0f };
s->layers[i].clearing = i ? false : true;
s->layers[i].blend = NULL;
s->layers[i].fs = NULL;
for ( j = 0; j < 3; j++)
pipe_sampler_view_reference(&s->layers[i].sampler_views[j], NULL);
+ for ( j = 0; j < 4; ++j)
+ s->layers[i].colors[j] = v_one;
}
}
@@ -895,8 +939,11 @@ vl_compositor_set_rgba_layer(struct vl_compositor_state *s,
unsigned layer,
struct pipe_sampler_view *rgba,
struct u_rect *src_rect,
- struct u_rect *dst_rect)
+ struct u_rect *dst_rect,
+ struct vertex4f *colors)
{
+ unsigned i;
+
assert(s && c && rgba);
assert(layer < VL_COMPOSITOR_MAX_LAYERS);
@@ -912,6 +959,10 @@ vl_compositor_set_rgba_layer(struct vl_compositor_state *s,
calc_src_and_dst(&s->layers[layer], rgba->texture->width0, rgba->texture->height0,
src_rect ? *src_rect : default_rect(&s->layers[layer]),
dst_rect ? *dst_rect : default_rect(&s->layers[layer]));
+
+ if (colors)
+ for (i = 0; i < 4; ++i)
+ s->layers[layer].colors[i] = colors[i];
}
void
diff --git a/src/gallium/auxiliary/vl/vl_compositor.h b/src/gallium/auxiliary/vl/vl_compositor.h
index f998a2e081c..f86a3f5f8db 100644
--- a/src/gallium/auxiliary/vl/vl_compositor.h
+++ b/src/gallium/auxiliary/vl/vl_compositor.h
@@ -65,6 +65,7 @@ struct vl_compositor_layer
struct vertex2f tl, br;
} src, dst;
struct vertex2f zw;
+ struct vertex4f colors[4];
};
struct vl_compositor_state
@@ -207,7 +208,8 @@ vl_compositor_set_rgba_layer(struct vl_compositor_state *state,
unsigned layer,
struct pipe_sampler_view *rgba,
struct u_rect *src_rect,
- struct u_rect *dst_rect);
+ struct u_rect *dst_rect,
+ struct vertex4f *colors);
/*@}*/
diff --git a/src/gallium/state_trackers/vdpau/mixer.c b/src/gallium/state_trackers/vdpau/mixer.c
index ead9323eb8f..066d60974f1 100644
--- a/src/gallium/state_trackers/vdpau/mixer.c
+++ b/src/gallium/state_trackers/vdpau/mixer.c
@@ -244,7 +244,7 @@ VdpStatus vlVdpVideoMixerRender(VdpVideoMixer mixer,
if (!bg)
return VDP_STATUS_INVALID_HANDLE;
vl_compositor_set_rgba_layer(&vmixer->cstate, compositor, layer++, bg->sampler_view,
- RectToPipe(background_source_rect, &src_rect), NULL);
+ RectToPipe(background_source_rect, &src_rect), NULL, NULL);
}
vl_compositor_clear_layers(&vmixer->cstate);
diff --git a/src/gallium/state_trackers/vdpau/output.c b/src/gallium/state_trackers/vdpau/output.c
index 0ea502939c3..9113e2574e2 100644
--- a/src/gallium/state_trackers/vdpau/output.c
+++ b/src/gallium/state_trackers/vdpau/output.c
@@ -472,7 +472,7 @@ vlVdpOutputSurfaceRenderOutputSurface(VdpOutputSurface destination_surface,
vl_compositor_clear_layers(cstate);
vl_compositor_set_layer_blend(cstate, 0, blend, false);
vl_compositor_set_rgba_layer(cstate, compositor, 0, src_vlsurface->sampler_view,
- RectToPipe(source_rect, &src_rect), NULL);
+ RectToPipe(source_rect, &src_rect), NULL, NULL);
vl_compositor_set_dst_area(cstate, RectToPipe(destination_rect, &dst_rect));
vl_compositor_render(cstate, compositor, dst_vlsurface->surface, NULL);
diff --git a/src/gallium/state_trackers/vdpau/presentation.c b/src/gallium/state_trackers/vdpau/presentation.c
index 4d12bb3e700..55437d7c4bd 100644
--- a/src/gallium/state_trackers/vdpau/presentation.c
+++ b/src/gallium/state_trackers/vdpau/presentation.c
@@ -241,7 +241,7 @@ vlVdpPresentationQueueDisplay(VdpPresentationQueue presentation_queue,
dst_clip.y1 = clip_height ? clip_height : surf_draw->height;
vl_compositor_clear_layers(&pq->cstate);
- vl_compositor_set_rgba_layer(&pq->cstate, compositor, 0, surf->sampler_view, &src_rect, NULL);
+ vl_compositor_set_rgba_layer(&pq->cstate, compositor, 0, surf->sampler_view, &src_rect, NULL, NULL);
vl_compositor_set_dst_clip(&pq->cstate, &dst_clip);
vl_compositor_render(&pq->cstate, compositor, surf_draw, dirty_area);
diff --git a/src/gallium/state_trackers/xvmc/surface.c b/src/gallium/state_trackers/xvmc/surface.c
index 33b7dc2b164..fcf6e619166 100644
--- a/src/gallium/state_trackers/xvmc/surface.c
+++ b/src/gallium/state_trackers/xvmc/surface.c
@@ -423,7 +423,7 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
&subpicture_priv->src_rect, &subpicture_priv->dst_rect, true);
else
vl_compositor_set_rgba_layer(cstate, compositor, 1, subpicture_priv->sampler,
- &subpicture_priv->src_rect, &subpicture_priv->dst_rect);
+ &subpicture_priv->src_rect, &subpicture_priv->dst_rect, NULL);
surface_priv->subpicture = NULL;
subpicture_priv->surface = NULL;