1 /**************************************************************************
3 * Copyright 2010 Thomas Balling Sørensen.
4 * Copyright 2011 Christian König.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sub license, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial portions
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 **************************************************************************/
29 #include <vdpau/vdpau.h>
31 #include "util/u_debug.h"
32 #include "util/u_memory.h"
33 #include "util/u_sampler.h"
34 #include "util/u_format.h"
36 #include "vl/vl_csc.h"
38 #include "vdpau_private.h"
41 * Create a VdpOutputSurface.
44 vlVdpOutputSurfaceCreate(VdpDevice device
,
45 VdpRGBAFormat rgba_format
,
46 uint32_t width
, uint32_t height
,
47 VdpOutputSurface
*surface
)
49 struct pipe_context
*pipe
;
50 struct pipe_resource res_tmpl
, *res
;
51 struct pipe_sampler_view sv_templ
;
52 struct pipe_surface surf_templ
;
54 vlVdpOutputSurface
*vlsurface
= NULL
;
56 if (!(width
&& height
))
57 return VDP_STATUS_INVALID_SIZE
;
59 vlVdpDevice
*dev
= vlGetDataHTAB(device
);
61 return VDP_STATUS_INVALID_HANDLE
;
65 return VDP_STATUS_INVALID_HANDLE
;
67 vlsurface
= CALLOC(1, sizeof(vlVdpOutputSurface
));
69 return VDP_STATUS_RESOURCES
;
71 vlsurface
->device
= dev
;
73 memset(&res_tmpl
, 0, sizeof(res_tmpl
));
75 res_tmpl
.target
= PIPE_TEXTURE_2D
;
76 res_tmpl
.format
= FormatRGBAToPipe(rgba_format
);
77 res_tmpl
.width0
= width
;
78 res_tmpl
.height0
= height
;
80 res_tmpl
.array_size
= 1;
81 res_tmpl
.bind
= PIPE_BIND_SAMPLER_VIEW
| PIPE_BIND_RENDER_TARGET
;
82 res_tmpl
.usage
= PIPE_USAGE_STATIC
;
84 pipe_mutex_lock(dev
->mutex
);
85 res
= pipe
->screen
->resource_create(pipe
->screen
, &res_tmpl
);
87 pipe_mutex_unlock(dev
->mutex
);
89 return VDP_STATUS_ERROR
;
92 vlVdpDefaultSamplerViewTemplate(&sv_templ
, res
);
93 vlsurface
->sampler_view
= pipe
->create_sampler_view(pipe
, res
, &sv_templ
);
94 if (!vlsurface
->sampler_view
) {
95 pipe_resource_reference(&res
, NULL
);
96 pipe_mutex_unlock(dev
->mutex
);
98 return VDP_STATUS_ERROR
;
101 memset(&surf_templ
, 0, sizeof(surf_templ
));
102 surf_templ
.format
= res
->format
;
103 surf_templ
.usage
= PIPE_BIND_SAMPLER_VIEW
| PIPE_BIND_RENDER_TARGET
;
104 vlsurface
->surface
= pipe
->create_surface(pipe
, res
, &surf_templ
);
105 if (!vlsurface
->surface
) {
106 pipe_resource_reference(&res
, NULL
);
107 pipe_mutex_unlock(dev
->mutex
);
109 return VDP_STATUS_ERROR
;
112 *surface
= vlAddDataHTAB(vlsurface
);
114 pipe_resource_reference(&res
, NULL
);
115 pipe_mutex_unlock(dev
->mutex
);
117 return VDP_STATUS_ERROR
;
120 pipe_resource_reference(&res
, NULL
);
122 vl_compositor_init_state(&vlsurface
->cstate
, pipe
);
123 vl_compositor_reset_dirty_area(&vlsurface
->dirty_area
);
124 pipe_mutex_unlock(dev
->mutex
);
126 return VDP_STATUS_OK
;
130 * Destroy a VdpOutputSurface.
133 vlVdpOutputSurfaceDestroy(VdpOutputSurface surface
)
135 vlVdpOutputSurface
*vlsurface
;
136 struct pipe_context
*pipe
;
138 vlsurface
= vlGetDataHTAB(surface
);
140 return VDP_STATUS_INVALID_HANDLE
;
142 pipe
= vlsurface
->device
->context
;
144 pipe_mutex_lock(vlsurface
->device
->mutex
);
145 vlVdpResolveDelayedRendering(vlsurface
->device
, NULL
, NULL
);
147 pipe_surface_reference(&vlsurface
->surface
, NULL
);
148 pipe_sampler_view_reference(&vlsurface
->sampler_view
, NULL
);
149 pipe
->screen
->fence_reference(pipe
->screen
, &vlsurface
->fence
, NULL
);
150 vl_compositor_cleanup_state(&vlsurface
->cstate
);
151 pipe_mutex_unlock(vlsurface
->device
->mutex
);
153 vlRemoveDataHTAB(surface
);
156 return VDP_STATUS_OK
;
160 * Retrieve the parameters used to create a VdpOutputSurface.
163 vlVdpOutputSurfaceGetParameters(VdpOutputSurface surface
,
164 VdpRGBAFormat
*rgba_format
,
165 uint32_t *width
, uint32_t *height
)
167 vlVdpOutputSurface
*vlsurface
;
169 vlsurface
= vlGetDataHTAB(surface
);
171 return VDP_STATUS_INVALID_HANDLE
;
173 *rgba_format
= PipeToFormatRGBA(vlsurface
->sampler_view
->texture
->format
);
174 *width
= vlsurface
->sampler_view
->texture
->width0
;
175 *height
= vlsurface
->sampler_view
->texture
->height0
;
177 return VDP_STATUS_OK
;
181 * Copy image data from a VdpOutputSurface to application memory in the
182 * surface's native format.
185 vlVdpOutputSurfaceGetBitsNative(VdpOutputSurface surface
,
186 VdpRect
const *source_rect
,
187 void *const *destination_data
,
188 uint32_t const *destination_pitches
)
190 vlVdpOutputSurface
*vlsurface
;
191 struct pipe_context
*pipe
;
192 struct pipe_resource
*res
;
194 struct pipe_transfer
*transfer
;
197 vlsurface
= vlGetDataHTAB(surface
);
199 return VDP_STATUS_INVALID_HANDLE
;
201 pipe
= vlsurface
->device
->context
;
203 return VDP_STATUS_INVALID_HANDLE
;
205 pipe_mutex_lock(vlsurface
->device
->mutex
);
206 vlVdpResolveDelayedRendering(vlsurface
->device
, NULL
, NULL
);
208 res
= vlsurface
->sampler_view
->texture
;
209 box
= RectToPipeBox(source_rect
, res
);
210 transfer
= pipe
->get_transfer(pipe
, res
, 0, PIPE_TRANSFER_READ
, &box
);
211 if (transfer
== NULL
) {
212 pipe_mutex_unlock(vlsurface
->device
->mutex
);
213 return VDP_STATUS_RESOURCES
;
216 map
= pipe_transfer_map(pipe
, transfer
);
218 pipe_transfer_destroy(pipe
, transfer
);
219 pipe_mutex_unlock(vlsurface
->device
->mutex
);
220 return VDP_STATUS_RESOURCES
;
223 util_copy_rect(*destination_data
, res
->format
, *destination_pitches
, 0, 0,
224 box
.width
, box
.height
, map
, transfer
->stride
, 0, 0);
226 pipe_transfer_unmap(pipe
, transfer
);
227 pipe_transfer_destroy(pipe
, transfer
);
228 pipe_mutex_unlock(vlsurface
->device
->mutex
);
230 return VDP_STATUS_OK
;
234 * Copy image data from application memory in the surface's native format to
235 * a VdpOutputSurface.
238 vlVdpOutputSurfacePutBitsNative(VdpOutputSurface surface
,
239 void const *const *source_data
,
240 uint32_t const *source_pitches
,
241 VdpRect
const *destination_rect
)
243 vlVdpOutputSurface
*vlsurface
;
244 struct pipe_box dst_box
;
245 struct pipe_context
*pipe
;
247 vlsurface
= vlGetDataHTAB(surface
);
249 return VDP_STATUS_INVALID_HANDLE
;
251 pipe
= vlsurface
->device
->context
;
253 return VDP_STATUS_INVALID_HANDLE
;
255 pipe_mutex_lock(vlsurface
->device
->mutex
);
256 vlVdpResolveDelayedRendering(vlsurface
->device
, NULL
, NULL
);
258 dst_box
= RectToPipeBox(destination_rect
, vlsurface
->sampler_view
->texture
);
259 pipe
->transfer_inline_write(pipe
, vlsurface
->sampler_view
->texture
, 0,
260 PIPE_TRANSFER_WRITE
, &dst_box
, *source_data
,
262 pipe_mutex_unlock(vlsurface
->device
->mutex
);
264 return VDP_STATUS_OK
;
268 * Copy image data from application memory in a specific indexed format to
269 * a VdpOutputSurface.
272 vlVdpOutputSurfacePutBitsIndexed(VdpOutputSurface surface
,
273 VdpIndexedFormat source_indexed_format
,
274 void const *const *source_data
,
275 uint32_t const *source_pitch
,
276 VdpRect
const *destination_rect
,
277 VdpColorTableFormat color_table_format
,
278 void const *color_table
)
280 vlVdpOutputSurface
*vlsurface
;
281 struct pipe_context
*context
;
282 struct vl_compositor
*compositor
;
283 struct vl_compositor_state
*cstate
;
285 enum pipe_format index_format
;
286 enum pipe_format colortbl_format
;
288 struct pipe_resource
*res
, res_tmpl
;
289 struct pipe_sampler_view sv_tmpl
;
290 struct pipe_sampler_view
*sv_idx
= NULL
, *sv_tbl
= NULL
;
293 struct u_rect dst_rect
;
295 vlsurface
= vlGetDataHTAB(surface
);
297 return VDP_STATUS_INVALID_HANDLE
;
299 context
= vlsurface
->device
->context
;
300 compositor
= &vlsurface
->device
->compositor
;
301 cstate
= &vlsurface
->cstate
;
303 index_format
= FormatIndexedToPipe(source_indexed_format
);
304 if (index_format
== PIPE_FORMAT_NONE
)
305 return VDP_STATUS_INVALID_INDEXED_FORMAT
;
307 if (!source_data
|| !source_pitch
)
308 return VDP_STATUS_INVALID_POINTER
;
310 colortbl_format
= FormatColorTableToPipe(color_table_format
);
311 if (colortbl_format
== PIPE_FORMAT_NONE
)
312 return VDP_STATUS_INVALID_COLOR_TABLE_FORMAT
;
315 return VDP_STATUS_INVALID_POINTER
;
317 memset(&res_tmpl
, 0, sizeof(res_tmpl
));
318 res_tmpl
.target
= PIPE_TEXTURE_2D
;
319 res_tmpl
.format
= index_format
;
321 if (destination_rect
) {
322 res_tmpl
.width0
= abs(destination_rect
->x0
-destination_rect
->x1
);
323 res_tmpl
.height0
= abs(destination_rect
->y0
-destination_rect
->y1
);
325 res_tmpl
.width0
= vlsurface
->surface
->texture
->width0
;
326 res_tmpl
.height0
= vlsurface
->surface
->texture
->height0
;
329 res_tmpl
.array_size
= 1;
330 res_tmpl
.usage
= PIPE_USAGE_STAGING
;
331 res_tmpl
.bind
= PIPE_BIND_SAMPLER_VIEW
;
333 pipe_mutex_lock(vlsurface
->device
->mutex
);
334 vlVdpResolveDelayedRendering(vlsurface
->device
, NULL
, NULL
);
336 res
= context
->screen
->resource_create(context
->screen
, &res_tmpl
);
340 box
.x
= box
.y
= box
.z
= 0;
341 box
.width
= res
->width0
;
342 box
.height
= res
->height0
;
343 box
.depth
= res
->depth0
;
345 context
->transfer_inline_write(context
, res
, 0, PIPE_TRANSFER_WRITE
, &box
,
346 source_data
[0], source_pitch
[0],
347 source_pitch
[0] * res
->height0
);
349 memset(&sv_tmpl
, 0, sizeof(sv_tmpl
));
350 u_sampler_view_default_template(&sv_tmpl
, res
, res
->format
);
352 sv_idx
= context
->create_sampler_view(context
, res
, &sv_tmpl
);
353 pipe_resource_reference(&res
, NULL
);
358 memset(&res_tmpl
, 0, sizeof(res_tmpl
));
359 res_tmpl
.target
= PIPE_TEXTURE_1D
;
360 res_tmpl
.format
= colortbl_format
;
361 res_tmpl
.width0
= 1 << util_format_get_component_bits(
362 index_format
, UTIL_FORMAT_COLORSPACE_RGB
, 0);
363 res_tmpl
.height0
= 1;
365 res_tmpl
.array_size
= 1;
366 res_tmpl
.usage
= PIPE_USAGE_STAGING
;
367 res_tmpl
.bind
= PIPE_BIND_SAMPLER_VIEW
;
369 res
= context
->screen
->resource_create(context
->screen
, &res_tmpl
);
373 box
.x
= box
.y
= box
.z
= 0;
374 box
.width
= res
->width0
;
375 box
.height
= res
->height0
;
376 box
.depth
= res
->depth0
;
378 context
->transfer_inline_write(context
, res
, 0, PIPE_TRANSFER_WRITE
, &box
, color_table
,
379 util_format_get_stride(colortbl_format
, res
->width0
), 0);
381 memset(&sv_tmpl
, 0, sizeof(sv_tmpl
));
382 u_sampler_view_default_template(&sv_tmpl
, res
, res
->format
);
384 sv_tbl
= context
->create_sampler_view(context
, res
, &sv_tmpl
);
385 pipe_resource_reference(&res
, NULL
);
390 vl_compositor_clear_layers(cstate
);
391 vl_compositor_set_palette_layer(cstate
, compositor
, 0, sv_idx
, sv_tbl
, NULL
, NULL
, false);
392 vl_compositor_set_layer_dst_area(cstate
, 0, RectToPipe(destination_rect
, &dst_rect
));
393 vl_compositor_render(cstate
, compositor
, vlsurface
->surface
, NULL
);
395 pipe_sampler_view_reference(&sv_idx
, NULL
);
396 pipe_sampler_view_reference(&sv_tbl
, NULL
);
397 pipe_mutex_unlock(vlsurface
->device
->mutex
);
399 return VDP_STATUS_OK
;
402 pipe_sampler_view_reference(&sv_idx
, NULL
);
403 pipe_sampler_view_reference(&sv_tbl
, NULL
);
404 pipe_mutex_unlock(vlsurface
->device
->mutex
);
405 return VDP_STATUS_RESOURCES
;
409 * Copy image data from application memory in a specific YCbCr format to
410 * a VdpOutputSurface.
413 vlVdpOutputSurfacePutBitsYCbCr(VdpOutputSurface surface
,
414 VdpYCbCrFormat source_ycbcr_format
,
415 void const *const *source_data
,
416 uint32_t const *source_pitches
,
417 VdpRect
const *destination_rect
,
418 VdpCSCMatrix
const *csc_matrix
)
420 vlVdpOutputSurface
*vlsurface
;
421 struct vl_compositor
*compositor
;
422 struct vl_compositor_state
*cstate
;
424 struct pipe_context
*pipe
;
425 enum pipe_format format
;
426 struct pipe_video_buffer vtmpl
, *vbuffer
;
427 struct u_rect dst_rect
;
428 struct pipe_sampler_view
**sampler_views
;
432 vlsurface
= vlGetDataHTAB(surface
);
434 return VDP_STATUS_INVALID_HANDLE
;
437 pipe
= vlsurface
->device
->context
;
438 compositor
= &vlsurface
->device
->compositor
;
439 cstate
= &vlsurface
->cstate
;
441 format
= FormatYCBCRToPipe(source_ycbcr_format
);
442 if (format
== PIPE_FORMAT_NONE
)
443 return VDP_STATUS_INVALID_Y_CB_CR_FORMAT
;
445 if (!source_data
|| !source_pitches
)
446 return VDP_STATUS_INVALID_POINTER
;
448 pipe_mutex_lock(vlsurface
->device
->mutex
);
449 vlVdpResolveDelayedRendering(vlsurface
->device
, NULL
, NULL
);
450 memset(&vtmpl
, 0, sizeof(vtmpl
));
451 vtmpl
.buffer_format
= format
;
452 vtmpl
.chroma_format
= PIPE_VIDEO_CHROMA_FORMAT_420
;
454 if (destination_rect
) {
455 vtmpl
.width
= abs(destination_rect
->x0
-destination_rect
->x1
);
456 vtmpl
.height
= abs(destination_rect
->y0
-destination_rect
->y1
);
458 vtmpl
.width
= vlsurface
->surface
->texture
->width0
;
459 vtmpl
.height
= vlsurface
->surface
->texture
->height0
;
462 vbuffer
= pipe
->create_video_buffer(pipe
, &vtmpl
);
464 pipe_mutex_unlock(vlsurface
->device
->mutex
);
465 return VDP_STATUS_RESOURCES
;
468 sampler_views
= vbuffer
->get_sampler_view_planes(vbuffer
);
469 if (!sampler_views
) {
470 vbuffer
->destroy(vbuffer
);
471 pipe_mutex_unlock(vlsurface
->device
->mutex
);
472 return VDP_STATUS_RESOURCES
;
475 for (i
= 0; i
< 3; ++i
) {
476 struct pipe_sampler_view
*sv
= sampler_views
[i
];
479 struct pipe_box dst_box
= {
481 sv
->texture
->width0
, sv
->texture
->height0
, 1
484 pipe
->transfer_inline_write(pipe
, sv
->texture
, 0, PIPE_TRANSFER_WRITE
, &dst_box
,
485 source_data
[i
], source_pitches
[i
], 0);
490 vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_BT_601
, NULL
, 1, &csc
);
491 vl_compositor_set_csc_matrix(cstate
, (const vl_csc_matrix
*)&csc
);
493 vl_compositor_set_csc_matrix(cstate
, csc_matrix
);
496 vl_compositor_clear_layers(cstate
);
497 vl_compositor_set_buffer_layer(cstate
, compositor
, 0, vbuffer
, NULL
, NULL
, VL_COMPOSITOR_WEAVE
);
498 vl_compositor_set_layer_dst_area(cstate
, 0, RectToPipe(destination_rect
, &dst_rect
));
499 vl_compositor_render(cstate
, compositor
, vlsurface
->surface
, NULL
);
501 vbuffer
->destroy(vbuffer
);
502 pipe_mutex_unlock(vlsurface
->device
->mutex
);
504 return VDP_STATUS_OK
;
508 BlendFactorToPipe(VdpOutputSurfaceRenderBlendFactor factor
)
511 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ZERO
:
512 return PIPE_BLENDFACTOR_ZERO
;
513 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE
:
514 return PIPE_BLENDFACTOR_ONE
;
515 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_COLOR
:
516 return PIPE_BLENDFACTOR_SRC_COLOR
;
517 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_COLOR
:
518 return PIPE_BLENDFACTOR_INV_SRC_COLOR
;
519 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_ALPHA
:
520 return PIPE_BLENDFACTOR_SRC_ALPHA
;
521 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA
:
522 return PIPE_BLENDFACTOR_INV_SRC_ALPHA
;
523 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_DST_ALPHA
:
524 return PIPE_BLENDFACTOR_DST_ALPHA
;
525 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_DST_ALPHA
:
526 return PIPE_BLENDFACTOR_INV_DST_ALPHA
;
527 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_DST_COLOR
:
528 return PIPE_BLENDFACTOR_DST_COLOR
;
529 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_DST_COLOR
:
530 return PIPE_BLENDFACTOR_INV_DST_COLOR
;
531 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_ALPHA_SATURATE
:
532 return PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
;
533 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_CONSTANT_COLOR
:
534 return PIPE_BLENDFACTOR_CONST_COLOR
;
535 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR
:
536 return PIPE_BLENDFACTOR_INV_CONST_COLOR
;
537 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_CONSTANT_ALPHA
:
538 return PIPE_BLENDFACTOR_CONST_ALPHA
;
539 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA
:
540 return PIPE_BLENDFACTOR_INV_CONST_ALPHA
;
543 return PIPE_BLENDFACTOR_ONE
;
548 BlendEquationToPipe(VdpOutputSurfaceRenderBlendEquation equation
)
551 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_SUBTRACT
:
552 return PIPE_BLEND_SUBTRACT
;
553 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_REVERSE_SUBTRACT
:
554 return PIPE_BLEND_REVERSE_SUBTRACT
;
555 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD
:
556 return PIPE_BLEND_ADD
;
557 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_MIN
:
558 return PIPE_BLEND_MIN
;
559 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_MAX
:
560 return PIPE_BLEND_MAX
;
563 return PIPE_BLEND_ADD
;
568 BlenderToPipe(struct pipe_context
*context
,
569 VdpOutputSurfaceRenderBlendState
const *blend_state
)
571 struct pipe_blend_state blend
;
573 memset(&blend
, 0, sizeof blend
);
574 blend
.independent_blend_enable
= 0;
577 blend
.rt
[0].blend_enable
= 1;
578 blend
.rt
[0].rgb_src_factor
= BlendFactorToPipe(blend_state
->blend_factor_source_color
);
579 blend
.rt
[0].rgb_dst_factor
= BlendFactorToPipe(blend_state
->blend_factor_destination_color
);
580 blend
.rt
[0].alpha_src_factor
= BlendFactorToPipe(blend_state
->blend_factor_source_alpha
);
581 blend
.rt
[0].alpha_dst_factor
= BlendFactorToPipe(blend_state
->blend_factor_destination_alpha
);
582 blend
.rt
[0].rgb_func
= BlendEquationToPipe(blend_state
->blend_equation_color
);
583 blend
.rt
[0].alpha_func
= BlendEquationToPipe(blend_state
->blend_equation_alpha
);
585 blend
.rt
[0].blend_enable
= 0;
588 blend
.logicop_enable
= 0;
589 blend
.logicop_func
= PIPE_LOGICOP_CLEAR
;
590 blend
.rt
[0].colormask
= PIPE_MASK_RGBA
;
593 return context
->create_blend_state(context
, &blend
);
596 static struct vertex4f
*
597 ColorsToPipe(VdpColor
const *colors
, uint32_t flags
, struct vertex4f result
[4])
600 struct vertex4f
*dst
= result
;
605 for (i
= 0; i
< 4; ++i
) {
606 dst
->x
= colors
->red
;
607 dst
->y
= colors
->green
;
608 dst
->z
= colors
->blue
;
609 dst
->w
= colors
->alpha
;
612 if (flags
& VDP_OUTPUT_SURFACE_RENDER_COLOR_PER_VERTEX
)
619 * Composite a sub-rectangle of a VdpOutputSurface into a sub-rectangle of
620 * another VdpOutputSurface; Output Surface object VdpOutputSurface.
623 vlVdpOutputSurfaceRenderOutputSurface(VdpOutputSurface destination_surface
,
624 VdpRect
const *destination_rect
,
625 VdpOutputSurface source_surface
,
626 VdpRect
const *source_rect
,
627 VdpColor
const *colors
,
628 VdpOutputSurfaceRenderBlendState
const *blend_state
,
631 vlVdpOutputSurface
*dst_vlsurface
;
632 vlVdpOutputSurface
*src_vlsurface
;
634 struct pipe_context
*context
;
635 struct vl_compositor
*compositor
;
636 struct vl_compositor_state
*cstate
;
638 struct u_rect src_rect
, dst_rect
;
640 struct vertex4f vlcolors
[4];
643 dst_vlsurface
= vlGetDataHTAB(destination_surface
);
645 return VDP_STATUS_INVALID_HANDLE
;
647 src_vlsurface
= vlGetDataHTAB(source_surface
);
649 return VDP_STATUS_INVALID_HANDLE
;
651 if (dst_vlsurface
->device
!= src_vlsurface
->device
)
652 return VDP_STATUS_HANDLE_DEVICE_MISMATCH
;
654 pipe_mutex_lock(dst_vlsurface
->device
->mutex
);
655 vlVdpResolveDelayedRendering(dst_vlsurface
->device
, NULL
, NULL
);
657 context
= dst_vlsurface
->device
->context
;
658 compositor
= &dst_vlsurface
->device
->compositor
;
659 cstate
= &dst_vlsurface
->cstate
;
661 blend
= BlenderToPipe(context
, blend_state
);
663 vl_compositor_clear_layers(cstate
);
664 vl_compositor_set_layer_blend(cstate
, 0, blend
, false);
665 vl_compositor_set_rgba_layer(cstate
, compositor
, 0, src_vlsurface
->sampler_view
,
666 RectToPipe(source_rect
, &src_rect
), NULL
,
667 ColorsToPipe(colors
, flags
, vlcolors
));
668 vl_compositor_set_layer_dst_area(cstate
, 0, RectToPipe(destination_rect
, &dst_rect
));
669 vl_compositor_render(cstate
, compositor
, dst_vlsurface
->surface
, NULL
);
671 context
->delete_blend_state(context
, blend
);
672 pipe_mutex_unlock(dst_vlsurface
->device
->mutex
);
674 return VDP_STATUS_OK
;
678 * Composite a sub-rectangle of a VdpBitmapSurface into a sub-rectangle of
679 * a VdpOutputSurface; Output Surface object VdpOutputSurface.
682 vlVdpOutputSurfaceRenderBitmapSurface(VdpOutputSurface destination_surface
,
683 VdpRect
const *destination_rect
,
684 VdpBitmapSurface source_surface
,
685 VdpRect
const *source_rect
,
686 VdpColor
const *colors
,
687 VdpOutputSurfaceRenderBlendState
const *blend_state
,
690 vlVdpOutputSurface
*dst_vlsurface
;
691 vlVdpBitmapSurface
*src_vlsurface
;
693 struct pipe_context
*context
;
694 struct vl_compositor
*compositor
;
695 struct vl_compositor_state
*cstate
;
697 struct u_rect src_rect
, dst_rect
;
699 struct vertex4f vlcolors
[4];
702 dst_vlsurface
= vlGetDataHTAB(destination_surface
);
704 return VDP_STATUS_INVALID_HANDLE
;
706 src_vlsurface
= vlGetDataHTAB(source_surface
);
708 return VDP_STATUS_INVALID_HANDLE
;
710 if (dst_vlsurface
->device
!= src_vlsurface
->device
)
711 return VDP_STATUS_HANDLE_DEVICE_MISMATCH
;
713 context
= dst_vlsurface
->device
->context
;
714 compositor
= &dst_vlsurface
->device
->compositor
;
715 cstate
= &dst_vlsurface
->cstate
;
717 pipe_mutex_lock(dst_vlsurface
->device
->mutex
);
718 vlVdpResolveDelayedRendering(dst_vlsurface
->device
, NULL
, NULL
);
720 blend
= BlenderToPipe(context
, blend_state
);
722 vl_compositor_clear_layers(cstate
);
723 vl_compositor_set_layer_blend(cstate
, 0, blend
, false);
724 vl_compositor_set_rgba_layer(cstate
, compositor
, 0, src_vlsurface
->sampler_view
,
725 RectToPipe(source_rect
, &src_rect
), NULL
,
726 ColorsToPipe(colors
, flags
, vlcolors
));
727 vl_compositor_set_layer_dst_area(cstate
, 0, RectToPipe(destination_rect
, &dst_rect
));
728 vl_compositor_render(cstate
, compositor
, dst_vlsurface
->surface
, NULL
);
730 context
->delete_blend_state(context
, blend
);
731 pipe_mutex_unlock(dst_vlsurface
->device
->mutex
);
733 return VDP_STATUS_OK
;