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 "state_tracker/drm_driver.h"
41 #include "vdpau_private.h"
44 * Create a VdpOutputSurface.
47 vlVdpOutputSurfaceCreate(VdpDevice device
,
48 VdpRGBAFormat rgba_format
,
49 uint32_t width
, uint32_t height
,
50 VdpOutputSurface
*surface
)
52 struct pipe_context
*pipe
;
53 struct pipe_resource res_tmpl
, *res
;
54 struct pipe_sampler_view sv_templ
;
55 struct pipe_surface surf_templ
;
57 vlVdpOutputSurface
*vlsurface
= NULL
;
59 if (!(width
&& height
))
60 return VDP_STATUS_INVALID_SIZE
;
62 vlVdpDevice
*dev
= vlGetDataHTAB(device
);
64 return VDP_STATUS_INVALID_HANDLE
;
68 return VDP_STATUS_INVALID_HANDLE
;
70 vlsurface
= CALLOC(1, sizeof(vlVdpOutputSurface
));
72 return VDP_STATUS_RESOURCES
;
74 DeviceReference(&vlsurface
->device
, dev
);
76 memset(&res_tmpl
, 0, sizeof(res_tmpl
));
79 * The output won't look correctly when this buffer is send to X,
80 * if the VDPAU RGB component order doesn't match the X11 one so
81 * we only allow the X11 format
83 vlsurface
->send_to_X
= rgba_format
== VDP_RGBA_FORMAT_B8G8R8A8
;
85 res_tmpl
.target
= PIPE_TEXTURE_2D
;
86 res_tmpl
.format
= VdpFormatRGBAToPipe(rgba_format
);
87 res_tmpl
.width0
= width
;
88 res_tmpl
.height0
= height
;
90 res_tmpl
.array_size
= 1;
91 res_tmpl
.bind
= PIPE_BIND_SAMPLER_VIEW
| PIPE_BIND_RENDER_TARGET
|
92 PIPE_BIND_SHARED
| PIPE_BIND_SCANOUT
;
93 res_tmpl
.usage
= PIPE_USAGE_DEFAULT
;
95 pipe_mutex_lock(dev
->mutex
);
97 if (!CheckSurfaceParams(pipe
->screen
, &res_tmpl
))
100 res
= pipe
->screen
->resource_create(pipe
->screen
, &res_tmpl
);
104 vlVdpDefaultSamplerViewTemplate(&sv_templ
, res
);
105 vlsurface
->sampler_view
= pipe
->create_sampler_view(pipe
, res
, &sv_templ
);
106 if (!vlsurface
->sampler_view
)
109 memset(&surf_templ
, 0, sizeof(surf_templ
));
110 surf_templ
.format
= res
->format
;
111 vlsurface
->surface
= pipe
->create_surface(pipe
, res
, &surf_templ
);
112 if (!vlsurface
->surface
)
115 *surface
= vlAddDataHTAB(vlsurface
);
119 pipe_resource_reference(&res
, NULL
);
121 if (!vl_compositor_init_state(&vlsurface
->cstate
, pipe
))
124 vl_compositor_reset_dirty_area(&vlsurface
->dirty_area
);
125 pipe_mutex_unlock(dev
->mutex
);
127 return VDP_STATUS_OK
;
130 pipe_sampler_view_reference(&vlsurface
->sampler_view
, NULL
);
131 pipe_surface_reference(&vlsurface
->surface
, NULL
);
132 pipe_resource_reference(&res
, NULL
);
134 pipe_mutex_unlock(dev
->mutex
);
135 DeviceReference(&vlsurface
->device
, NULL
);
137 return VDP_STATUS_ERROR
;
141 * Destroy a VdpOutputSurface.
144 vlVdpOutputSurfaceDestroy(VdpOutputSurface surface
)
146 vlVdpOutputSurface
*vlsurface
;
147 struct pipe_context
*pipe
;
149 vlsurface
= vlGetDataHTAB(surface
);
151 return VDP_STATUS_INVALID_HANDLE
;
153 pipe
= vlsurface
->device
->context
;
155 pipe_mutex_lock(vlsurface
->device
->mutex
);
157 pipe_surface_reference(&vlsurface
->surface
, NULL
);
158 pipe_sampler_view_reference(&vlsurface
->sampler_view
, NULL
);
159 pipe
->screen
->fence_reference(pipe
->screen
, &vlsurface
->fence
, NULL
);
160 vl_compositor_cleanup_state(&vlsurface
->cstate
);
161 pipe_mutex_unlock(vlsurface
->device
->mutex
);
163 vlRemoveDataHTAB(surface
);
164 DeviceReference(&vlsurface
->device
, NULL
);
167 return VDP_STATUS_OK
;
171 * Retrieve the parameters used to create a VdpOutputSurface.
174 vlVdpOutputSurfaceGetParameters(VdpOutputSurface surface
,
175 VdpRGBAFormat
*rgba_format
,
176 uint32_t *width
, uint32_t *height
)
178 vlVdpOutputSurface
*vlsurface
;
180 vlsurface
= vlGetDataHTAB(surface
);
182 return VDP_STATUS_INVALID_HANDLE
;
184 *rgba_format
= PipeToFormatRGBA(vlsurface
->sampler_view
->texture
->format
);
185 *width
= vlsurface
->sampler_view
->texture
->width0
;
186 *height
= vlsurface
->sampler_view
->texture
->height0
;
188 return VDP_STATUS_OK
;
192 * Copy image data from a VdpOutputSurface to application memory in the
193 * surface's native format.
196 vlVdpOutputSurfaceGetBitsNative(VdpOutputSurface surface
,
197 VdpRect
const *source_rect
,
198 void *const *destination_data
,
199 uint32_t const *destination_pitches
)
201 vlVdpOutputSurface
*vlsurface
;
202 struct pipe_context
*pipe
;
203 struct pipe_resource
*res
;
205 struct pipe_transfer
*transfer
;
208 vlsurface
= vlGetDataHTAB(surface
);
210 return VDP_STATUS_INVALID_HANDLE
;
212 pipe
= vlsurface
->device
->context
;
214 return VDP_STATUS_INVALID_HANDLE
;
216 if (!destination_data
|| !destination_pitches
)
217 return VDP_STATUS_INVALID_POINTER
;
219 pipe_mutex_lock(vlsurface
->device
->mutex
);
221 res
= vlsurface
->sampler_view
->texture
;
222 box
= RectToPipeBox(source_rect
, res
);
223 map
= pipe
->transfer_map(pipe
, res
, 0, PIPE_TRANSFER_READ
, &box
, &transfer
);
225 pipe_mutex_unlock(vlsurface
->device
->mutex
);
226 return VDP_STATUS_RESOURCES
;
229 util_copy_rect(*destination_data
, res
->format
, *destination_pitches
, 0, 0,
230 box
.width
, box
.height
, map
, transfer
->stride
, 0, 0);
232 pipe_transfer_unmap(pipe
, transfer
);
233 pipe_mutex_unlock(vlsurface
->device
->mutex
);
235 return VDP_STATUS_OK
;
239 * Copy image data from application memory in the surface's native format to
240 * a VdpOutputSurface.
243 vlVdpOutputSurfacePutBitsNative(VdpOutputSurface surface
,
244 void const *const *source_data
,
245 uint32_t const *source_pitches
,
246 VdpRect
const *destination_rect
)
248 vlVdpOutputSurface
*vlsurface
;
249 struct pipe_box dst_box
;
250 struct pipe_context
*pipe
;
252 vlsurface
= vlGetDataHTAB(surface
);
254 return VDP_STATUS_INVALID_HANDLE
;
256 pipe
= vlsurface
->device
->context
;
258 return VDP_STATUS_INVALID_HANDLE
;
260 if (!source_data
|| !source_pitches
)
261 return VDP_STATUS_INVALID_POINTER
;
263 pipe_mutex_lock(vlsurface
->device
->mutex
);
265 dst_box
= RectToPipeBox(destination_rect
, vlsurface
->sampler_view
->texture
);
267 /* Check for a no-op. (application bug?) */
268 if (!dst_box
.width
|| !dst_box
.height
) {
269 pipe_mutex_unlock(vlsurface
->device
->mutex
);
270 return VDP_STATUS_OK
;
273 pipe
->texture_subdata(pipe
, vlsurface
->sampler_view
->texture
, 0,
274 PIPE_TRANSFER_WRITE
, &dst_box
, *source_data
,
276 pipe_mutex_unlock(vlsurface
->device
->mutex
);
278 return VDP_STATUS_OK
;
282 * Copy image data from application memory in a specific indexed format to
283 * a VdpOutputSurface.
286 vlVdpOutputSurfacePutBitsIndexed(VdpOutputSurface surface
,
287 VdpIndexedFormat source_indexed_format
,
288 void const *const *source_data
,
289 uint32_t const *source_pitch
,
290 VdpRect
const *destination_rect
,
291 VdpColorTableFormat color_table_format
,
292 void const *color_table
)
294 vlVdpOutputSurface
*vlsurface
;
295 struct pipe_context
*context
;
296 struct vl_compositor
*compositor
;
297 struct vl_compositor_state
*cstate
;
299 enum pipe_format index_format
;
300 enum pipe_format colortbl_format
;
302 struct pipe_resource
*res
, res_tmpl
;
303 struct pipe_sampler_view sv_tmpl
;
304 struct pipe_sampler_view
*sv_idx
= NULL
, *sv_tbl
= NULL
;
307 struct u_rect dst_rect
;
309 vlsurface
= vlGetDataHTAB(surface
);
311 return VDP_STATUS_INVALID_HANDLE
;
313 context
= vlsurface
->device
->context
;
314 compositor
= &vlsurface
->device
->compositor
;
315 cstate
= &vlsurface
->cstate
;
317 index_format
= FormatIndexedToPipe(source_indexed_format
);
318 if (index_format
== PIPE_FORMAT_NONE
)
319 return VDP_STATUS_INVALID_INDEXED_FORMAT
;
321 if (!source_data
|| !source_pitch
)
322 return VDP_STATUS_INVALID_POINTER
;
324 colortbl_format
= FormatColorTableToPipe(color_table_format
);
325 if (colortbl_format
== PIPE_FORMAT_NONE
)
326 return VDP_STATUS_INVALID_COLOR_TABLE_FORMAT
;
329 return VDP_STATUS_INVALID_POINTER
;
331 memset(&res_tmpl
, 0, sizeof(res_tmpl
));
332 res_tmpl
.target
= PIPE_TEXTURE_2D
;
333 res_tmpl
.format
= index_format
;
335 if (destination_rect
) {
336 res_tmpl
.width0
= abs(destination_rect
->x0
-destination_rect
->x1
);
337 res_tmpl
.height0
= abs(destination_rect
->y0
-destination_rect
->y1
);
339 res_tmpl
.width0
= vlsurface
->surface
->texture
->width0
;
340 res_tmpl
.height0
= vlsurface
->surface
->texture
->height0
;
343 res_tmpl
.array_size
= 1;
344 res_tmpl
.usage
= PIPE_USAGE_STAGING
;
345 res_tmpl
.bind
= PIPE_BIND_SAMPLER_VIEW
;
347 pipe_mutex_lock(vlsurface
->device
->mutex
);
349 if (!CheckSurfaceParams(context
->screen
, &res_tmpl
))
352 res
= context
->screen
->resource_create(context
->screen
, &res_tmpl
);
356 box
.x
= box
.y
= box
.z
= 0;
357 box
.width
= res
->width0
;
358 box
.height
= res
->height0
;
359 box
.depth
= res
->depth0
;
361 context
->texture_subdata(context
, res
, 0, PIPE_TRANSFER_WRITE
, &box
,
362 source_data
[0], source_pitch
[0],
363 source_pitch
[0] * res
->height0
);
365 memset(&sv_tmpl
, 0, sizeof(sv_tmpl
));
366 u_sampler_view_default_template(&sv_tmpl
, res
, res
->format
);
368 sv_idx
= context
->create_sampler_view(context
, res
, &sv_tmpl
);
369 pipe_resource_reference(&res
, NULL
);
374 memset(&res_tmpl
, 0, sizeof(res_tmpl
));
375 res_tmpl
.target
= PIPE_TEXTURE_1D
;
376 res_tmpl
.format
= colortbl_format
;
377 res_tmpl
.width0
= 1 << util_format_get_component_bits(
378 index_format
, UTIL_FORMAT_COLORSPACE_RGB
, 0);
379 res_tmpl
.height0
= 1;
381 res_tmpl
.array_size
= 1;
382 res_tmpl
.usage
= PIPE_USAGE_STAGING
;
383 res_tmpl
.bind
= PIPE_BIND_SAMPLER_VIEW
;
385 res
= context
->screen
->resource_create(context
->screen
, &res_tmpl
);
389 box
.x
= box
.y
= box
.z
= 0;
390 box
.width
= res
->width0
;
391 box
.height
= res
->height0
;
392 box
.depth
= res
->depth0
;
394 context
->texture_subdata(context
, res
, 0, PIPE_TRANSFER_WRITE
, &box
, color_table
,
395 util_format_get_stride(colortbl_format
, res
->width0
), 0);
397 memset(&sv_tmpl
, 0, sizeof(sv_tmpl
));
398 u_sampler_view_default_template(&sv_tmpl
, res
, res
->format
);
400 sv_tbl
= context
->create_sampler_view(context
, res
, &sv_tmpl
);
401 pipe_resource_reference(&res
, NULL
);
406 vl_compositor_clear_layers(cstate
);
407 vl_compositor_set_palette_layer(cstate
, compositor
, 0, sv_idx
, sv_tbl
, NULL
, NULL
, false);
408 vl_compositor_set_layer_dst_area(cstate
, 0, RectToPipe(destination_rect
, &dst_rect
));
409 vl_compositor_render(cstate
, compositor
, vlsurface
->surface
, &vlsurface
->dirty_area
, false);
411 pipe_sampler_view_reference(&sv_idx
, NULL
);
412 pipe_sampler_view_reference(&sv_tbl
, NULL
);
413 pipe_mutex_unlock(vlsurface
->device
->mutex
);
415 return VDP_STATUS_OK
;
418 pipe_sampler_view_reference(&sv_idx
, NULL
);
419 pipe_sampler_view_reference(&sv_tbl
, NULL
);
420 pipe_mutex_unlock(vlsurface
->device
->mutex
);
421 return VDP_STATUS_RESOURCES
;
425 * Copy image data from application memory in a specific YCbCr format to
426 * a VdpOutputSurface.
429 vlVdpOutputSurfacePutBitsYCbCr(VdpOutputSurface surface
,
430 VdpYCbCrFormat source_ycbcr_format
,
431 void const *const *source_data
,
432 uint32_t const *source_pitches
,
433 VdpRect
const *destination_rect
,
434 VdpCSCMatrix
const *csc_matrix
)
436 vlVdpOutputSurface
*vlsurface
;
437 struct vl_compositor
*compositor
;
438 struct vl_compositor_state
*cstate
;
440 struct pipe_context
*pipe
;
441 enum pipe_format format
;
442 struct pipe_video_buffer vtmpl
, *vbuffer
;
443 struct u_rect dst_rect
;
444 struct pipe_sampler_view
**sampler_views
;
448 vlsurface
= vlGetDataHTAB(surface
);
450 return VDP_STATUS_INVALID_HANDLE
;
453 pipe
= vlsurface
->device
->context
;
454 compositor
= &vlsurface
->device
->compositor
;
455 cstate
= &vlsurface
->cstate
;
457 format
= FormatYCBCRToPipe(source_ycbcr_format
);
458 if (format
== PIPE_FORMAT_NONE
)
459 return VDP_STATUS_INVALID_Y_CB_CR_FORMAT
;
461 if (!source_data
|| !source_pitches
)
462 return VDP_STATUS_INVALID_POINTER
;
464 pipe_mutex_lock(vlsurface
->device
->mutex
);
465 memset(&vtmpl
, 0, sizeof(vtmpl
));
466 vtmpl
.buffer_format
= format
;
467 vtmpl
.chroma_format
= FormatYCBCRToPipeChroma(source_ycbcr_format
);
469 if (destination_rect
) {
470 vtmpl
.width
= abs(destination_rect
->x0
-destination_rect
->x1
);
471 vtmpl
.height
= abs(destination_rect
->y0
-destination_rect
->y1
);
473 vtmpl
.width
= vlsurface
->surface
->texture
->width0
;
474 vtmpl
.height
= vlsurface
->surface
->texture
->height0
;
477 vbuffer
= pipe
->create_video_buffer(pipe
, &vtmpl
);
479 pipe_mutex_unlock(vlsurface
->device
->mutex
);
480 return VDP_STATUS_RESOURCES
;
483 sampler_views
= vbuffer
->get_sampler_view_planes(vbuffer
);
484 if (!sampler_views
) {
485 vbuffer
->destroy(vbuffer
);
486 pipe_mutex_unlock(vlsurface
->device
->mutex
);
487 return VDP_STATUS_RESOURCES
;
490 for (i
= 0; i
< 3; ++i
) {
491 struct pipe_sampler_view
*sv
= sampler_views
[i
];
494 struct pipe_box dst_box
= {
496 sv
->texture
->width0
, sv
->texture
->height0
, 1
499 pipe
->texture_subdata(pipe
, sv
->texture
, 0, PIPE_TRANSFER_WRITE
, &dst_box
,
500 source_data
[i
], source_pitches
[i
], 0);
505 vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_BT_601
, NULL
, 1, &csc
);
506 if (!vl_compositor_set_csc_matrix(cstate
, (const vl_csc_matrix
*)&csc
, 1.0f
, 0.0f
))
509 if (!vl_compositor_set_csc_matrix(cstate
, csc_matrix
, 1.0f
, 0.0f
))
513 vl_compositor_clear_layers(cstate
);
514 vl_compositor_set_buffer_layer(cstate
, compositor
, 0, vbuffer
, NULL
, NULL
, VL_COMPOSITOR_WEAVE
);
515 vl_compositor_set_layer_dst_area(cstate
, 0, RectToPipe(destination_rect
, &dst_rect
));
516 vl_compositor_render(cstate
, compositor
, vlsurface
->surface
, &vlsurface
->dirty_area
, false);
518 vbuffer
->destroy(vbuffer
);
519 pipe_mutex_unlock(vlsurface
->device
->mutex
);
521 return VDP_STATUS_OK
;
523 vbuffer
->destroy(vbuffer
);
524 pipe_mutex_unlock(vlsurface
->device
->mutex
);
525 return VDP_STATUS_ERROR
;
529 BlendFactorToPipe(VdpOutputSurfaceRenderBlendFactor factor
)
532 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ZERO
:
533 return PIPE_BLENDFACTOR_ZERO
;
534 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE
:
535 return PIPE_BLENDFACTOR_ONE
;
536 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_COLOR
:
537 return PIPE_BLENDFACTOR_SRC_COLOR
;
538 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_COLOR
:
539 return PIPE_BLENDFACTOR_INV_SRC_COLOR
;
540 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_ALPHA
:
541 return PIPE_BLENDFACTOR_SRC_ALPHA
;
542 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA
:
543 return PIPE_BLENDFACTOR_INV_SRC_ALPHA
;
544 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_DST_ALPHA
:
545 return PIPE_BLENDFACTOR_DST_ALPHA
;
546 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_DST_ALPHA
:
547 return PIPE_BLENDFACTOR_INV_DST_ALPHA
;
548 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_DST_COLOR
:
549 return PIPE_BLENDFACTOR_DST_COLOR
;
550 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_DST_COLOR
:
551 return PIPE_BLENDFACTOR_INV_DST_COLOR
;
552 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_ALPHA_SATURATE
:
553 return PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
;
554 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_CONSTANT_COLOR
:
555 return PIPE_BLENDFACTOR_CONST_COLOR
;
556 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR
:
557 return PIPE_BLENDFACTOR_INV_CONST_COLOR
;
558 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_CONSTANT_ALPHA
:
559 return PIPE_BLENDFACTOR_CONST_ALPHA
;
560 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA
:
561 return PIPE_BLENDFACTOR_INV_CONST_ALPHA
;
564 return PIPE_BLENDFACTOR_ONE
;
569 BlendEquationToPipe(VdpOutputSurfaceRenderBlendEquation equation
)
572 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_SUBTRACT
:
573 return PIPE_BLEND_SUBTRACT
;
574 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_REVERSE_SUBTRACT
:
575 return PIPE_BLEND_REVERSE_SUBTRACT
;
576 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD
:
577 return PIPE_BLEND_ADD
;
578 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_MIN
:
579 return PIPE_BLEND_MIN
;
580 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_MAX
:
581 return PIPE_BLEND_MAX
;
584 return PIPE_BLEND_ADD
;
589 BlenderToPipe(struct pipe_context
*context
,
590 VdpOutputSurfaceRenderBlendState
const *blend_state
)
592 struct pipe_blend_state blend
;
594 memset(&blend
, 0, sizeof blend
);
595 blend
.independent_blend_enable
= 0;
598 blend
.rt
[0].blend_enable
= 1;
599 blend
.rt
[0].rgb_src_factor
= BlendFactorToPipe(blend_state
->blend_factor_source_color
);
600 blend
.rt
[0].rgb_dst_factor
= BlendFactorToPipe(blend_state
->blend_factor_destination_color
);
601 blend
.rt
[0].alpha_src_factor
= BlendFactorToPipe(blend_state
->blend_factor_source_alpha
);
602 blend
.rt
[0].alpha_dst_factor
= BlendFactorToPipe(blend_state
->blend_factor_destination_alpha
);
603 blend
.rt
[0].rgb_func
= BlendEquationToPipe(blend_state
->blend_equation_color
);
604 blend
.rt
[0].alpha_func
= BlendEquationToPipe(blend_state
->blend_equation_alpha
);
606 blend
.rt
[0].blend_enable
= 0;
609 blend
.logicop_enable
= 0;
610 blend
.logicop_func
= PIPE_LOGICOP_CLEAR
;
611 blend
.rt
[0].colormask
= PIPE_MASK_RGBA
;
614 return context
->create_blend_state(context
, &blend
);
617 static struct vertex4f
*
618 ColorsToPipe(VdpColor
const *colors
, uint32_t flags
, struct vertex4f result
[4])
621 struct vertex4f
*dst
= result
;
626 for (i
= 0; i
< 4; ++i
) {
627 dst
->x
= colors
->red
;
628 dst
->y
= colors
->green
;
629 dst
->z
= colors
->blue
;
630 dst
->w
= colors
->alpha
;
633 if (flags
& VDP_OUTPUT_SURFACE_RENDER_COLOR_PER_VERTEX
)
640 * Composite a sub-rectangle of a VdpOutputSurface into a sub-rectangle of
641 * another VdpOutputSurface; Output Surface object VdpOutputSurface.
644 vlVdpOutputSurfaceRenderOutputSurface(VdpOutputSurface destination_surface
,
645 VdpRect
const *destination_rect
,
646 VdpOutputSurface source_surface
,
647 VdpRect
const *source_rect
,
648 VdpColor
const *colors
,
649 VdpOutputSurfaceRenderBlendState
const *blend_state
,
652 vlVdpOutputSurface
*dst_vlsurface
;
654 struct pipe_context
*context
;
655 struct pipe_sampler_view
*src_sv
;
656 struct vl_compositor
*compositor
;
657 struct vl_compositor_state
*cstate
;
659 struct u_rect src_rect
, dst_rect
;
661 struct vertex4f vlcolors
[4];
664 dst_vlsurface
= vlGetDataHTAB(destination_surface
);
666 return VDP_STATUS_INVALID_HANDLE
;
668 if (source_surface
== VDP_INVALID_HANDLE
) {
669 src_sv
= dst_vlsurface
->device
->dummy_sv
;
672 vlVdpOutputSurface
*src_vlsurface
= vlGetDataHTAB(source_surface
);
674 return VDP_STATUS_INVALID_HANDLE
;
676 if (dst_vlsurface
->device
!= src_vlsurface
->device
)
677 return VDP_STATUS_HANDLE_DEVICE_MISMATCH
;
679 src_sv
= src_vlsurface
->sampler_view
;
682 pipe_mutex_lock(dst_vlsurface
->device
->mutex
);
684 context
= dst_vlsurface
->device
->context
;
685 compositor
= &dst_vlsurface
->device
->compositor
;
686 cstate
= &dst_vlsurface
->cstate
;
688 blend
= BlenderToPipe(context
, blend_state
);
690 vl_compositor_clear_layers(cstate
);
691 vl_compositor_set_layer_blend(cstate
, 0, blend
, false);
692 vl_compositor_set_rgba_layer(cstate
, compositor
, 0, src_sv
,
693 RectToPipe(source_rect
, &src_rect
), NULL
,
694 ColorsToPipe(colors
, flags
, vlcolors
));
695 STATIC_ASSERT(VL_COMPOSITOR_ROTATE_0
== VDP_OUTPUT_SURFACE_RENDER_ROTATE_0
);
696 STATIC_ASSERT(VL_COMPOSITOR_ROTATE_90
== VDP_OUTPUT_SURFACE_RENDER_ROTATE_90
);
697 STATIC_ASSERT(VL_COMPOSITOR_ROTATE_180
== VDP_OUTPUT_SURFACE_RENDER_ROTATE_180
);
698 STATIC_ASSERT(VL_COMPOSITOR_ROTATE_270
== VDP_OUTPUT_SURFACE_RENDER_ROTATE_270
);
699 vl_compositor_set_layer_rotation(cstate
, 0, flags
& 3);
700 vl_compositor_set_layer_dst_area(cstate
, 0, RectToPipe(destination_rect
, &dst_rect
));
701 vl_compositor_render(cstate
, compositor
, dst_vlsurface
->surface
, &dst_vlsurface
->dirty_area
, false);
703 context
->delete_blend_state(context
, blend
);
704 pipe_mutex_unlock(dst_vlsurface
->device
->mutex
);
706 return VDP_STATUS_OK
;
710 * Composite a sub-rectangle of a VdpBitmapSurface into a sub-rectangle of
711 * a VdpOutputSurface; Output Surface object VdpOutputSurface.
714 vlVdpOutputSurfaceRenderBitmapSurface(VdpOutputSurface destination_surface
,
715 VdpRect
const *destination_rect
,
716 VdpBitmapSurface source_surface
,
717 VdpRect
const *source_rect
,
718 VdpColor
const *colors
,
719 VdpOutputSurfaceRenderBlendState
const *blend_state
,
722 vlVdpOutputSurface
*dst_vlsurface
;
724 struct pipe_context
*context
;
725 struct pipe_sampler_view
*src_sv
;
726 struct vl_compositor
*compositor
;
727 struct vl_compositor_state
*cstate
;
729 struct u_rect src_rect
, dst_rect
;
731 struct vertex4f vlcolors
[4];
734 dst_vlsurface
= vlGetDataHTAB(destination_surface
);
736 return VDP_STATUS_INVALID_HANDLE
;
738 if (source_surface
== VDP_INVALID_HANDLE
) {
739 src_sv
= dst_vlsurface
->device
->dummy_sv
;
742 vlVdpBitmapSurface
*src_vlsurface
= vlGetDataHTAB(source_surface
);
744 return VDP_STATUS_INVALID_HANDLE
;
746 if (dst_vlsurface
->device
!= src_vlsurface
->device
)
747 return VDP_STATUS_HANDLE_DEVICE_MISMATCH
;
749 src_sv
= src_vlsurface
->sampler_view
;
752 context
= dst_vlsurface
->device
->context
;
753 compositor
= &dst_vlsurface
->device
->compositor
;
754 cstate
= &dst_vlsurface
->cstate
;
756 pipe_mutex_lock(dst_vlsurface
->device
->mutex
);
758 blend
= BlenderToPipe(context
, blend_state
);
760 vl_compositor_clear_layers(cstate
);
761 vl_compositor_set_layer_blend(cstate
, 0, blend
, false);
762 vl_compositor_set_rgba_layer(cstate
, compositor
, 0, src_sv
,
763 RectToPipe(source_rect
, &src_rect
), NULL
,
764 ColorsToPipe(colors
, flags
, vlcolors
));
765 vl_compositor_set_layer_rotation(cstate
, 0, flags
& 3);
766 vl_compositor_set_layer_dst_area(cstate
, 0, RectToPipe(destination_rect
, &dst_rect
));
767 vl_compositor_render(cstate
, compositor
, dst_vlsurface
->surface
, &dst_vlsurface
->dirty_area
, false);
769 context
->delete_blend_state(context
, blend
);
770 pipe_mutex_unlock(dst_vlsurface
->device
->mutex
);
772 return VDP_STATUS_OK
;
775 struct pipe_resource
*vlVdpOutputSurfaceGallium(VdpOutputSurface surface
)
777 vlVdpOutputSurface
*vlsurface
;
779 vlsurface
= vlGetDataHTAB(surface
);
780 if (!vlsurface
|| !vlsurface
->surface
)
783 pipe_mutex_lock(vlsurface
->device
->mutex
);
784 vlsurface
->device
->context
->flush(vlsurface
->device
->context
, NULL
, 0);
785 pipe_mutex_unlock(vlsurface
->device
->mutex
);
787 return vlsurface
->surface
->texture
;
790 VdpStatus
vlVdpOutputSurfaceDMABuf(VdpOutputSurface surface
,
791 struct VdpSurfaceDMABufDesc
*result
)
793 vlVdpOutputSurface
*vlsurface
;
794 struct pipe_screen
*pscreen
;
795 struct winsys_handle whandle
;
797 memset(result
, 0, sizeof(*result
));
800 vlsurface
= vlGetDataHTAB(surface
);
801 if (!vlsurface
|| !vlsurface
->surface
)
802 return VDP_STATUS_INVALID_HANDLE
;
804 pipe_mutex_lock(vlsurface
->device
->mutex
);
805 vlsurface
->device
->context
->flush(vlsurface
->device
->context
, NULL
, 0);
807 memset(&whandle
, 0, sizeof(struct winsys_handle
));
808 whandle
.type
= DRM_API_HANDLE_TYPE_FD
;
810 pscreen
= vlsurface
->surface
->texture
->screen
;
811 if (!pscreen
->resource_get_handle(pscreen
, vlsurface
->device
->context
,
812 vlsurface
->surface
->texture
, &whandle
,
813 PIPE_HANDLE_USAGE_READ_WRITE
)) {
814 pipe_mutex_unlock(vlsurface
->device
->mutex
);
815 return VDP_STATUS_NO_IMPLEMENTATION
;
818 pipe_mutex_unlock(vlsurface
->device
->mutex
);
820 result
->handle
= whandle
.handle
;
821 result
->width
= vlsurface
->surface
->width
;
822 result
->height
= vlsurface
->surface
->height
;
823 result
->offset
= whandle
.offset
;
824 result
->stride
= whandle
.stride
;
825 result
->format
= PipeToFormatRGBA(vlsurface
->surface
->format
);
827 return VDP_STATUS_OK
;