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 VMWARE 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"
35 #include "util/u_surface.h"
37 #include "vl/vl_csc.h"
39 #include "vdpau_private.h"
42 * Create a VdpOutputSurface.
45 vlVdpOutputSurfaceCreate(VdpDevice device
,
46 VdpRGBAFormat rgba_format
,
47 uint32_t width
, uint32_t height
,
48 VdpOutputSurface
*surface
)
50 struct pipe_context
*pipe
;
51 struct pipe_resource res_tmpl
, *res
;
52 struct pipe_sampler_view sv_templ
;
53 struct pipe_surface surf_templ
;
55 vlVdpOutputSurface
*vlsurface
= NULL
;
57 if (!(width
&& height
))
58 return VDP_STATUS_INVALID_SIZE
;
60 vlVdpDevice
*dev
= vlGetDataHTAB(device
);
62 return VDP_STATUS_INVALID_HANDLE
;
66 return VDP_STATUS_INVALID_HANDLE
;
68 vlsurface
= CALLOC(1, sizeof(vlVdpOutputSurface
));
70 return VDP_STATUS_RESOURCES
;
72 DeviceReference(&vlsurface
->device
, dev
);
74 memset(&res_tmpl
, 0, sizeof(res_tmpl
));
76 res_tmpl
.target
= PIPE_TEXTURE_2D
;
77 res_tmpl
.format
= FormatRGBAToPipe(rgba_format
);
78 res_tmpl
.width0
= width
;
79 res_tmpl
.height0
= height
;
81 res_tmpl
.array_size
= 1;
82 res_tmpl
.bind
= PIPE_BIND_SAMPLER_VIEW
| PIPE_BIND_RENDER_TARGET
;
83 res_tmpl
.usage
= PIPE_USAGE_DEFAULT
;
85 pipe_mutex_lock(dev
->mutex
);
87 if (!CheckSurfaceParams(pipe
->screen
, &res_tmpl
))
90 res
= pipe
->screen
->resource_create(pipe
->screen
, &res_tmpl
);
94 vlVdpDefaultSamplerViewTemplate(&sv_templ
, res
);
95 vlsurface
->sampler_view
= pipe
->create_sampler_view(pipe
, res
, &sv_templ
);
96 if (!vlsurface
->sampler_view
)
99 memset(&surf_templ
, 0, sizeof(surf_templ
));
100 surf_templ
.format
= res
->format
;
101 vlsurface
->surface
= pipe
->create_surface(pipe
, res
, &surf_templ
);
102 if (!vlsurface
->surface
)
105 *surface
= vlAddDataHTAB(vlsurface
);
109 pipe_resource_reference(&res
, NULL
);
111 vl_compositor_init_state(&vlsurface
->cstate
, pipe
);
112 vl_compositor_reset_dirty_area(&vlsurface
->dirty_area
);
113 pipe_mutex_unlock(dev
->mutex
);
115 return VDP_STATUS_OK
;
118 pipe_sampler_view_reference(&vlsurface
->sampler_view
, NULL
);
119 pipe_surface_reference(&vlsurface
->surface
, NULL
);
120 pipe_resource_reference(&res
, NULL
);
122 pipe_mutex_unlock(dev
->mutex
);
123 DeviceReference(&vlsurface
->device
, NULL
);
125 return VDP_STATUS_ERROR
;
129 * Destroy a VdpOutputSurface.
132 vlVdpOutputSurfaceDestroy(VdpOutputSurface surface
)
134 vlVdpOutputSurface
*vlsurface
;
135 struct pipe_context
*pipe
;
137 vlsurface
= vlGetDataHTAB(surface
);
139 return VDP_STATUS_INVALID_HANDLE
;
141 pipe
= vlsurface
->device
->context
;
143 pipe_mutex_lock(vlsurface
->device
->mutex
);
144 vlVdpResolveDelayedRendering(vlsurface
->device
, NULL
, NULL
);
146 pipe_surface_reference(&vlsurface
->surface
, NULL
);
147 pipe_sampler_view_reference(&vlsurface
->sampler_view
, NULL
);
148 pipe
->screen
->fence_reference(pipe
->screen
, &vlsurface
->fence
, NULL
);
149 vl_compositor_cleanup_state(&vlsurface
->cstate
);
150 pipe_mutex_unlock(vlsurface
->device
->mutex
);
152 vlRemoveDataHTAB(surface
);
153 DeviceReference(&vlsurface
->device
, NULL
);
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 map
= pipe
->transfer_map(pipe
, res
, 0, PIPE_TRANSFER_READ
, &box
, &transfer
);
212 pipe_mutex_unlock(vlsurface
->device
->mutex
);
213 return VDP_STATUS_RESOURCES
;
216 util_copy_rect(*destination_data
, res
->format
, *destination_pitches
, 0, 0,
217 box
.width
, box
.height
, map
, transfer
->stride
, 0, 0);
219 pipe_transfer_unmap(pipe
, transfer
);
220 pipe_mutex_unlock(vlsurface
->device
->mutex
);
222 return VDP_STATUS_OK
;
226 * Copy image data from application memory in the surface's native format to
227 * a VdpOutputSurface.
230 vlVdpOutputSurfacePutBitsNative(VdpOutputSurface surface
,
231 void const *const *source_data
,
232 uint32_t const *source_pitches
,
233 VdpRect
const *destination_rect
)
235 vlVdpOutputSurface
*vlsurface
;
236 struct pipe_box dst_box
;
237 struct pipe_context
*pipe
;
239 vlsurface
= vlGetDataHTAB(surface
);
241 return VDP_STATUS_INVALID_HANDLE
;
243 pipe
= vlsurface
->device
->context
;
245 return VDP_STATUS_INVALID_HANDLE
;
247 pipe_mutex_lock(vlsurface
->device
->mutex
);
248 vlVdpResolveDelayedRendering(vlsurface
->device
, NULL
, NULL
);
250 dst_box
= RectToPipeBox(destination_rect
, vlsurface
->sampler_view
->texture
);
251 pipe
->transfer_inline_write(pipe
, vlsurface
->sampler_view
->texture
, 0,
252 PIPE_TRANSFER_WRITE
, &dst_box
, *source_data
,
254 pipe_mutex_unlock(vlsurface
->device
->mutex
);
256 return VDP_STATUS_OK
;
260 * Copy image data from application memory in a specific indexed format to
261 * a VdpOutputSurface.
264 vlVdpOutputSurfacePutBitsIndexed(VdpOutputSurface surface
,
265 VdpIndexedFormat source_indexed_format
,
266 void const *const *source_data
,
267 uint32_t const *source_pitch
,
268 VdpRect
const *destination_rect
,
269 VdpColorTableFormat color_table_format
,
270 void const *color_table
)
272 vlVdpOutputSurface
*vlsurface
;
273 struct pipe_context
*context
;
274 struct vl_compositor
*compositor
;
275 struct vl_compositor_state
*cstate
;
277 enum pipe_format index_format
;
278 enum pipe_format colortbl_format
;
280 struct pipe_resource
*res
, res_tmpl
;
281 struct pipe_sampler_view sv_tmpl
;
282 struct pipe_sampler_view
*sv_idx
= NULL
, *sv_tbl
= NULL
;
285 struct u_rect dst_rect
;
287 vlsurface
= vlGetDataHTAB(surface
);
289 return VDP_STATUS_INVALID_HANDLE
;
291 context
= vlsurface
->device
->context
;
292 compositor
= &vlsurface
->device
->compositor
;
293 cstate
= &vlsurface
->cstate
;
295 index_format
= FormatIndexedToPipe(source_indexed_format
);
296 if (index_format
== PIPE_FORMAT_NONE
)
297 return VDP_STATUS_INVALID_INDEXED_FORMAT
;
299 if (!source_data
|| !source_pitch
)
300 return VDP_STATUS_INVALID_POINTER
;
302 colortbl_format
= FormatColorTableToPipe(color_table_format
);
303 if (colortbl_format
== PIPE_FORMAT_NONE
)
304 return VDP_STATUS_INVALID_COLOR_TABLE_FORMAT
;
307 return VDP_STATUS_INVALID_POINTER
;
309 memset(&res_tmpl
, 0, sizeof(res_tmpl
));
310 res_tmpl
.target
= PIPE_TEXTURE_2D
;
311 res_tmpl
.format
= index_format
;
313 if (destination_rect
) {
314 res_tmpl
.width0
= abs(destination_rect
->x0
-destination_rect
->x1
);
315 res_tmpl
.height0
= abs(destination_rect
->y0
-destination_rect
->y1
);
317 res_tmpl
.width0
= vlsurface
->surface
->texture
->width0
;
318 res_tmpl
.height0
= vlsurface
->surface
->texture
->height0
;
321 res_tmpl
.array_size
= 1;
322 res_tmpl
.usage
= PIPE_USAGE_STAGING
;
323 res_tmpl
.bind
= PIPE_BIND_SAMPLER_VIEW
;
325 pipe_mutex_lock(vlsurface
->device
->mutex
);
326 vlVdpResolveDelayedRendering(vlsurface
->device
, NULL
, NULL
);
328 if (!CheckSurfaceParams(context
->screen
, &res_tmpl
))
331 res
= context
->screen
->resource_create(context
->screen
, &res_tmpl
);
335 box
.x
= box
.y
= box
.z
= 0;
336 box
.width
= res
->width0
;
337 box
.height
= res
->height0
;
338 box
.depth
= res
->depth0
;
340 context
->transfer_inline_write(context
, res
, 0, PIPE_TRANSFER_WRITE
, &box
,
341 source_data
[0], source_pitch
[0],
342 source_pitch
[0] * res
->height0
);
344 memset(&sv_tmpl
, 0, sizeof(sv_tmpl
));
345 u_sampler_view_default_template(&sv_tmpl
, res
, res
->format
);
347 sv_idx
= context
->create_sampler_view(context
, res
, &sv_tmpl
);
348 pipe_resource_reference(&res
, NULL
);
353 memset(&res_tmpl
, 0, sizeof(res_tmpl
));
354 res_tmpl
.target
= PIPE_TEXTURE_1D
;
355 res_tmpl
.format
= colortbl_format
;
356 res_tmpl
.width0
= 1 << util_format_get_component_bits(
357 index_format
, UTIL_FORMAT_COLORSPACE_RGB
, 0);
358 res_tmpl
.height0
= 1;
360 res_tmpl
.array_size
= 1;
361 res_tmpl
.usage
= PIPE_USAGE_STAGING
;
362 res_tmpl
.bind
= PIPE_BIND_SAMPLER_VIEW
;
364 res
= context
->screen
->resource_create(context
->screen
, &res_tmpl
);
368 box
.x
= box
.y
= box
.z
= 0;
369 box
.width
= res
->width0
;
370 box
.height
= res
->height0
;
371 box
.depth
= res
->depth0
;
373 context
->transfer_inline_write(context
, res
, 0, PIPE_TRANSFER_WRITE
, &box
, color_table
,
374 util_format_get_stride(colortbl_format
, res
->width0
), 0);
376 memset(&sv_tmpl
, 0, sizeof(sv_tmpl
));
377 u_sampler_view_default_template(&sv_tmpl
, res
, res
->format
);
379 sv_tbl
= context
->create_sampler_view(context
, res
, &sv_tmpl
);
380 pipe_resource_reference(&res
, NULL
);
385 vl_compositor_clear_layers(cstate
);
386 vl_compositor_set_palette_layer(cstate
, compositor
, 0, sv_idx
, sv_tbl
, NULL
, NULL
, false);
387 vl_compositor_set_layer_dst_area(cstate
, 0, RectToPipe(destination_rect
, &dst_rect
));
388 vl_compositor_render(cstate
, compositor
, vlsurface
->surface
, &vlsurface
->dirty_area
, false);
390 pipe_sampler_view_reference(&sv_idx
, NULL
);
391 pipe_sampler_view_reference(&sv_tbl
, NULL
);
392 pipe_mutex_unlock(vlsurface
->device
->mutex
);
394 return VDP_STATUS_OK
;
397 pipe_sampler_view_reference(&sv_idx
, NULL
);
398 pipe_sampler_view_reference(&sv_tbl
, NULL
);
399 pipe_mutex_unlock(vlsurface
->device
->mutex
);
400 return VDP_STATUS_RESOURCES
;
404 * Copy image data from application memory in a specific YCbCr format to
405 * a VdpOutputSurface.
408 vlVdpOutputSurfacePutBitsYCbCr(VdpOutputSurface surface
,
409 VdpYCbCrFormat source_ycbcr_format
,
410 void const *const *source_data
,
411 uint32_t const *source_pitches
,
412 VdpRect
const *destination_rect
,
413 VdpCSCMatrix
const *csc_matrix
)
415 vlVdpOutputSurface
*vlsurface
;
416 struct vl_compositor
*compositor
;
417 struct vl_compositor_state
*cstate
;
419 struct pipe_context
*pipe
;
420 enum pipe_format format
;
421 struct pipe_video_buffer vtmpl
, *vbuffer
;
422 struct u_rect dst_rect
;
423 struct pipe_sampler_view
**sampler_views
;
427 vlsurface
= vlGetDataHTAB(surface
);
429 return VDP_STATUS_INVALID_HANDLE
;
432 pipe
= vlsurface
->device
->context
;
433 compositor
= &vlsurface
->device
->compositor
;
434 cstate
= &vlsurface
->cstate
;
436 format
= FormatYCBCRToPipe(source_ycbcr_format
);
437 if (format
== PIPE_FORMAT_NONE
)
438 return VDP_STATUS_INVALID_Y_CB_CR_FORMAT
;
440 if (!source_data
|| !source_pitches
)
441 return VDP_STATUS_INVALID_POINTER
;
443 pipe_mutex_lock(vlsurface
->device
->mutex
);
444 vlVdpResolveDelayedRendering(vlsurface
->device
, NULL
, NULL
);
445 memset(&vtmpl
, 0, sizeof(vtmpl
));
446 vtmpl
.buffer_format
= format
;
447 vtmpl
.chroma_format
= FormatYCBCRToPipeChroma(source_ycbcr_format
);
449 if (destination_rect
) {
450 vtmpl
.width
= abs(destination_rect
->x0
-destination_rect
->x1
);
451 vtmpl
.height
= abs(destination_rect
->y0
-destination_rect
->y1
);
453 vtmpl
.width
= vlsurface
->surface
->texture
->width0
;
454 vtmpl
.height
= vlsurface
->surface
->texture
->height0
;
457 vbuffer
= pipe
->create_video_buffer(pipe
, &vtmpl
);
459 pipe_mutex_unlock(vlsurface
->device
->mutex
);
460 return VDP_STATUS_RESOURCES
;
463 sampler_views
= vbuffer
->get_sampler_view_planes(vbuffer
);
464 if (!sampler_views
) {
465 vbuffer
->destroy(vbuffer
);
466 pipe_mutex_unlock(vlsurface
->device
->mutex
);
467 return VDP_STATUS_RESOURCES
;
470 for (i
= 0; i
< 3; ++i
) {
471 struct pipe_sampler_view
*sv
= sampler_views
[i
];
474 struct pipe_box dst_box
= {
476 sv
->texture
->width0
, sv
->texture
->height0
, 1
479 pipe
->transfer_inline_write(pipe
, sv
->texture
, 0, PIPE_TRANSFER_WRITE
, &dst_box
,
480 source_data
[i
], source_pitches
[i
], 0);
485 vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_BT_601
, NULL
, 1, &csc
);
486 vl_compositor_set_csc_matrix(cstate
, (const vl_csc_matrix
*)&csc
);
488 vl_compositor_set_csc_matrix(cstate
, csc_matrix
);
491 vl_compositor_clear_layers(cstate
);
492 vl_compositor_set_buffer_layer(cstate
, compositor
, 0, vbuffer
, NULL
, NULL
, VL_COMPOSITOR_WEAVE
);
493 vl_compositor_set_layer_dst_area(cstate
, 0, RectToPipe(destination_rect
, &dst_rect
));
494 vl_compositor_render(cstate
, compositor
, vlsurface
->surface
, &vlsurface
->dirty_area
, false);
496 vbuffer
->destroy(vbuffer
);
497 pipe_mutex_unlock(vlsurface
->device
->mutex
);
499 return VDP_STATUS_OK
;
503 BlendFactorToPipe(VdpOutputSurfaceRenderBlendFactor factor
)
506 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ZERO
:
507 return PIPE_BLENDFACTOR_ZERO
;
508 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE
:
509 return PIPE_BLENDFACTOR_ONE
;
510 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_COLOR
:
511 return PIPE_BLENDFACTOR_SRC_COLOR
;
512 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_COLOR
:
513 return PIPE_BLENDFACTOR_INV_SRC_COLOR
;
514 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_ALPHA
:
515 return PIPE_BLENDFACTOR_SRC_ALPHA
;
516 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA
:
517 return PIPE_BLENDFACTOR_INV_SRC_ALPHA
;
518 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_DST_ALPHA
:
519 return PIPE_BLENDFACTOR_DST_ALPHA
;
520 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_DST_ALPHA
:
521 return PIPE_BLENDFACTOR_INV_DST_ALPHA
;
522 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_DST_COLOR
:
523 return PIPE_BLENDFACTOR_DST_COLOR
;
524 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_DST_COLOR
:
525 return PIPE_BLENDFACTOR_INV_DST_COLOR
;
526 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_ALPHA_SATURATE
:
527 return PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
;
528 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_CONSTANT_COLOR
:
529 return PIPE_BLENDFACTOR_CONST_COLOR
;
530 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR
:
531 return PIPE_BLENDFACTOR_INV_CONST_COLOR
;
532 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_CONSTANT_ALPHA
:
533 return PIPE_BLENDFACTOR_CONST_ALPHA
;
534 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA
:
535 return PIPE_BLENDFACTOR_INV_CONST_ALPHA
;
538 return PIPE_BLENDFACTOR_ONE
;
543 BlendEquationToPipe(VdpOutputSurfaceRenderBlendEquation equation
)
546 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_SUBTRACT
:
547 return PIPE_BLEND_SUBTRACT
;
548 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_REVERSE_SUBTRACT
:
549 return PIPE_BLEND_REVERSE_SUBTRACT
;
550 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD
:
551 return PIPE_BLEND_ADD
;
552 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_MIN
:
553 return PIPE_BLEND_MIN
;
554 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_MAX
:
555 return PIPE_BLEND_MAX
;
558 return PIPE_BLEND_ADD
;
563 BlenderToPipe(struct pipe_context
*context
,
564 VdpOutputSurfaceRenderBlendState
const *blend_state
)
566 struct pipe_blend_state blend
;
568 memset(&blend
, 0, sizeof blend
);
569 blend
.independent_blend_enable
= 0;
572 blend
.rt
[0].blend_enable
= 1;
573 blend
.rt
[0].rgb_src_factor
= BlendFactorToPipe(blend_state
->blend_factor_source_color
);
574 blend
.rt
[0].rgb_dst_factor
= BlendFactorToPipe(blend_state
->blend_factor_destination_color
);
575 blend
.rt
[0].alpha_src_factor
= BlendFactorToPipe(blend_state
->blend_factor_source_alpha
);
576 blend
.rt
[0].alpha_dst_factor
= BlendFactorToPipe(blend_state
->blend_factor_destination_alpha
);
577 blend
.rt
[0].rgb_func
= BlendEquationToPipe(blend_state
->blend_equation_color
);
578 blend
.rt
[0].alpha_func
= BlendEquationToPipe(blend_state
->blend_equation_alpha
);
580 blend
.rt
[0].blend_enable
= 0;
583 blend
.logicop_enable
= 0;
584 blend
.logicop_func
= PIPE_LOGICOP_CLEAR
;
585 blend
.rt
[0].colormask
= PIPE_MASK_RGBA
;
588 return context
->create_blend_state(context
, &blend
);
591 static struct vertex4f
*
592 ColorsToPipe(VdpColor
const *colors
, uint32_t flags
, struct vertex4f result
[4])
595 struct vertex4f
*dst
= result
;
600 for (i
= 0; i
< 4; ++i
) {
601 dst
->x
= colors
->red
;
602 dst
->y
= colors
->green
;
603 dst
->z
= colors
->blue
;
604 dst
->w
= colors
->alpha
;
607 if (flags
& VDP_OUTPUT_SURFACE_RENDER_COLOR_PER_VERTEX
)
614 * Composite a sub-rectangle of a VdpOutputSurface into a sub-rectangle of
615 * another VdpOutputSurface; Output Surface object VdpOutputSurface.
618 vlVdpOutputSurfaceRenderOutputSurface(VdpOutputSurface destination_surface
,
619 VdpRect
const *destination_rect
,
620 VdpOutputSurface source_surface
,
621 VdpRect
const *source_rect
,
622 VdpColor
const *colors
,
623 VdpOutputSurfaceRenderBlendState
const *blend_state
,
626 vlVdpOutputSurface
*dst_vlsurface
;
628 struct pipe_context
*context
;
629 struct pipe_sampler_view
*src_sv
;
630 struct vl_compositor
*compositor
;
631 struct vl_compositor_state
*cstate
;
633 struct u_rect src_rect
, dst_rect
;
635 struct vertex4f vlcolors
[4];
638 dst_vlsurface
= vlGetDataHTAB(destination_surface
);
640 return VDP_STATUS_INVALID_HANDLE
;
642 if (source_surface
== VDP_INVALID_HANDLE
) {
643 src_sv
= dst_vlsurface
->device
->dummy_sv
;
646 vlVdpOutputSurface
*src_vlsurface
= vlGetDataHTAB(source_surface
);
648 return VDP_STATUS_INVALID_HANDLE
;
650 if (dst_vlsurface
->device
!= src_vlsurface
->device
)
651 return VDP_STATUS_HANDLE_DEVICE_MISMATCH
;
653 src_sv
= src_vlsurface
->sampler_view
;
656 pipe_mutex_lock(dst_vlsurface
->device
->mutex
);
657 vlVdpResolveDelayedRendering(dst_vlsurface
->device
, NULL
, NULL
);
659 context
= dst_vlsurface
->device
->context
;
660 compositor
= &dst_vlsurface
->device
->compositor
;
661 cstate
= &dst_vlsurface
->cstate
;
663 blend
= BlenderToPipe(context
, blend_state
);
665 vl_compositor_clear_layers(cstate
);
666 vl_compositor_set_layer_blend(cstate
, 0, blend
, false);
667 vl_compositor_set_rgba_layer(cstate
, compositor
, 0, src_sv
,
668 RectToPipe(source_rect
, &src_rect
), NULL
,
669 ColorsToPipe(colors
, flags
, vlcolors
));
670 STATIC_ASSERT(VL_COMPOSITOR_ROTATE_0
== VDP_OUTPUT_SURFACE_RENDER_ROTATE_0
);
671 STATIC_ASSERT(VL_COMPOSITOR_ROTATE_90
== VDP_OUTPUT_SURFACE_RENDER_ROTATE_90
);
672 STATIC_ASSERT(VL_COMPOSITOR_ROTATE_180
== VDP_OUTPUT_SURFACE_RENDER_ROTATE_180
);
673 STATIC_ASSERT(VL_COMPOSITOR_ROTATE_270
== VDP_OUTPUT_SURFACE_RENDER_ROTATE_270
);
674 vl_compositor_set_layer_rotation(cstate
, 0, flags
& 3);
675 vl_compositor_set_layer_dst_area(cstate
, 0, RectToPipe(destination_rect
, &dst_rect
));
676 vl_compositor_render(cstate
, compositor
, dst_vlsurface
->surface
, &dst_vlsurface
->dirty_area
, false);
678 context
->delete_blend_state(context
, blend
);
679 pipe_mutex_unlock(dst_vlsurface
->device
->mutex
);
681 return VDP_STATUS_OK
;
685 * Composite a sub-rectangle of a VdpBitmapSurface into a sub-rectangle of
686 * a VdpOutputSurface; Output Surface object VdpOutputSurface.
689 vlVdpOutputSurfaceRenderBitmapSurface(VdpOutputSurface destination_surface
,
690 VdpRect
const *destination_rect
,
691 VdpBitmapSurface source_surface
,
692 VdpRect
const *source_rect
,
693 VdpColor
const *colors
,
694 VdpOutputSurfaceRenderBlendState
const *blend_state
,
697 vlVdpOutputSurface
*dst_vlsurface
;
699 struct pipe_context
*context
;
700 struct pipe_sampler_view
*src_sv
;
701 struct vl_compositor
*compositor
;
702 struct vl_compositor_state
*cstate
;
704 struct u_rect src_rect
, dst_rect
;
706 struct vertex4f vlcolors
[4];
709 dst_vlsurface
= vlGetDataHTAB(destination_surface
);
711 return VDP_STATUS_INVALID_HANDLE
;
713 if (source_surface
== VDP_INVALID_HANDLE
) {
714 src_sv
= dst_vlsurface
->device
->dummy_sv
;
717 vlVdpBitmapSurface
*src_vlsurface
= vlGetDataHTAB(source_surface
);
719 return VDP_STATUS_INVALID_HANDLE
;
721 if (dst_vlsurface
->device
!= src_vlsurface
->device
)
722 return VDP_STATUS_HANDLE_DEVICE_MISMATCH
;
724 src_sv
= src_vlsurface
->sampler_view
;
727 context
= dst_vlsurface
->device
->context
;
728 compositor
= &dst_vlsurface
->device
->compositor
;
729 cstate
= &dst_vlsurface
->cstate
;
731 pipe_mutex_lock(dst_vlsurface
->device
->mutex
);
732 vlVdpResolveDelayedRendering(dst_vlsurface
->device
, NULL
, NULL
);
734 blend
= BlenderToPipe(context
, blend_state
);
736 vl_compositor_clear_layers(cstate
);
737 vl_compositor_set_layer_blend(cstate
, 0, blend
, false);
738 vl_compositor_set_rgba_layer(cstate
, compositor
, 0, src_sv
,
739 RectToPipe(source_rect
, &src_rect
), NULL
,
740 ColorsToPipe(colors
, flags
, vlcolors
));
741 vl_compositor_set_layer_rotation(cstate
, 0, flags
& 3);
742 vl_compositor_set_layer_dst_area(cstate
, 0, RectToPipe(destination_rect
, &dst_rect
));
743 vl_compositor_render(cstate
, compositor
, dst_vlsurface
->surface
, &dst_vlsurface
->dirty_area
, false);
745 context
->delete_blend_state(context
, blend
);
746 pipe_mutex_unlock(dst_vlsurface
->device
->mutex
);
748 return VDP_STATUS_OK
;
751 struct pipe_resource
*vlVdpOutputSurfaceGallium(VdpOutputSurface surface
)
753 vlVdpOutputSurface
*vlsurface
;
755 vlsurface
= vlGetDataHTAB(surface
);
756 if (!vlsurface
|| !vlsurface
->surface
)
759 pipe_mutex_lock(vlsurface
->device
->mutex
);
760 vlVdpResolveDelayedRendering(vlsurface
->device
, NULL
, NULL
);
761 vlsurface
->device
->context
->flush(vlsurface
->device
->context
, NULL
, 0);
762 pipe_mutex_unlock(vlsurface
->device
->mutex
);
764 return vlsurface
->surface
->texture
;