vl_compositor.c revision 4a0b80f00dbc77d333027afd195daae7ef1e651c
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 "vl_compositor.h" 29#include "util/u_draw.h" 30#include <assert.h> 31#include <pipe/p_context.h> 32#include <util/u_inlines.h> 33#include <util/u_memory.h> 34#include <util/u_keymap.h> 35#include <util/u_draw.h> 36#include <util/u_sampler.h> 37#include <tgsi/tgsi_ureg.h> 38#include "vl_csc.h" 39 40struct vertex_shader_consts 41{ 42 struct vertex4f dst_scale; 43 struct vertex4f dst_trans; 44 struct vertex4f src_scale; 45 struct vertex4f src_trans; 46}; 47 48struct fragment_shader_consts 49{ 50 float matrix[16]; 51}; 52 53static bool 54u_video_rects_equal(struct pipe_video_rect *a, struct pipe_video_rect *b) 55{ 56 assert(a && b); 57 58 if (a->x != b->x) 59 return false; 60 if (a->y != b->y) 61 return false; 62 if (a->w != b->w) 63 return false; 64 if (a->h != b->h) 65 return false; 66 67 return true; 68} 69 70static bool 71create_vert_shader(struct vl_compositor *c) 72{ 73 struct ureg_program *shader; 74 struct ureg_src vpos, vtex; 75 struct ureg_dst o_vpos, o_vtex; 76 77 shader = ureg_create(TGSI_PROCESSOR_VERTEX); 78 if (!shader) 79 return false; 80 81 vpos = ureg_DECL_vs_input(shader, 0); 82 vtex = ureg_DECL_vs_input(shader, 1); 83 o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, 0); 84 o_vtex = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, 1); 85 86 /* 87 * o_vpos = vpos 88 * o_vtex = vtex 89 */ 90 ureg_MOV(shader, o_vpos, vpos); 91 ureg_MOV(shader, o_vtex, vtex); 92 93 ureg_END(shader); 94 95 c->vertex_shader = ureg_create_shader_and_destroy(shader, c->pipe); 96 if (!c->vertex_shader) 97 return false; 98 99 return true; 100} 101 102static bool 103create_frag_shader_ycbcr_2_rgb(struct vl_compositor *c) 104{ 105 struct ureg_program *shader; 106 struct ureg_src tc; 107 struct ureg_src csc[4]; 108 struct ureg_src sampler; 109 struct ureg_dst texel; 110 struct ureg_dst fragment; 111 unsigned i; 112 113 shader = ureg_create(TGSI_PROCESSOR_FRAGMENT); 114 if (!shader) 115 return false; 116 117 tc = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, 1, TGSI_INTERPOLATE_LINEAR); 118 for (i = 0; i < 4; ++i) 119 csc[i] = ureg_DECL_constant(shader, i); 120 sampler = ureg_DECL_sampler(shader, 0); 121 texel = ureg_DECL_temporary(shader); 122 fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0); 123 124 /* 125 * texel = tex(tc, sampler) 126 * fragment = csc * texel 127 */ 128 ureg_TEX(shader, texel, TGSI_TEXTURE_2D, tc, sampler); 129 for (i = 0; i < 4; ++i) 130 ureg_DP4(shader, ureg_writemask(fragment, TGSI_WRITEMASK_X << i), csc[i], ureg_src(texel)); 131 132 ureg_release_temporary(shader, texel); 133 ureg_END(shader); 134 135 c->fragment_shader.ycbcr_2_rgb = ureg_create_shader_and_destroy(shader, c->pipe); 136 if (!c->fragment_shader.ycbcr_2_rgb) 137 return false; 138 139 return true; 140} 141 142static bool 143create_frag_shader_rgb_2_rgb(struct vl_compositor *c) 144{ 145 struct ureg_program *shader; 146 struct ureg_src tc; 147 struct ureg_src sampler; 148 struct ureg_dst fragment; 149 150 shader = ureg_create(TGSI_PROCESSOR_FRAGMENT); 151 if (!shader) 152 return false; 153 154 tc = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, 1, TGSI_INTERPOLATE_LINEAR); 155 sampler = ureg_DECL_sampler(shader, 0); 156 fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0); 157 158 /* 159 * fragment = tex(tc, sampler) 160 */ 161 ureg_TEX(shader, fragment, TGSI_TEXTURE_2D, tc, sampler); 162 ureg_END(shader); 163 164 c->fragment_shader.rgb_2_rgb = ureg_create_shader_and_destroy(shader, c->pipe); 165 if (!c->fragment_shader.rgb_2_rgb) 166 return false; 167 168 return true; 169} 170 171static bool 172init_pipe_state(struct vl_compositor *c) 173{ 174 struct pipe_sampler_state sampler; 175 176 assert(c); 177 178 c->fb_state.nr_cbufs = 1; 179 c->fb_state.zsbuf = NULL; 180 181 memset(&sampler, 0, sizeof(sampler)); 182 sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 183 sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 184 sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; 185 sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR; 186 sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; 187 sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR; 188 sampler.compare_mode = PIPE_TEX_COMPARE_NONE; 189 sampler.compare_func = PIPE_FUNC_ALWAYS; 190 sampler.normalized_coords = 1; 191 /*sampler.lod_bias = ;*/ 192 /*sampler.min_lod = ;*/ 193 /*sampler.max_lod = ;*/ 194 /*sampler.border_color[i] = ;*/ 195 /*sampler.max_anisotropy = ;*/ 196 c->sampler = c->pipe->create_sampler_state(c->pipe, &sampler); 197 198 return true; 199} 200 201static void cleanup_pipe_state(struct vl_compositor *c) 202{ 203 assert(c); 204 205 c->pipe->delete_sampler_state(c->pipe, c->sampler); 206} 207 208static bool 209init_shaders(struct vl_compositor *c) 210{ 211 assert(c); 212 213 if (!create_vert_shader(c)) { 214 debug_printf("Unable to create vertex shader.\n"); 215 return false; 216 } 217 if (!create_frag_shader_ycbcr_2_rgb(c)) { 218 debug_printf("Unable to create YCbCr-to-RGB fragment shader.\n"); 219 return false; 220 } 221 if (!create_frag_shader_rgb_2_rgb(c)) { 222 debug_printf("Unable to create RGB-to-RGB fragment shader.\n"); 223 return false; 224 } 225 226 return true; 227} 228 229static void cleanup_shaders(struct vl_compositor *c) 230{ 231 assert(c); 232 233 c->pipe->delete_vs_state(c->pipe, c->vertex_shader); 234 c->pipe->delete_fs_state(c->pipe, c->fragment_shader.ycbcr_2_rgb); 235 c->pipe->delete_fs_state(c->pipe, c->fragment_shader.rgb_2_rgb); 236} 237 238static bool 239init_buffers(struct vl_compositor *c) 240{ 241 struct fragment_shader_consts fsc; 242 struct pipe_vertex_element vertex_elems[2]; 243 244 assert(c); 245 246 /* 247 * Create our vertex buffer and vertex buffer elements 248 */ 249 c->vertex_buf.stride = sizeof(struct vertex4f); 250 c->vertex_buf.buffer_offset = 0; 251 /* XXX: Create with DYNAMIC or STREAM */ 252 c->vertex_buf.buffer = pipe_buffer_create 253 ( 254 c->pipe->screen, 255 PIPE_BIND_VERTEX_BUFFER, 256 PIPE_USAGE_STATIC, 257 sizeof(struct vertex4f) * (VL_COMPOSITOR_MAX_LAYERS + 2) * 6 258 ); 259 260 vertex_elems[0].src_offset = 0; 261 vertex_elems[0].instance_divisor = 0; 262 vertex_elems[0].vertex_buffer_index = 0; 263 vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT; 264 vertex_elems[1].src_offset = sizeof(struct vertex2f); 265 vertex_elems[1].instance_divisor = 0; 266 vertex_elems[1].vertex_buffer_index = 0; 267 vertex_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT; 268 c->vertex_elems_state = c->pipe->create_vertex_elements_state(c->pipe, 2, vertex_elems); 269 270 /* 271 * Create our fragment shader's constant buffer 272 * Const buffer contains the color conversion matrix and bias vectors 273 */ 274 /* XXX: Create with IMMUTABLE/STATIC... although it does change every once in a long while... */ 275 c->fs_const_buf = pipe_buffer_create 276 ( 277 c->pipe->screen, 278 PIPE_BIND_CONSTANT_BUFFER, 279 PIPE_USAGE_STATIC, 280 sizeof(struct fragment_shader_consts) 281 ); 282 283 vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_IDENTITY, NULL, true, fsc.matrix); 284 285 vl_compositor_set_csc_matrix(c, fsc.matrix); 286 287 return true; 288} 289 290static void 291cleanup_buffers(struct vl_compositor *c) 292{ 293 assert(c); 294 295 c->pipe->delete_vertex_elements_state(c->pipe, c->vertex_elems_state); 296 pipe_resource_reference(&c->vertex_buf.buffer, NULL); 297 pipe_resource_reference(&c->fs_const_buf, NULL); 298} 299 300static void 301texview_map_delete(const struct keymap *map, 302 const void *key, void *data, 303 void *user) 304{ 305 struct pipe_sampler_view *sv = (struct pipe_sampler_view*)data; 306 307 assert(map); 308 assert(key); 309 assert(data); 310 assert(user); 311 312 pipe_sampler_view_reference(&sv, NULL); 313} 314 315bool vl_compositor_init(struct vl_compositor *compositor, struct pipe_context *pipe) 316{ 317 unsigned i; 318 319 assert(compositor); 320 321 memset(compositor, 0, sizeof(struct vl_compositor)); 322 323 compositor->pipe = pipe; 324 325 compositor->texview_map = util_new_keymap(sizeof(struct pipe_surface*), -1, 326 texview_map_delete); 327 if (!compositor->texview_map) 328 return false; 329 330 if (!init_pipe_state(compositor)) { 331 util_delete_keymap(compositor->texview_map, compositor->pipe); 332 return false; 333 } 334 if (!init_shaders(compositor)) { 335 util_delete_keymap(compositor->texview_map, compositor->pipe); 336 cleanup_pipe_state(compositor); 337 return false; 338 } 339 if (!init_buffers(compositor)) { 340 util_delete_keymap(compositor->texview_map, compositor->pipe); 341 cleanup_shaders(compositor); 342 cleanup_pipe_state(compositor); 343 return false; 344 } 345 346 compositor->fb_state.width = 0; 347 compositor->fb_state.height = 0; 348 compositor->bg = NULL; 349 compositor->dirty_bg = false; 350 for (i = 0; i < VL_COMPOSITOR_MAX_LAYERS; ++i) 351 compositor->layers[i] = NULL; 352 compositor->dirty_layers = 0; 353 354 return true; 355} 356 357void vl_compositor_cleanup(struct vl_compositor *compositor) 358{ 359 assert(compositor); 360 361 util_delete_keymap(compositor->texview_map, compositor->pipe); 362 cleanup_buffers(compositor); 363 cleanup_shaders(compositor); 364 cleanup_pipe_state(compositor); 365} 366 367#if 0 368void vl_compositor_set_background(struct vl_compositor *compositor, 369 struct pipe_surface *bg, struct pipe_video_rect *bg_src_rect) 370{ 371 assert(compositor); 372 assert((bg && bg_src_rect) || (!bg && !bg_src_rect)); 373 374 if (compositor->bg != bg || 375 !u_video_rects_equal(&compositor->bg_src_rect, bg_src_rect)) { 376 pipe_surface_reference(&compositor->bg, bg); 377 /*if (!u_video_rects_equal(&compositor->bg_src_rect, bg_src_rect))*/ 378 compositor->bg_src_rect = *bg_src_rect; 379 compositor->dirty_bg = true; 380 } 381} 382#endif 383 384void vl_compositor_set_layers(struct vl_compositor *compositor, 385 struct pipe_sampler_view *layers[], 386 struct pipe_video_rect *src_rects[], 387 struct pipe_video_rect *dst_rects[], 388 unsigned num_layers) 389{ 390 unsigned i; 391 392 assert(compositor); 393 assert(num_layers <= VL_COMPOSITOR_MAX_LAYERS); 394 395 for (i = 0; i < num_layers; ++i) 396 { 397 assert((layers[i] && src_rects[i] && dst_rects[i]) || 398 (!layers[i] && !src_rects[i] && !dst_rects[i])); 399 400 if (compositor->layers[i] != layers[i] || 401 !u_video_rects_equal(&compositor->layer_src_rects[i], src_rects[i]) || 402 !u_video_rects_equal(&compositor->layer_dst_rects[i], dst_rects[i])) 403 { 404 pipe_sampler_view_reference(&compositor->layers[i], layers[i]); 405 compositor->layer_src_rects[i] = *src_rects[i]; 406 compositor->layer_dst_rects[i] = *dst_rects[i]; 407 compositor->dirty_layers |= 1 << i; 408 } 409 410 if (layers[i]) 411 compositor->dirty_layers |= 1 << i; 412 } 413 414 for (; i < VL_COMPOSITOR_MAX_LAYERS; ++i) 415 pipe_sampler_view_reference(&compositor->layers[i], NULL); 416} 417 418static void gen_rect_verts(unsigned pos, 419 struct pipe_video_rect *src_rect, 420 struct vertex2f *src_inv_size, 421 struct pipe_video_rect *dst_rect, 422 struct vertex2f *dst_inv_size, 423 struct vertex4f *vb) 424{ 425 assert(pos < VL_COMPOSITOR_MAX_LAYERS + 2); 426 assert(src_rect); 427 assert(src_inv_size); 428 assert((dst_rect && dst_inv_size) /*|| (!dst_rect && !dst_inv_size)*/); 429 assert(vb); 430 431 vb[pos * 6 + 0].x = dst_rect->x * dst_inv_size->x; 432 vb[pos * 6 + 0].y = dst_rect->y * dst_inv_size->y; 433 vb[pos * 6 + 0].z = src_rect->x * src_inv_size->x; 434 vb[pos * 6 + 0].w = src_rect->y * src_inv_size->y; 435 436 vb[pos * 6 + 1].x = dst_rect->x * dst_inv_size->x; 437 vb[pos * 6 + 1].y = (dst_rect->y + dst_rect->h) * dst_inv_size->y; 438 vb[pos * 6 + 1].z = src_rect->x * src_inv_size->x; 439 vb[pos * 6 + 1].w = (src_rect->y + src_rect->h) * src_inv_size->y; 440 441 vb[pos * 6 + 2].x = (dst_rect->x + dst_rect->w) * dst_inv_size->x; 442 vb[pos * 6 + 2].y = dst_rect->y * dst_inv_size->y; 443 vb[pos * 6 + 2].z = (src_rect->x + src_rect->w) * src_inv_size->x; 444 vb[pos * 6 + 2].w = src_rect->y * src_inv_size->y; 445 446 vb[pos * 6 + 3].x = (dst_rect->x + dst_rect->w) * dst_inv_size->x; 447 vb[pos * 6 + 3].y = dst_rect->y * dst_inv_size->y; 448 vb[pos * 6 + 3].z = (src_rect->x + src_rect->w) * src_inv_size->x; 449 vb[pos * 6 + 3].w = src_rect->y * src_inv_size->y; 450 451 vb[pos * 6 + 4].x = dst_rect->x * dst_inv_size->x; 452 vb[pos * 6 + 4].y = (dst_rect->y + dst_rect->h) * dst_inv_size->y; 453 vb[pos * 6 + 4].z = src_rect->x * src_inv_size->x; 454 vb[pos * 6 + 4].w = (src_rect->y + src_rect->h) * src_inv_size->y; 455 456 vb[pos * 6 + 5].x = (dst_rect->x + dst_rect->w) * dst_inv_size->x; 457 vb[pos * 6 + 5].y = (dst_rect->y + dst_rect->h) * dst_inv_size->y; 458 vb[pos * 6 + 5].z = (src_rect->x + src_rect->w) * src_inv_size->x; 459 vb[pos * 6 + 5].w = (src_rect->y + src_rect->h) * src_inv_size->y; 460} 461 462static unsigned gen_data(struct vl_compositor *c, 463 struct pipe_sampler_view *src_surface, 464 struct pipe_video_rect *src_rect, 465 struct pipe_video_rect *dst_rect, 466 struct pipe_sampler_view **textures, 467 void **frag_shaders) 468{ 469 void *vb; 470 struct pipe_transfer *buf_transfer; 471 unsigned num_rects = 0; 472 unsigned i; 473 474 assert(c); 475 assert(src_surface); 476 assert(src_rect); 477 assert(dst_rect); 478 assert(textures); 479 480 vb = pipe_buffer_map(c->pipe, c->vertex_buf.buffer, 481 PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD, 482 &buf_transfer); 483 484 if (!vb) 485 return 0; 486 487 if (c->dirty_bg) { 488 struct vertex2f bg_inv_size = {1.0f / c->bg->texture->width0, 1.0f / c->bg->texture->height0}; 489 gen_rect_verts(num_rects, &c->bg_src_rect, &bg_inv_size, NULL, NULL, vb); 490 textures[num_rects] = c->bg; 491 /* XXX: Hack */ 492 frag_shaders[num_rects] = c->fragment_shader.rgb_2_rgb; 493 ++num_rects; 494 c->dirty_bg = false; 495 } 496 497 { 498 struct vertex2f src_inv_size = { 1.0f / src_surface->texture->width0, 1.0f / src_surface->texture->height0}; 499 gen_rect_verts(num_rects, src_rect, &src_inv_size, dst_rect, &c->fb_inv_size, vb); 500 textures[num_rects] = src_surface; 501 /* XXX: Hack, sort of */ 502 frag_shaders[num_rects] = c->fragment_shader.ycbcr_2_rgb; 503 ++num_rects; 504 } 505 506 for (i = 0; c->dirty_layers > 0; i++) { 507 assert(i < VL_COMPOSITOR_MAX_LAYERS); 508 509 if (c->dirty_layers & (1 << i)) { 510 struct vertex2f layer_inv_size = {1.0f / c->layers[i]->texture->width0, 1.0f / c->layers[i]->texture->height0}; 511 gen_rect_verts(num_rects, &c->layer_src_rects[i], &layer_inv_size, 512 &c->layer_dst_rects[i], &c->fb_inv_size, vb); 513 textures[num_rects] = c->layers[i]; 514 /* XXX: Hack */ 515 frag_shaders[num_rects] = c->fragment_shader.rgb_2_rgb; 516 ++num_rects; 517 c->dirty_layers &= ~(1 << i); 518 } 519 } 520 521 pipe_buffer_unmap(c->pipe, buf_transfer); 522 523 return num_rects; 524} 525 526static void draw_layers(struct vl_compositor *c, 527 struct pipe_sampler_view *src_surface, 528 struct pipe_video_rect *src_rect, 529 struct pipe_video_rect *dst_rect) 530{ 531 unsigned num_rects; 532 struct pipe_sampler_view *src_surfaces[VL_COMPOSITOR_MAX_LAYERS + 2]; 533 void *frag_shaders[VL_COMPOSITOR_MAX_LAYERS + 2]; 534 unsigned i; 535 536 assert(c); 537 assert(src_surface); 538 assert(src_rect); 539 assert(dst_rect); 540 541 num_rects = gen_data(c, src_surface, src_rect, dst_rect, src_surfaces, frag_shaders); 542 543 for (i = 0; i < num_rects; ++i) { 544 boolean delete_view = FALSE; 545 struct pipe_sampler_view *surface_view = (struct pipe_sampler_view*)util_keymap_lookup(c->texview_map, 546 &src_surfaces[i]); 547 if (!surface_view) { 548 struct pipe_sampler_view templat; 549 u_sampler_view_default_template(&templat, src_surfaces[i]->texture, 550 src_surfaces[i]->texture->format); 551 surface_view = c->pipe->create_sampler_view(c->pipe, src_surfaces[i]->texture, 552 &templat); 553 if (!surface_view) 554 return; 555 556 delete_view = !util_keymap_insert(c->texview_map, &src_surfaces[i], 557 surface_view, c->pipe); 558 } 559 560 c->pipe->bind_fs_state(c->pipe, frag_shaders[i]); 561 c->pipe->set_fragment_sampler_views(c->pipe, 1, &surface_view); 562 563 util_draw_arrays(c->pipe, PIPE_PRIM_TRIANGLES, i * 6, 6); 564 565 if (delete_view) { 566 pipe_sampler_view_reference(&surface_view, NULL); 567 } 568 } 569} 570 571void vl_compositor_render(struct vl_compositor *compositor, 572 struct pipe_sampler_view *src_surface, 573 enum pipe_mpeg12_picture_type picture_type, 574 struct pipe_video_rect *src_area, 575 struct pipe_surface *dst_surface, 576 struct pipe_video_rect *dst_area, 577 struct pipe_fence_handle **fence) 578{ 579 assert(compositor); 580 assert(src_surface); 581 assert(src_area); 582 assert(dst_surface); 583 assert(dst_area); 584 assert(picture_type == PIPE_MPEG12_PICTURE_TYPE_FRAME); 585 586 if (compositor->fb_state.width != dst_surface->width) { 587 compositor->fb_inv_size.x = 1.0f / dst_surface->width; 588 compositor->fb_state.width = dst_surface->width; 589 } 590 if (compositor->fb_state.height != dst_surface->height) { 591 compositor->fb_inv_size.y = 1.0f / dst_surface->height; 592 compositor->fb_state.height = dst_surface->height; 593 } 594 595 compositor->fb_state.cbufs[0] = dst_surface; 596 597 compositor->viewport.scale[0] = compositor->fb_state.width; 598 compositor->viewport.scale[1] = compositor->fb_state.height; 599 compositor->viewport.scale[2] = 1; 600 compositor->viewport.scale[3] = 1; 601 compositor->viewport.translate[0] = 0; 602 compositor->viewport.translate[1] = 0; 603 compositor->viewport.translate[2] = 0; 604 compositor->viewport.translate[3] = 0; 605 606 compositor->pipe->set_framebuffer_state(compositor->pipe, &compositor->fb_state); 607 compositor->pipe->set_viewport_state(compositor->pipe, &compositor->viewport); 608 compositor->pipe->bind_fragment_sampler_states(compositor->pipe, 1, &compositor->sampler); 609 compositor->pipe->bind_vs_state(compositor->pipe, compositor->vertex_shader); 610 compositor->pipe->set_vertex_buffers(compositor->pipe, 1, &compositor->vertex_buf); 611 compositor->pipe->bind_vertex_elements_state(compositor->pipe, compositor->vertex_elems_state); 612 compositor->pipe->set_constant_buffer(compositor->pipe, PIPE_SHADER_FRAGMENT, 0, compositor->fs_const_buf); 613 614 draw_layers(compositor, src_surface, src_area, dst_area); 615 616 assert(!compositor->dirty_bg && !compositor->dirty_layers); 617 compositor->pipe->flush(compositor->pipe, fence); 618} 619 620void vl_compositor_set_csc_matrix(struct vl_compositor *compositor, const float *mat) 621{ 622 struct pipe_transfer *buf_transfer; 623 624 assert(compositor); 625 626 memcpy 627 ( 628 pipe_buffer_map(compositor->pipe, compositor->fs_const_buf, 629 PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD, 630 &buf_transfer), 631 mat, 632 sizeof(struct fragment_shader_consts) 633 ); 634 635 pipe_buffer_unmap(compositor->pipe, buf_transfer); 636} 637