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
));
78 res_tmpl
.target
= PIPE_TEXTURE_2D
;
79 res_tmpl
.format
= VdpFormatRGBAToPipe(rgba_format
);
80 res_tmpl
.width0
= width
;
81 res_tmpl
.height0
= height
;
83 res_tmpl
.array_size
= 1;
84 res_tmpl
.bind
= PIPE_BIND_SAMPLER_VIEW
| PIPE_BIND_RENDER_TARGET
|
85 PIPE_BIND_SHARED
| PIPE_BIND_SCANOUT
;
86 res_tmpl
.usage
= PIPE_USAGE_DEFAULT
;
88 pipe_mutex_lock(dev
->mutex
);
90 if (!CheckSurfaceParams(pipe
->screen
, &res_tmpl
))
93 res
= pipe
->screen
->resource_create(pipe
->screen
, &res_tmpl
);
97 vlVdpDefaultSamplerViewTemplate(&sv_templ
, res
);
98 vlsurface
->sampler_view
= pipe
->create_sampler_view(pipe
, res
, &sv_templ
);
99 if (!vlsurface
->sampler_view
)
102 memset(&surf_templ
, 0, sizeof(surf_templ
));
103 surf_templ
.format
= res
->format
;
104 vlsurface
->surface
= pipe
->create_surface(pipe
, res
, &surf_templ
);
105 if (!vlsurface
->surface
)
108 *surface
= vlAddDataHTAB(vlsurface
);
112 pipe_resource_reference(&res
, NULL
);
114 if (!vl_compositor_init_state(&vlsurface
->cstate
, pipe
))
117 vl_compositor_reset_dirty_area(&vlsurface
->dirty_area
);
118 pipe_mutex_unlock(dev
->mutex
);
120 return VDP_STATUS_OK
;
123 pipe_sampler_view_reference(&vlsurface
->sampler_view
, NULL
);
124 pipe_surface_reference(&vlsurface
->surface
, NULL
);
125 pipe_resource_reference(&res
, NULL
);
127 pipe_mutex_unlock(dev
->mutex
);
128 DeviceReference(&vlsurface
->device
, NULL
);
130 return VDP_STATUS_ERROR
;
134 * Destroy a VdpOutputSurface.
137 vlVdpOutputSurfaceDestroy(VdpOutputSurface surface
)
139 vlVdpOutputSurface
*vlsurface
;
140 struct pipe_context
*pipe
;
142 vlsurface
= vlGetDataHTAB(surface
);
144 return VDP_STATUS_INVALID_HANDLE
;
146 pipe
= vlsurface
->device
->context
;
148 pipe_mutex_lock(vlsurface
->device
->mutex
);
149 vlVdpResolveDelayedRendering(vlsurface
->device
, NULL
, NULL
);
151 pipe_surface_reference(&vlsurface
->surface
, NULL
);
152 pipe_sampler_view_reference(&vlsurface
->sampler_view
, NULL
);
153 pipe
->screen
->fence_reference(pipe
->screen
, &vlsurface
->fence
, NULL
);
154 vl_compositor_cleanup_state(&vlsurface
->cstate
);
155 pipe_mutex_unlock(vlsurface
->device
->mutex
);
157 vlRemoveDataHTAB(surface
);
158 DeviceReference(&vlsurface
->device
, NULL
);
161 return VDP_STATUS_OK
;
165 * Retrieve the parameters used to create a VdpOutputSurface.
168 vlVdpOutputSurfaceGetParameters(VdpOutputSurface surface
,
169 VdpRGBAFormat
*rgba_format
,
170 uint32_t *width
, uint32_t *height
)
172 vlVdpOutputSurface
*vlsurface
;
174 vlsurface
= vlGetDataHTAB(surface
);
176 return VDP_STATUS_INVALID_HANDLE
;
178 *rgba_format
= PipeToFormatRGBA(vlsurface
->sampler_view
->texture
->format
);
179 *width
= vlsurface
->sampler_view
->texture
->width0
;
180 *height
= vlsurface
->sampler_view
->texture
->height0
;
182 return VDP_STATUS_OK
;
186 * Copy image data from a VdpOutputSurface to application memory in the
187 * surface's native format.
190 vlVdpOutputSurfaceGetBitsNative(VdpOutputSurface surface
,
191 VdpRect
const *source_rect
,
192 void *const *destination_data
,
193 uint32_t const *destination_pitches
)
195 vlVdpOutputSurface
*vlsurface
;
196 struct pipe_context
*pipe
;
197 struct pipe_resource
*res
;
199 struct pipe_transfer
*transfer
;
202 vlsurface
= vlGetDataHTAB(surface
);
204 return VDP_STATUS_INVALID_HANDLE
;
206 pipe
= vlsurface
->device
->context
;
208 return VDP_STATUS_INVALID_HANDLE
;
210 if (!destination_data
|| !destination_pitches
)
211 return VDP_STATUS_INVALID_POINTER
;
213 pipe_mutex_lock(vlsurface
->device
->mutex
);
214 vlVdpResolveDelayedRendering(vlsurface
->device
, NULL
, NULL
);
216 res
= vlsurface
->sampler_view
->texture
;
217 box
= RectToPipeBox(source_rect
, res
);
218 map
= pipe
->transfer_map(pipe
, res
, 0, PIPE_TRANSFER_READ
, &box
, &transfer
);
220 pipe_mutex_unlock(vlsurface
->device
->mutex
);
221 return VDP_STATUS_RESOURCES
;
224 util_copy_rect(*destination_data
, res
->format
, *destination_pitches
, 0, 0,
225 box
.width
, box
.height
, map
, transfer
->stride
, 0, 0);
227 pipe_transfer_unmap(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 if (!source_data
|| !source_pitches
)
256 return VDP_STATUS_INVALID_POINTER
;
258 pipe_mutex_lock(vlsurface
->device
->mutex
);
259 vlVdpResolveDelayedRendering(vlsurface
->device
, NULL
, NULL
);
261 dst_box
= RectToPipeBox(destination_rect
, vlsurface
->sampler_view
->texture
);
262 pipe
->texture_subdata(pipe
, vlsurface
->sampler_view
->texture
, 0,
263 PIPE_TRANSFER_WRITE
, &dst_box
, *source_data
,
265 pipe_mutex_unlock(vlsurface
->device
->mutex
);
267 return VDP_STATUS_OK
;
271 * Copy image data from application memory in a specific indexed format to
272 * a VdpOutputSurface.
275 vlVdpOutputSurfacePutBitsIndexed(VdpOutputSurface surface
,
276 VdpIndexedFormat source_indexed_format
,
277 void const *const *source_data
,
278 uint32_t const *source_pitch
,
279 VdpRect
const *destination_rect
,
280 VdpColorTableFormat color_table_format
,
281 void const *color_table
)
283 vlVdpOutputSurface
*vlsurface
;
284 struct pipe_context
*context
;
285 struct vl_compositor
*compositor
;
286 struct vl_compositor_state
*cstate
;
288 enum pipe_format index_format
;
289 enum pipe_format colortbl_format
;
291 struct pipe_resource
*res
, res_tmpl
;
292 struct pipe_sampler_view sv_tmpl
;
293 struct pipe_sampler_view
*sv_idx
= NULL
, *sv_tbl
= NULL
;
296 struct u_rect dst_rect
;
298 vlsurface
= vlGetDataHTAB(surface
);
300 return VDP_STATUS_INVALID_HANDLE
;
302 context
= vlsurface
->device
->context
;
303 compositor
= &vlsurface
->device
->compositor
;
304 cstate
= &vlsurface
->cstate
;
306 index_format
= FormatIndexedToPipe(source_indexed_format
);
307 if (index_format
== PIPE_FORMAT_NONE
)
308 return VDP_STATUS_INVALID_INDEXED_FORMAT
;
310 if (!source_data
|| !source_pitch
)
311 return VDP_STATUS_INVALID_POINTER
;
313 colortbl_format
= FormatColorTableToPipe(color_table_format
);
314 if (colortbl_format
== PIPE_FORMAT_NONE
)
315 return VDP_STATUS_INVALID_COLOR_TABLE_FORMAT
;
318 return VDP_STATUS_INVALID_POINTER
;
320 memset(&res_tmpl
, 0, sizeof(res_tmpl
));
321 res_tmpl
.target
= PIPE_TEXTURE_2D
;
322 res_tmpl
.format
= index_format
;
324 if (destination_rect
) {
325 res_tmpl
.width0
= abs(destination_rect
->x0
-destination_rect
->x1
);
326 res_tmpl
.height0
= abs(destination_rect
->y0
-destination_rect
->y1
);
328 res_tmpl
.width0
= vlsurface
->surface
->texture
->width0
;
329 res_tmpl
.height0
= vlsurface
->surface
->texture
->height0
;
332 res_tmpl
.array_size
= 1;
333 res_tmpl
.usage
= PIPE_USAGE_STAGING
;
334 res_tmpl
.bind
= PIPE_BIND_SAMPLER_VIEW
;
336 pipe_mutex_lock(vlsurface
->device
->mutex
);
337 vlVdpResolveDelayedRendering(vlsurface
->device
, NULL
, NULL
);
339 if (!CheckSurfaceParams(context
->screen
, &res_tmpl
))
342 res
= context
->screen
->resource_create(context
->screen
, &res_tmpl
);
346 box
.x
= box
.y
= box
.z
= 0;
347 box
.width
= res
->width0
;
348 box
.height
= res
->height0
;
349 box
.depth
= res
->depth0
;
351 context
->texture_subdata(context
, res
, 0, PIPE_TRANSFER_WRITE
, &box
,
352 source_data
[0], source_pitch
[0],
353 source_pitch
[0] * res
->height0
);
355 memset(&sv_tmpl
, 0, sizeof(sv_tmpl
));
356 u_sampler_view_default_template(&sv_tmpl
, res
, res
->format
);
358 sv_idx
= context
->create_sampler_view(context
, res
, &sv_tmpl
);
359 pipe_resource_reference(&res
, NULL
);
364 memset(&res_tmpl
, 0, sizeof(res_tmpl
));
365 res_tmpl
.target
= PIPE_TEXTURE_1D
;
366 res_tmpl
.format
= colortbl_format
;
367 res_tmpl
.width0
= 1 << util_format_get_component_bits(
368 index_format
, UTIL_FORMAT_COLORSPACE_RGB
, 0);
369 res_tmpl
.height0
= 1;
371 res_tmpl
.array_size
= 1;
372 res_tmpl
.usage
= PIPE_USAGE_STAGING
;
373 res_tmpl
.bind
= PIPE_BIND_SAMPLER_VIEW
;
375 res
= context
->screen
->resource_create(context
->screen
, &res_tmpl
);
379 box
.x
= box
.y
= box
.z
= 0;
380 box
.width
= res
->width0
;
381 box
.height
= res
->height0
;
382 box
.depth
= res
->depth0
;
384 context
->texture_subdata(context
, res
, 0, PIPE_TRANSFER_WRITE
, &box
, color_table
,
385 util_format_get_stride(colortbl_format
, res
->width0
), 0);
387 memset(&sv_tmpl
, 0, sizeof(sv_tmpl
));
388 u_sampler_view_default_template(&sv_tmpl
, res
, res
->format
);
390 sv_tbl
= context
->create_sampler_view(context
, res
, &sv_tmpl
);
391 pipe_resource_reference(&res
, NULL
);
396 vl_compositor_clear_layers(cstate
);
397 vl_compositor_set_palette_layer(cstate
, compositor
, 0, sv_idx
, sv_tbl
, NULL
, NULL
, false);
398 vl_compositor_set_layer_dst_area(cstate
, 0, RectToPipe(destination_rect
, &dst_rect
));
399 vl_compositor_render(cstate
, compositor
, vlsurface
->surface
, &vlsurface
->dirty_area
, false);
401 pipe_sampler_view_reference(&sv_idx
, NULL
);
402 pipe_sampler_view_reference(&sv_tbl
, NULL
);
403 pipe_mutex_unlock(vlsurface
->device
->mutex
);
405 return VDP_STATUS_OK
;
408 pipe_sampler_view_reference(&sv_idx
, NULL
);
409 pipe_sampler_view_reference(&sv_tbl
, NULL
);
410 pipe_mutex_unlock(vlsurface
->device
->mutex
);
411 return VDP_STATUS_RESOURCES
;
415 * Copy image data from application memory in a specific YCbCr format to
416 * a VdpOutputSurface.
419 vlVdpOutputSurfacePutBitsYCbCr(VdpOutputSurface surface
,
420 VdpYCbCrFormat source_ycbcr_format
,
421 void const *const *source_data
,
422 uint32_t const *source_pitches
,
423 VdpRect
const *destination_rect
,
424 VdpCSCMatrix
const *csc_matrix
)
426 vlVdpOutputSurface
*vlsurface
;
427 struct vl_compositor
*compositor
;
428 struct vl_compositor_state
*cstate
;
430 struct pipe_context
*pipe
;
431 enum pipe_format format
;
432 struct pipe_video_buffer vtmpl
, *vbuffer
;
433 struct u_rect dst_rect
;
434 struct pipe_sampler_view
**sampler_views
;
438 vlsurface
= vlGetDataHTAB(surface
);
440 return VDP_STATUS_INVALID_HANDLE
;
443 pipe
= vlsurface
->device
->context
;
444 compositor
= &vlsurface
->device
->compositor
;
445 cstate
= &vlsurface
->cstate
;
447 format
= FormatYCBCRToPipe(source_ycbcr_format
);
448 if (format
== PIPE_FORMAT_NONE
)
449 return VDP_STATUS_INVALID_Y_CB_CR_FORMAT
;
451 if (!source_data
|| !source_pitches
)
452 return VDP_STATUS_INVALID_POINTER
;
454 pipe_mutex_lock(vlsurface
->device
->mutex
);
455 vlVdpResolveDelayedRendering(vlsurface
->device
, NULL
, NULL
);
456 memset(&vtmpl
, 0, sizeof(vtmpl
));
457 vtmpl
.buffer_format
= format
;
458 vtmpl
.chroma_format
= FormatYCBCRToPipeChroma(source_ycbcr_format
);
460 if (destination_rect
) {
461 vtmpl
.width
= abs(destination_rect
->x0
-destination_rect
->x1
);
462 vtmpl
.height
= abs(destination_rect
->y0
-destination_rect
->y1
);
464 vtmpl
.width
= vlsurface
->surface
->texture
->width0
;
465 vtmpl
.height
= vlsurface
->surface
->texture
->height0
;
468 vbuffer
= pipe
->create_video_buffer(pipe
, &vtmpl
);
470 pipe_mutex_unlock(vlsurface
->device
->mutex
);
471 return VDP_STATUS_RESOURCES
;
474 sampler_views
= vbuffer
->get_sampler_view_planes(vbuffer
);
475 if (!sampler_views
) {
476 vbuffer
->destroy(vbuffer
);
477 pipe_mutex_unlock(vlsurface
->device
->mutex
);
478 return VDP_STATUS_RESOURCES
;
481 for (i
= 0; i
< 3; ++i
) {
482 struct pipe_sampler_view
*sv
= sampler_views
[i
];
485 struct pipe_box dst_box
= {
487 sv
->texture
->width0
, sv
->texture
->height0
, 1
490 pipe
->texture_subdata(pipe
, sv
->texture
, 0, PIPE_TRANSFER_WRITE
, &dst_box
,
491 source_data
[i
], source_pitches
[i
], 0);
496 vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_BT_601
, NULL
, 1, &csc
);
497 if (!vl_compositor_set_csc_matrix(cstate
, (const vl_csc_matrix
*)&csc
, 1.0f
, 0.0f
))
500 if (!vl_compositor_set_csc_matrix(cstate
, csc_matrix
, 1.0f
, 0.0f
))
504 vl_compositor_clear_layers(cstate
);
505 vl_compositor_set_buffer_layer(cstate
, compositor
, 0, vbuffer
, NULL
, NULL
, VL_COMPOSITOR_WEAVE
);
506 vl_compositor_set_layer_dst_area(cstate
, 0, RectToPipe(destination_rect
, &dst_rect
));
507 vl_compositor_render(cstate
, compositor
, vlsurface
->surface
, &vlsurface
->dirty_area
, false);
509 vbuffer
->destroy(vbuffer
);
510 pipe_mutex_unlock(vlsurface
->device
->mutex
);
512 return VDP_STATUS_OK
;
514 vbuffer
->destroy(vbuffer
);
515 pipe_mutex_unlock(vlsurface
->device
->mutex
);
516 return VDP_STATUS_ERROR
;
520 BlendFactorToPipe(VdpOutputSurfaceRenderBlendFactor factor
)
523 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ZERO
:
524 return PIPE_BLENDFACTOR_ZERO
;
525 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE
:
526 return PIPE_BLENDFACTOR_ONE
;
527 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_COLOR
:
528 return PIPE_BLENDFACTOR_SRC_COLOR
;
529 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_COLOR
:
530 return PIPE_BLENDFACTOR_INV_SRC_COLOR
;
531 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_ALPHA
:
532 return PIPE_BLENDFACTOR_SRC_ALPHA
;
533 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA
:
534 return PIPE_BLENDFACTOR_INV_SRC_ALPHA
;
535 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_DST_ALPHA
:
536 return PIPE_BLENDFACTOR_DST_ALPHA
;
537 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_DST_ALPHA
:
538 return PIPE_BLENDFACTOR_INV_DST_ALPHA
;
539 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_DST_COLOR
:
540 return PIPE_BLENDFACTOR_DST_COLOR
;
541 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_DST_COLOR
:
542 return PIPE_BLENDFACTOR_INV_DST_COLOR
;
543 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_ALPHA_SATURATE
:
544 return PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
;
545 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_CONSTANT_COLOR
:
546 return PIPE_BLENDFACTOR_CONST_COLOR
;
547 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR
:
548 return PIPE_BLENDFACTOR_INV_CONST_COLOR
;
549 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_CONSTANT_ALPHA
:
550 return PIPE_BLENDFACTOR_CONST_ALPHA
;
551 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA
:
552 return PIPE_BLENDFACTOR_INV_CONST_ALPHA
;
555 return PIPE_BLENDFACTOR_ONE
;
560 BlendEquationToPipe(VdpOutputSurfaceRenderBlendEquation equation
)
563 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_SUBTRACT
:
564 return PIPE_BLEND_SUBTRACT
;
565 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_REVERSE_SUBTRACT
:
566 return PIPE_BLEND_REVERSE_SUBTRACT
;
567 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD
:
568 return PIPE_BLEND_ADD
;
569 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_MIN
:
570 return PIPE_BLEND_MIN
;
571 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_MAX
:
572 return PIPE_BLEND_MAX
;
575 return PIPE_BLEND_ADD
;
580 BlenderToPipe(struct pipe_context
*context
,
581 VdpOutputSurfaceRenderBlendState
const *blend_state
)
583 struct pipe_blend_state blend
;
585 memset(&blend
, 0, sizeof blend
);
586 blend
.independent_blend_enable
= 0;
589 blend
.rt
[0].blend_enable
= 1;
590 blend
.rt
[0].rgb_src_factor
= BlendFactorToPipe(blend_state
->blend_factor_source_color
);
591 blend
.rt
[0].rgb_dst_factor
= BlendFactorToPipe(blend_state
->blend_factor_destination_color
);
592 blend
.rt
[0].alpha_src_factor
= BlendFactorToPipe(blend_state
->blend_factor_source_alpha
);
593 blend
.rt
[0].alpha_dst_factor
= BlendFactorToPipe(blend_state
->blend_factor_destination_alpha
);
594 blend
.rt
[0].rgb_func
= BlendEquationToPipe(blend_state
->blend_equation_color
);
595 blend
.rt
[0].alpha_func
= BlendEquationToPipe(blend_state
->blend_equation_alpha
);
597 blend
.rt
[0].blend_enable
= 0;
600 blend
.logicop_enable
= 0;
601 blend
.logicop_func
= PIPE_LOGICOP_CLEAR
;
602 blend
.rt
[0].colormask
= PIPE_MASK_RGBA
;
605 return context
->create_blend_state(context
, &blend
);
608 static struct vertex4f
*
609 ColorsToPipe(VdpColor
const *colors
, uint32_t flags
, struct vertex4f result
[4])
612 struct vertex4f
*dst
= result
;
617 for (i
= 0; i
< 4; ++i
) {
618 dst
->x
= colors
->red
;
619 dst
->y
= colors
->green
;
620 dst
->z
= colors
->blue
;
621 dst
->w
= colors
->alpha
;
624 if (flags
& VDP_OUTPUT_SURFACE_RENDER_COLOR_PER_VERTEX
)
631 * Composite a sub-rectangle of a VdpOutputSurface into a sub-rectangle of
632 * another VdpOutputSurface; Output Surface object VdpOutputSurface.
635 vlVdpOutputSurfaceRenderOutputSurface(VdpOutputSurface destination_surface
,
636 VdpRect
const *destination_rect
,
637 VdpOutputSurface source_surface
,
638 VdpRect
const *source_rect
,
639 VdpColor
const *colors
,
640 VdpOutputSurfaceRenderBlendState
const *blend_state
,
643 vlVdpOutputSurface
*dst_vlsurface
;
645 struct pipe_context
*context
;
646 struct pipe_sampler_view
*src_sv
;
647 struct vl_compositor
*compositor
;
648 struct vl_compositor_state
*cstate
;
650 struct u_rect src_rect
, dst_rect
;
652 struct vertex4f vlcolors
[4];
655 dst_vlsurface
= vlGetDataHTAB(destination_surface
);
657 return VDP_STATUS_INVALID_HANDLE
;
659 if (source_surface
== VDP_INVALID_HANDLE
) {
660 src_sv
= dst_vlsurface
->device
->dummy_sv
;
663 vlVdpOutputSurface
*src_vlsurface
= vlGetDataHTAB(source_surface
);
665 return VDP_STATUS_INVALID_HANDLE
;
667 if (dst_vlsurface
->device
!= src_vlsurface
->device
)
668 return VDP_STATUS_HANDLE_DEVICE_MISMATCH
;
670 src_sv
= src_vlsurface
->sampler_view
;
673 pipe_mutex_lock(dst_vlsurface
->device
->mutex
);
674 vlVdpResolveDelayedRendering(dst_vlsurface
->device
, NULL
, NULL
);
676 context
= dst_vlsurface
->device
->context
;
677 compositor
= &dst_vlsurface
->device
->compositor
;
678 cstate
= &dst_vlsurface
->cstate
;
680 blend
= BlenderToPipe(context
, blend_state
);
682 vl_compositor_clear_layers(cstate
);
683 vl_compositor_set_layer_blend(cstate
, 0, blend
, false);
684 vl_compositor_set_rgba_layer(cstate
, compositor
, 0, src_sv
,
685 RectToPipe(source_rect
, &src_rect
), NULL
,
686 ColorsToPipe(colors
, flags
, vlcolors
));
687 STATIC_ASSERT(VL_COMPOSITOR_ROTATE_0
== VDP_OUTPUT_SURFACE_RENDER_ROTATE_0
);
688 STATIC_ASSERT(VL_COMPOSITOR_ROTATE_90
== VDP_OUTPUT_SURFACE_RENDER_ROTATE_90
);
689 STATIC_ASSERT(VL_COMPOSITOR_ROTATE_180
== VDP_OUTPUT_SURFACE_RENDER_ROTATE_180
);
690 STATIC_ASSERT(VL_COMPOSITOR_ROTATE_270
== VDP_OUTPUT_SURFACE_RENDER_ROTATE_270
);
691 vl_compositor_set_layer_rotation(cstate
, 0, flags
& 3);
692 vl_compositor_set_layer_dst_area(cstate
, 0, RectToPipe(destination_rect
, &dst_rect
));
693 vl_compositor_render(cstate
, compositor
, dst_vlsurface
->surface
, &dst_vlsurface
->dirty_area
, false);
695 context
->delete_blend_state(context
, blend
);
696 pipe_mutex_unlock(dst_vlsurface
->device
->mutex
);
698 return VDP_STATUS_OK
;
702 * Composite a sub-rectangle of a VdpBitmapSurface into a sub-rectangle of
703 * a VdpOutputSurface; Output Surface object VdpOutputSurface.
706 vlVdpOutputSurfaceRenderBitmapSurface(VdpOutputSurface destination_surface
,
707 VdpRect
const *destination_rect
,
708 VdpBitmapSurface source_surface
,
709 VdpRect
const *source_rect
,
710 VdpColor
const *colors
,
711 VdpOutputSurfaceRenderBlendState
const *blend_state
,
714 vlVdpOutputSurface
*dst_vlsurface
;
716 struct pipe_context
*context
;
717 struct pipe_sampler_view
*src_sv
;
718 struct vl_compositor
*compositor
;
719 struct vl_compositor_state
*cstate
;
721 struct u_rect src_rect
, dst_rect
;
723 struct vertex4f vlcolors
[4];
726 dst_vlsurface
= vlGetDataHTAB(destination_surface
);
728 return VDP_STATUS_INVALID_HANDLE
;
730 if (source_surface
== VDP_INVALID_HANDLE
) {
731 src_sv
= dst_vlsurface
->device
->dummy_sv
;
734 vlVdpBitmapSurface
*src_vlsurface
= vlGetDataHTAB(source_surface
);
736 return VDP_STATUS_INVALID_HANDLE
;
738 if (dst_vlsurface
->device
!= src_vlsurface
->device
)
739 return VDP_STATUS_HANDLE_DEVICE_MISMATCH
;
741 src_sv
= src_vlsurface
->sampler_view
;
744 context
= dst_vlsurface
->device
->context
;
745 compositor
= &dst_vlsurface
->device
->compositor
;
746 cstate
= &dst_vlsurface
->cstate
;
748 pipe_mutex_lock(dst_vlsurface
->device
->mutex
);
749 vlVdpResolveDelayedRendering(dst_vlsurface
->device
, NULL
, NULL
);
751 blend
= BlenderToPipe(context
, blend_state
);
753 vl_compositor_clear_layers(cstate
);
754 vl_compositor_set_layer_blend(cstate
, 0, blend
, false);
755 vl_compositor_set_rgba_layer(cstate
, compositor
, 0, src_sv
,
756 RectToPipe(source_rect
, &src_rect
), NULL
,
757 ColorsToPipe(colors
, flags
, vlcolors
));
758 vl_compositor_set_layer_rotation(cstate
, 0, flags
& 3);
759 vl_compositor_set_layer_dst_area(cstate
, 0, RectToPipe(destination_rect
, &dst_rect
));
760 vl_compositor_render(cstate
, compositor
, dst_vlsurface
->surface
, &dst_vlsurface
->dirty_area
, false);
762 context
->delete_blend_state(context
, blend
);
763 pipe_mutex_unlock(dst_vlsurface
->device
->mutex
);
765 return VDP_STATUS_OK
;
768 struct pipe_resource
*vlVdpOutputSurfaceGallium(VdpOutputSurface surface
)
770 vlVdpOutputSurface
*vlsurface
;
772 vlsurface
= vlGetDataHTAB(surface
);
773 if (!vlsurface
|| !vlsurface
->surface
)
776 pipe_mutex_lock(vlsurface
->device
->mutex
);
777 vlVdpResolveDelayedRendering(vlsurface
->device
, NULL
, NULL
);
778 vlsurface
->device
->context
->flush(vlsurface
->device
->context
, NULL
, 0);
779 pipe_mutex_unlock(vlsurface
->device
->mutex
);
781 return vlsurface
->surface
->texture
;
784 VdpStatus
vlVdpOutputSurfaceDMABuf(VdpOutputSurface surface
,
785 struct VdpSurfaceDMABufDesc
*result
)
787 vlVdpOutputSurface
*vlsurface
;
788 struct pipe_screen
*pscreen
;
789 struct winsys_handle whandle
;
791 memset(result
, 0, sizeof(*result
));
794 vlsurface
= vlGetDataHTAB(surface
);
795 if (!vlsurface
|| !vlsurface
->surface
)
796 return VDP_STATUS_INVALID_HANDLE
;
798 pipe_mutex_lock(vlsurface
->device
->mutex
);
799 vlVdpResolveDelayedRendering(vlsurface
->device
, NULL
, NULL
);
800 vlsurface
->device
->context
->flush(vlsurface
->device
->context
, NULL
, 0);
802 memset(&whandle
, 0, sizeof(struct winsys_handle
));
803 whandle
.type
= DRM_API_HANDLE_TYPE_FD
;
805 pscreen
= vlsurface
->surface
->texture
->screen
;
806 if (!pscreen
->resource_get_handle(pscreen
, vlsurface
->device
->context
,
807 vlsurface
->surface
->texture
, &whandle
,
808 PIPE_HANDLE_USAGE_READ_WRITE
)) {
809 pipe_mutex_unlock(vlsurface
->device
->mutex
);
810 return VDP_STATUS_NO_IMPLEMENTATION
;
813 pipe_mutex_unlock(vlsurface
->device
->mutex
);
815 result
->handle
= whandle
.handle
;
816 result
->width
= vlsurface
->surface
->width
;
817 result
->height
= vlsurface
->surface
->height
;
818 result
->offset
= whandle
.offset
;
819 result
->stride
= whandle
.stride
;
820 result
->format
= PipeToFormatRGBA(vlsurface
->surface
->format
);
822 return VDP_STATUS_OK
;