[g3dvl] cleanup headers and comments
[mesa.git] / src / gallium / auxiliary / vl / vl_compositor.c
1 /**************************************************************************
2 *
3 * Copyright 2009 Younes Manton.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 #include <assert.h>
29
30 #include <pipe/p_context.h>
31
32 #include <util/u_memory.h>
33 #include <util/u_draw.h>
34
35 #include <tgsi/tgsi_ureg.h>
36
37 #include "vl_csc.h"
38 #include "vl_types.h"
39 #include "vl_compositor.h"
40
41 typedef float csc_matrix[16];
42
43 static void *
44 create_vert_shader(struct vl_compositor *c)
45 {
46 struct ureg_program *shader;
47 struct ureg_src vpos, vtex;
48 struct ureg_dst o_vpos, o_vtex;
49
50 shader = ureg_create(TGSI_PROCESSOR_VERTEX);
51 if (!shader)
52 return false;
53
54 vpos = ureg_DECL_vs_input(shader, 0);
55 vtex = ureg_DECL_vs_input(shader, 1);
56 o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, 0);
57 o_vtex = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, 1);
58
59 /*
60 * o_vpos = vpos
61 * o_vtex = vtex
62 */
63 ureg_MOV(shader, o_vpos, vpos);
64 ureg_MOV(shader, o_vtex, vtex);
65
66 ureg_END(shader);
67
68 return ureg_create_shader_and_destroy(shader, c->pipe);
69 }
70
71 static void *
72 create_frag_shader_video_buffer(struct vl_compositor *c)
73 {
74 struct ureg_program *shader;
75 struct ureg_src tc;
76 struct ureg_src csc[3];
77 struct ureg_src sampler[3];
78 struct ureg_dst texel;
79 struct ureg_dst fragment;
80 unsigned i;
81
82 shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
83 if (!shader)
84 return false;
85
86 tc = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, 1, TGSI_INTERPOLATE_LINEAR);
87 for (i = 0; i < 3; ++i) {
88 csc[i] = ureg_DECL_constant(shader, i);
89 sampler[i] = ureg_DECL_sampler(shader, i);
90 }
91 texel = ureg_DECL_temporary(shader);
92 fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
93
94 /*
95 * texel.xyz = tex(tc, sampler[i])
96 * fragment = csc * texel
97 */
98 for (i = 0; i < 3; ++i)
99 ureg_TEX(shader, ureg_writemask(texel, TGSI_WRITEMASK_X << i), TGSI_TEXTURE_2D, tc, sampler[i]);
100
101 ureg_MOV(shader, ureg_writemask(texel, TGSI_WRITEMASK_W), ureg_imm1f(shader, 1.0f));
102
103 for (i = 0; i < 3; ++i)
104 ureg_DP4(shader, ureg_writemask(fragment, TGSI_WRITEMASK_X << i), csc[i], ureg_src(texel));
105
106 ureg_MOV(shader, ureg_writemask(fragment, TGSI_WRITEMASK_W), ureg_imm1f(shader, 1.0f));
107
108 ureg_release_temporary(shader, texel);
109 ureg_END(shader);
110
111 return ureg_create_shader_and_destroy(shader, c->pipe);
112 }
113
114 static void *
115 create_frag_shader_palette(struct vl_compositor *c)
116 {
117 struct ureg_program *shader;
118 struct ureg_src tc;
119 struct ureg_src sampler;
120 struct ureg_src palette;
121 struct ureg_dst texel;
122 struct ureg_dst fragment;
123
124 shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
125 if (!shader)
126 return false;
127
128 tc = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, 1, TGSI_INTERPOLATE_LINEAR);
129 sampler = ureg_DECL_sampler(shader, 0);
130 palette = ureg_DECL_sampler(shader, 1);
131 fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
132 texel = ureg_DECL_temporary(shader);
133
134 /*
135 * texel = tex(tc, sampler)
136 * fragment.xyz = tex(texel, palette)
137 * fragment.a = texel.a
138 */
139 ureg_TEX(shader, texel, TGSI_TEXTURE_2D, tc, sampler);
140 ureg_TEX(shader, fragment, TGSI_TEXTURE_1D, ureg_src(texel), palette);
141 ureg_MOV(shader, ureg_writemask(fragment, TGSI_WRITEMASK_W), ureg_src(texel));
142
143 ureg_release_temporary(shader, texel);
144 ureg_END(shader);
145
146 return ureg_create_shader_and_destroy(shader, c->pipe);
147 }
148
149 static void *
150 create_frag_shader_rgba(struct vl_compositor *c)
151 {
152 struct ureg_program *shader;
153 struct ureg_src tc;
154 struct ureg_src sampler;
155 struct ureg_dst fragment;
156
157 shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
158 if (!shader)
159 return false;
160
161 tc = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, 1, TGSI_INTERPOLATE_LINEAR);
162 sampler = ureg_DECL_sampler(shader, 0);
163 fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
164
165 /*
166 * fragment = tex(tc, sampler)
167 */
168 ureg_TEX(shader, fragment, TGSI_TEXTURE_2D, tc, sampler);
169 ureg_END(shader);
170
171 return ureg_create_shader_and_destroy(shader, c->pipe);
172 }
173
174 static bool
175 init_shaders(struct vl_compositor *c)
176 {
177 assert(c);
178
179 c->vs = create_vert_shader(c);
180 if (!c->vs) {
181 debug_printf("Unable to create vertex shader.\n");
182 return false;
183 }
184
185 c->fs_video_buffer = create_frag_shader_video_buffer(c);
186 if (!c->fs_video_buffer) {
187 debug_printf("Unable to create YCbCr-to-RGB fragment shader.\n");
188 return false;
189 }
190
191 c->fs_palette = create_frag_shader_palette(c);
192 if (!c->fs_palette) {
193 debug_printf("Unable to create Palette-to-RGB fragment shader.\n");
194 return false;
195 }
196
197 c->fs_rgba = create_frag_shader_rgba(c);
198 if (!c->fs_rgba) {
199 debug_printf("Unable to create RGB-to-RGB fragment shader.\n");
200 return false;
201 }
202
203 return true;
204 }
205
206 static void cleanup_shaders(struct vl_compositor *c)
207 {
208 assert(c);
209
210 c->pipe->delete_vs_state(c->pipe, c->vs);
211 c->pipe->delete_fs_state(c->pipe, c->fs_video_buffer);
212 c->pipe->delete_fs_state(c->pipe, c->fs_palette);
213 c->pipe->delete_fs_state(c->pipe, c->fs_rgba);
214 }
215
216 static bool
217 init_pipe_state(struct vl_compositor *c)
218 {
219 struct pipe_rasterizer_state rast;
220 struct pipe_sampler_state sampler;
221 struct pipe_blend_state blend;
222
223 assert(c);
224
225 c->fb_state.nr_cbufs = 1;
226 c->fb_state.zsbuf = NULL;
227
228 c->viewport.scale[2] = 1;
229 c->viewport.scale[3] = 1;
230 c->viewport.translate[0] = 0;
231 c->viewport.translate[1] = 0;
232 c->viewport.translate[2] = 0;
233 c->viewport.translate[3] = 0;
234
235 memset(&sampler, 0, sizeof(sampler));
236 sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
237 sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
238 sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
239 sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR;
240 sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
241 sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
242 sampler.compare_mode = PIPE_TEX_COMPARE_NONE;
243 sampler.compare_func = PIPE_FUNC_ALWAYS;
244 sampler.normalized_coords = 1;
245 /*sampler.lod_bias = ;*/
246 /*sampler.min_lod = ;*/
247 /*sampler.max_lod = ;*/
248 /*sampler.border_color[i] = ;*/
249 /*sampler.max_anisotropy = ;*/
250 c->sampler = c->pipe->create_sampler_state(c->pipe, &sampler);
251
252 memset(&blend, 0, sizeof blend);
253 blend.independent_blend_enable = 0;
254 blend.rt[0].blend_enable = 1;
255 blend.rt[0].rgb_func = PIPE_BLEND_ADD;
256 blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
257 blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
258 blend.rt[0].alpha_func = PIPE_BLEND_ADD;
259 blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
260 blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
261 blend.logicop_enable = 0;
262 blend.logicop_func = PIPE_LOGICOP_CLEAR;
263 blend.rt[0].colormask = PIPE_MASK_RGBA;
264 blend.dither = 0;
265 c->blend = c->pipe->create_blend_state(c->pipe, &blend);
266
267 memset(&rast, 0, sizeof rast);
268 rast.flatshade = 1;
269 rast.front_ccw = 1;
270 rast.cull_face = PIPE_FACE_NONE;
271 rast.fill_back = PIPE_POLYGON_MODE_FILL;
272 rast.fill_front = PIPE_POLYGON_MODE_FILL;
273 rast.scissor = 1;
274 rast.line_width = 1;
275 rast.point_size_per_vertex = 1;
276 rast.offset_units = 1;
277 rast.offset_scale = 1;
278 rast.gl_rasterization_rules = 1;
279
280 c->rast = c->pipe->create_rasterizer_state(c->pipe, &rast);
281
282 return true;
283 }
284
285 static void cleanup_pipe_state(struct vl_compositor *c)
286 {
287 assert(c);
288
289 c->pipe->delete_sampler_state(c->pipe, c->sampler);
290 c->pipe->delete_blend_state(c->pipe, c->blend);
291 c->pipe->delete_rasterizer_state(c->pipe, c->rast);
292 }
293
294 static bool
295 init_buffers(struct vl_compositor *c)
296 {
297 struct pipe_vertex_element vertex_elems[2];
298
299 assert(c);
300
301 /*
302 * Create our vertex buffer and vertex buffer elements
303 */
304 c->vertex_buf.stride = sizeof(struct vertex4f);
305 c->vertex_buf.buffer_offset = 0;
306 c->vertex_buf.buffer = pipe_buffer_create
307 (
308 c->pipe->screen,
309 PIPE_BIND_VERTEX_BUFFER,
310 PIPE_USAGE_STREAM,
311 sizeof(struct vertex4f) * (VL_COMPOSITOR_MAX_LAYERS + 1) * 4
312 );
313
314 vertex_elems[0].src_offset = 0;
315 vertex_elems[0].instance_divisor = 0;
316 vertex_elems[0].vertex_buffer_index = 0;
317 vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT;
318 vertex_elems[1].src_offset = sizeof(struct vertex2f);
319 vertex_elems[1].instance_divisor = 0;
320 vertex_elems[1].vertex_buffer_index = 0;
321 vertex_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT;
322 c->vertex_elems_state = c->pipe->create_vertex_elements_state(c->pipe, 2, vertex_elems);
323
324 /*
325 * Create our fragment shader's constant buffer
326 * Const buffer contains the color conversion matrix and bias vectors
327 */
328 /* XXX: Create with IMMUTABLE/STATIC... although it does change every once in a long while... */
329 c->csc_matrix = pipe_buffer_create
330 (
331 c->pipe->screen,
332 PIPE_BIND_CONSTANT_BUFFER,
333 PIPE_USAGE_STATIC,
334 sizeof(csc_matrix)
335 );
336
337 return true;
338 }
339
340 static void
341 cleanup_buffers(struct vl_compositor *c)
342 {
343 assert(c);
344
345 c->pipe->delete_vertex_elements_state(c->pipe, c->vertex_elems_state);
346 pipe_resource_reference(&c->vertex_buf.buffer, NULL);
347 pipe_resource_reference(&c->csc_matrix, NULL);
348 }
349
350 static inline struct pipe_video_rect
351 default_rect(struct vl_compositor_layer *layer)
352 {
353 struct pipe_resource *res = layer->sampler_views[0]->texture;
354 struct pipe_video_rect rect = { 0, 0, res->width0, res->height0 };
355 return rect;
356 }
357
358 static void
359 gen_rect_verts(struct vertex4f *vb,
360 struct pipe_video_rect *src_rect,
361 struct vertex2f *src_inv_size,
362 struct pipe_video_rect *dst_rect,
363 struct vertex2f *dst_inv_size)
364 {
365 assert(vb);
366 assert(src_rect && src_inv_size);
367 assert(dst_rect && dst_inv_size);
368
369 vb[0].x = dst_rect->x * dst_inv_size->x;
370 vb[0].y = dst_rect->y * dst_inv_size->y;
371 vb[0].z = src_rect->x * src_inv_size->x;
372 vb[0].w = src_rect->y * src_inv_size->y;
373
374 vb[1].x = (dst_rect->x + dst_rect->w) * dst_inv_size->x;
375 vb[1].y = dst_rect->y * dst_inv_size->y;
376 vb[1].z = (src_rect->x + src_rect->w) * src_inv_size->x;
377 vb[1].w = src_rect->y * src_inv_size->y;
378
379 vb[2].x = (dst_rect->x + dst_rect->w) * dst_inv_size->x;
380 vb[2].y = (dst_rect->y + dst_rect->h) * dst_inv_size->y;
381 vb[2].z = (src_rect->x + src_rect->w) * src_inv_size->x;
382 vb[2].w = (src_rect->y + src_rect->h) * src_inv_size->y;
383
384 vb[3].x = dst_rect->x * dst_inv_size->x;
385 vb[3].y = (dst_rect->y + dst_rect->h) * dst_inv_size->y;
386 vb[3].z = src_rect->x * src_inv_size->x;
387 vb[3].w = (src_rect->y + src_rect->h) * src_inv_size->y;
388 }
389
390 static void
391 gen_vertex_data(struct vl_compositor *c)
392 {
393 struct vertex4f *vb;
394 struct pipe_transfer *buf_transfer;
395 unsigned i;
396
397 assert(c);
398
399 vb = pipe_buffer_map(c->pipe, c->vertex_buf.buffer,
400 PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD | PIPE_TRANSFER_DONTBLOCK,
401 &buf_transfer);
402
403 if (!vb)
404 return;
405
406 for (i = 0; i < VL_COMPOSITOR_MAX_LAYERS; i++) {
407 if (c->used_layers & (1 << i)) {
408 struct pipe_sampler_view *sv = c->layers[i].sampler_views[0];
409 struct vertex2f src_inv_size = {1.0f / sv->texture->width0, 1.0f / sv->texture->height0};
410
411 gen_rect_verts(vb, &c->layers[i].src_rect, &src_inv_size, &c->layers[i].dst_rect, &src_inv_size);
412
413 vb += 4;
414 }
415 }
416
417 pipe_buffer_unmap(c->pipe, buf_transfer);
418 }
419
420 static void
421 draw_layers(struct vl_compositor *c)
422 {
423 unsigned vb_index, i;
424
425 assert(c);
426
427 for (i = 0, vb_index = 0; i < VL_COMPOSITOR_MAX_LAYERS; ++i) {
428 if (c->used_layers & (1 << i)) {
429 struct pipe_sampler_view **samplers = &c->layers[i].sampler_views[0];
430 unsigned num_sampler_views = !samplers[1] ? 1 : !samplers[2] ? 2 : 3;
431
432 c->pipe->bind_fs_state(c->pipe, c->layers[i].fs);
433 c->pipe->set_fragment_sampler_views(c->pipe, num_sampler_views, samplers);
434 util_draw_arrays(c->pipe, PIPE_PRIM_QUADS, vb_index * 4, 4);
435 vb_index++;
436 }
437 }
438 }
439
440 static void
441 vl_compositor_clear_layers(struct pipe_video_compositor *compositor)
442 {
443 struct vl_compositor *c = (struct vl_compositor *)compositor;
444 unsigned i, j;
445
446 assert(compositor);
447
448 c->used_layers = 0;
449 for ( i = 0; i < VL_COMPOSITOR_MAX_LAYERS; ++i) {
450 c->layers[i].fs = NULL;
451 for ( j = 0; j < 3; j++)
452 pipe_sampler_view_reference(&c->layers[i].sampler_views[j], NULL);
453 }
454 }
455
456 static void
457 vl_compositor_destroy(struct pipe_video_compositor *compositor)
458 {
459 struct vl_compositor *c = (struct vl_compositor *)compositor;
460 assert(compositor);
461
462 vl_compositor_clear_layers(compositor);
463
464 cleanup_buffers(c);
465 cleanup_shaders(c);
466 cleanup_pipe_state(c);
467
468 FREE(compositor);
469 }
470
471 static void
472 vl_compositor_set_csc_matrix(struct pipe_video_compositor *compositor, const float matrix[16])
473 {
474 struct vl_compositor *c = (struct vl_compositor *)compositor;
475 struct pipe_transfer *buf_transfer;
476
477 assert(compositor);
478
479 memcpy
480 (
481 pipe_buffer_map(c->pipe, c->csc_matrix,
482 PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
483 &buf_transfer),
484 matrix,
485 sizeof(csc_matrix)
486 );
487
488 pipe_buffer_unmap(c->pipe, buf_transfer);
489 }
490
491 static void
492 vl_compositor_set_buffer_layer(struct pipe_video_compositor *compositor,
493 unsigned layer,
494 struct pipe_video_buffer *buffer,
495 struct pipe_video_rect *src_rect,
496 struct pipe_video_rect *dst_rect)
497 {
498 struct vl_compositor *c = (struct vl_compositor *)compositor;
499 struct pipe_sampler_view **sampler_views;
500 unsigned i;
501
502 assert(compositor && buffer);
503
504 assert(layer < VL_COMPOSITOR_MAX_LAYERS);
505
506 c->used_layers |= 1 << layer;
507 c->layers[layer].fs = c->fs_video_buffer;
508
509 sampler_views = buffer->get_sampler_views(buffer);
510 for (i = 0; i < 3; ++i)
511 pipe_sampler_view_reference(&c->layers[layer].sampler_views[i], sampler_views[i]);
512
513 c->layers[layer].src_rect = src_rect ? *src_rect : default_rect(&c->layers[layer]);
514 c->layers[layer].dst_rect = dst_rect ? *dst_rect : default_rect(&c->layers[layer]);
515 }
516
517 static void
518 vl_compositor_set_palette_layer(struct pipe_video_compositor *compositor,
519 unsigned layer,
520 struct pipe_sampler_view *indexes,
521 struct pipe_sampler_view *palette,
522 struct pipe_video_rect *src_rect,
523 struct pipe_video_rect *dst_rect)
524 {
525 struct vl_compositor *c = (struct vl_compositor *)compositor;
526 assert(compositor && indexes && palette);
527
528 assert(layer < VL_COMPOSITOR_MAX_LAYERS);
529
530 c->used_layers |= 1 << layer;
531 c->layers[layer].fs = c->fs_palette;
532 pipe_sampler_view_reference(&c->layers[layer].sampler_views[0], indexes);
533 pipe_sampler_view_reference(&c->layers[layer].sampler_views[1], palette);
534 pipe_sampler_view_reference(&c->layers[layer].sampler_views[2], NULL);
535 c->layers[layer].src_rect = src_rect ? *src_rect : default_rect(&c->layers[layer]);
536 c->layers[layer].dst_rect = dst_rect ? *dst_rect : default_rect(&c->layers[layer]);
537 }
538
539 static void
540 vl_compositor_set_rgba_layer(struct pipe_video_compositor *compositor,
541 unsigned layer,
542 struct pipe_sampler_view *rgba,
543 struct pipe_video_rect *src_rect,
544 struct pipe_video_rect *dst_rect)
545 {
546 struct vl_compositor *c = (struct vl_compositor *)compositor;
547 assert(compositor && rgba);
548
549 assert(layer < VL_COMPOSITOR_MAX_LAYERS);
550
551 c->used_layers |= 1 << layer;
552 c->layers[layer].fs = c->fs_rgba;
553 pipe_sampler_view_reference(&c->layers[layer].sampler_views[0], rgba);
554 pipe_sampler_view_reference(&c->layers[layer].sampler_views[1], NULL);
555 pipe_sampler_view_reference(&c->layers[layer].sampler_views[2], NULL);
556 c->layers[layer].src_rect = src_rect ? *src_rect : default_rect(&c->layers[layer]);
557 c->layers[layer].dst_rect = dst_rect ? *dst_rect : default_rect(&c->layers[layer]);
558 }
559
560 static void
561 vl_compositor_render(struct pipe_video_compositor *compositor,
562 enum pipe_mpeg12_picture_type picture_type,
563 struct pipe_surface *dst_surface,
564 struct pipe_video_rect *dst_area,
565 struct pipe_fence_handle **fence)
566 {
567 struct vl_compositor *c = (struct vl_compositor *)compositor;
568 struct pipe_scissor_state scissor;
569 void *samplers[3];
570
571 assert(compositor);
572 assert(dst_surface);
573
574 c->fb_state.width = dst_surface->width;
575 c->fb_state.height = dst_surface->height;
576 c->fb_state.cbufs[0] = dst_surface;
577
578 c->viewport.scale[0] = dst_surface->width;
579 c->viewport.scale[1] = dst_surface->height;
580
581 if (dst_area) {
582 scissor.minx = dst_area->x;
583 scissor.miny = dst_area->y;
584 scissor.maxx = dst_area->x + dst_area->w;
585 scissor.maxy = dst_area->y + dst_area->h;
586 } else {
587 scissor.minx = 0;
588 scissor.miny = 0;
589 scissor.maxx = dst_surface->width;
590 scissor.maxy = dst_surface->height;
591 }
592
593 samplers[0] = samplers[1] = samplers[2] = c->sampler;
594
595 gen_vertex_data(c);
596
597 c->pipe->set_scissor_state(c->pipe, &scissor);
598 c->pipe->set_framebuffer_state(c->pipe, &c->fb_state);
599 c->pipe->set_viewport_state(c->pipe, &c->viewport);
600 c->pipe->bind_fragment_sampler_states(c->pipe, 3, &samplers[0]);
601 c->pipe->bind_vs_state(c->pipe, c->vs);
602 c->pipe->set_vertex_buffers(c->pipe, 1, &c->vertex_buf);
603 c->pipe->bind_vertex_elements_state(c->pipe, c->vertex_elems_state);
604 c->pipe->set_constant_buffer(c->pipe, PIPE_SHADER_FRAGMENT, 0, c->csc_matrix);
605 c->pipe->bind_blend_state(c->pipe, c->blend);
606 c->pipe->bind_rasterizer_state(c->pipe, c->rast);
607
608 draw_layers(c);
609
610 c->pipe->flush(c->pipe, fence);
611 }
612
613 struct pipe_video_compositor *
614 vl_compositor_init(struct pipe_video_context *vpipe, struct pipe_context *pipe)
615 {
616 csc_matrix csc_matrix;
617 struct vl_compositor *compositor;
618
619 compositor = CALLOC_STRUCT(vl_compositor);
620
621 compositor->base.context = vpipe;
622 compositor->base.destroy = vl_compositor_destroy;
623 compositor->base.set_csc_matrix = vl_compositor_set_csc_matrix;
624 compositor->base.clear_layers = vl_compositor_clear_layers;
625 compositor->base.set_buffer_layer = vl_compositor_set_buffer_layer;
626 compositor->base.set_palette_layer = vl_compositor_set_palette_layer;
627 compositor->base.set_rgba_layer = vl_compositor_set_rgba_layer;
628 compositor->base.render_picture = vl_compositor_render;
629
630 compositor->pipe = pipe;
631
632 if (!init_pipe_state(compositor))
633 return false;
634
635 if (!init_shaders(compositor)) {
636 cleanup_pipe_state(compositor);
637 return false;
638 }
639 if (!init_buffers(compositor)) {
640 cleanup_shaders(compositor);
641 cleanup_pipe_state(compositor);
642 return false;
643 }
644
645 vl_compositor_clear_layers(&compositor->base);
646
647 vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_IDENTITY, NULL, true, csc_matrix);
648 vl_compositor_set_csc_matrix(&compositor->base, csc_matrix);
649
650 return &compositor->base;
651 }