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
= dev
->vscreen
->color_depth
== 24 &&
84 rgba_format
== VDP_RGBA_FORMAT_B8G8R8A8
;
86 res_tmpl
.target
= PIPE_TEXTURE_2D
;
87 res_tmpl
.format
= VdpFormatRGBAToPipe(rgba_format
);
88 res_tmpl
.width0
= width
;
89 res_tmpl
.height0
= height
;
91 res_tmpl
.array_size
= 1;
92 res_tmpl
.bind
= PIPE_BIND_SAMPLER_VIEW
| PIPE_BIND_RENDER_TARGET
|
93 PIPE_BIND_SHARED
| PIPE_BIND_SCANOUT
;
94 res_tmpl
.usage
= PIPE_USAGE_DEFAULT
;
96 mtx_lock(&dev
->mutex
);
98 if (!CheckSurfaceParams(pipe
->screen
, &res_tmpl
))
101 res
= pipe
->screen
->resource_create(pipe
->screen
, &res_tmpl
);
105 vlVdpDefaultSamplerViewTemplate(&sv_templ
, res
);
106 vlsurface
->sampler_view
= pipe
->create_sampler_view(pipe
, res
, &sv_templ
);
107 if (!vlsurface
->sampler_view
)
110 memset(&surf_templ
, 0, sizeof(surf_templ
));
111 surf_templ
.format
= res
->format
;
112 vlsurface
->surface
= pipe
->create_surface(pipe
, res
, &surf_templ
);
113 if (!vlsurface
->surface
)
116 *surface
= vlAddDataHTAB(vlsurface
);
120 pipe_resource_reference(&res
, NULL
);
122 if (!vl_compositor_init_state(&vlsurface
->cstate
, pipe
))
125 vl_compositor_reset_dirty_area(&vlsurface
->dirty_area
);
126 mtx_unlock(&dev
->mutex
);
128 return VDP_STATUS_OK
;
131 pipe_sampler_view_reference(&vlsurface
->sampler_view
, NULL
);
132 pipe_surface_reference(&vlsurface
->surface
, NULL
);
133 pipe_resource_reference(&res
, NULL
);
135 mtx_unlock(&dev
->mutex
);
136 DeviceReference(&vlsurface
->device
, NULL
);
138 return VDP_STATUS_ERROR
;
142 * Destroy a VdpOutputSurface.
145 vlVdpOutputSurfaceDestroy(VdpOutputSurface surface
)
147 vlVdpOutputSurface
*vlsurface
;
148 struct pipe_context
*pipe
;
150 vlsurface
= vlGetDataHTAB(surface
);
152 return VDP_STATUS_INVALID_HANDLE
;
154 pipe
= vlsurface
->device
->context
;
156 mtx_lock(&vlsurface
->device
->mutex
);
158 pipe_surface_reference(&vlsurface
->surface
, NULL
);
159 pipe_sampler_view_reference(&vlsurface
->sampler_view
, NULL
);
160 pipe
->screen
->fence_reference(pipe
->screen
, &vlsurface
->fence
, NULL
);
161 vl_compositor_cleanup_state(&vlsurface
->cstate
);
162 mtx_unlock(&vlsurface
->device
->mutex
);
164 vlRemoveDataHTAB(surface
);
165 DeviceReference(&vlsurface
->device
, NULL
);
168 return VDP_STATUS_OK
;
172 * Retrieve the parameters used to create a VdpOutputSurface.
175 vlVdpOutputSurfaceGetParameters(VdpOutputSurface surface
,
176 VdpRGBAFormat
*rgba_format
,
177 uint32_t *width
, uint32_t *height
)
179 vlVdpOutputSurface
*vlsurface
;
181 vlsurface
= vlGetDataHTAB(surface
);
183 return VDP_STATUS_INVALID_HANDLE
;
185 *rgba_format
= PipeToFormatRGBA(vlsurface
->sampler_view
->texture
->format
);
186 *width
= vlsurface
->sampler_view
->texture
->width0
;
187 *height
= vlsurface
->sampler_view
->texture
->height0
;
189 return VDP_STATUS_OK
;
193 * Copy image data from a VdpOutputSurface to application memory in the
194 * surface's native format.
197 vlVdpOutputSurfaceGetBitsNative(VdpOutputSurface surface
,
198 VdpRect
const *source_rect
,
199 void *const *destination_data
,
200 uint32_t const *destination_pitches
)
202 vlVdpOutputSurface
*vlsurface
;
203 struct pipe_context
*pipe
;
204 struct pipe_resource
*res
;
206 struct pipe_transfer
*transfer
;
209 vlsurface
= vlGetDataHTAB(surface
);
211 return VDP_STATUS_INVALID_HANDLE
;
213 pipe
= vlsurface
->device
->context
;
215 return VDP_STATUS_INVALID_HANDLE
;
217 if (!destination_data
|| !destination_pitches
)
218 return VDP_STATUS_INVALID_POINTER
;
220 mtx_lock(&vlsurface
->device
->mutex
);
222 res
= vlsurface
->sampler_view
->texture
;
223 box
= RectToPipeBox(source_rect
, res
);
224 map
= pipe
->transfer_map(pipe
, res
, 0, PIPE_TRANSFER_READ
, &box
, &transfer
);
226 mtx_unlock(&vlsurface
->device
->mutex
);
227 return VDP_STATUS_RESOURCES
;
230 util_copy_rect(*destination_data
, res
->format
, *destination_pitches
, 0, 0,
231 box
.width
, box
.height
, map
, transfer
->stride
, 0, 0);
233 pipe_transfer_unmap(pipe
, transfer
);
234 mtx_unlock(&vlsurface
->device
->mutex
);
236 return VDP_STATUS_OK
;
240 * Copy image data from application memory in the surface's native format to
241 * a VdpOutputSurface.
244 vlVdpOutputSurfacePutBitsNative(VdpOutputSurface surface
,
245 void const *const *source_data
,
246 uint32_t const *source_pitches
,
247 VdpRect
const *destination_rect
)
249 vlVdpOutputSurface
*vlsurface
;
250 struct pipe_box dst_box
;
251 struct pipe_context
*pipe
;
253 vlsurface
= vlGetDataHTAB(surface
);
255 return VDP_STATUS_INVALID_HANDLE
;
257 pipe
= vlsurface
->device
->context
;
259 return VDP_STATUS_INVALID_HANDLE
;
261 if (!source_data
|| !source_pitches
)
262 return VDP_STATUS_INVALID_POINTER
;
264 mtx_lock(&vlsurface
->device
->mutex
);
266 dst_box
= RectToPipeBox(destination_rect
, vlsurface
->sampler_view
->texture
);
268 /* Check for a no-op. (application bug?) */
269 if (!dst_box
.width
|| !dst_box
.height
) {
270 mtx_unlock(&vlsurface
->device
->mutex
);
271 return VDP_STATUS_OK
;
274 pipe
->texture_subdata(pipe
, vlsurface
->sampler_view
->texture
, 0,
275 PIPE_TRANSFER_WRITE
, &dst_box
, *source_data
,
277 mtx_unlock(&vlsurface
->device
->mutex
);
279 return VDP_STATUS_OK
;
283 * Copy image data from application memory in a specific indexed format to
284 * a VdpOutputSurface.
287 vlVdpOutputSurfacePutBitsIndexed(VdpOutputSurface surface
,
288 VdpIndexedFormat source_indexed_format
,
289 void const *const *source_data
,
290 uint32_t const *source_pitch
,
291 VdpRect
const *destination_rect
,
292 VdpColorTableFormat color_table_format
,
293 void const *color_table
)
295 vlVdpOutputSurface
*vlsurface
;
296 struct pipe_context
*context
;
297 struct vl_compositor
*compositor
;
298 struct vl_compositor_state
*cstate
;
300 enum pipe_format index_format
;
301 enum pipe_format colortbl_format
;
303 struct pipe_resource
*res
, res_tmpl
;
304 struct pipe_sampler_view sv_tmpl
;
305 struct pipe_sampler_view
*sv_idx
= NULL
, *sv_tbl
= NULL
;
308 struct u_rect dst_rect
;
310 vlsurface
= vlGetDataHTAB(surface
);
312 return VDP_STATUS_INVALID_HANDLE
;
314 context
= vlsurface
->device
->context
;
315 compositor
= &vlsurface
->device
->compositor
;
316 cstate
= &vlsurface
->cstate
;
318 index_format
= FormatIndexedToPipe(source_indexed_format
);
319 if (index_format
== PIPE_FORMAT_NONE
)
320 return VDP_STATUS_INVALID_INDEXED_FORMAT
;
322 if (!source_data
|| !source_pitch
)
323 return VDP_STATUS_INVALID_POINTER
;
325 colortbl_format
= FormatColorTableToPipe(color_table_format
);
326 if (colortbl_format
== PIPE_FORMAT_NONE
)
327 return VDP_STATUS_INVALID_COLOR_TABLE_FORMAT
;
330 return VDP_STATUS_INVALID_POINTER
;
332 memset(&res_tmpl
, 0, sizeof(res_tmpl
));
333 res_tmpl
.target
= PIPE_TEXTURE_2D
;
334 res_tmpl
.format
= index_format
;
336 if (destination_rect
) {
337 res_tmpl
.width0
= abs(destination_rect
->x0
-destination_rect
->x1
);
338 res_tmpl
.height0
= abs(destination_rect
->y0
-destination_rect
->y1
);
340 res_tmpl
.width0
= vlsurface
->surface
->texture
->width0
;
341 res_tmpl
.height0
= vlsurface
->surface
->texture
->height0
;
344 res_tmpl
.array_size
= 1;
345 res_tmpl
.usage
= PIPE_USAGE_STAGING
;
346 res_tmpl
.bind
= PIPE_BIND_SAMPLER_VIEW
;
348 mtx_lock(&vlsurface
->device
->mutex
);
350 if (!CheckSurfaceParams(context
->screen
, &res_tmpl
))
353 res
= context
->screen
->resource_create(context
->screen
, &res_tmpl
);
357 box
.x
= box
.y
= box
.z
= 0;
358 box
.width
= res
->width0
;
359 box
.height
= res
->height0
;
360 box
.depth
= res
->depth0
;
362 context
->texture_subdata(context
, res
, 0, PIPE_TRANSFER_WRITE
, &box
,
363 source_data
[0], source_pitch
[0],
364 source_pitch
[0] * res
->height0
);
366 memset(&sv_tmpl
, 0, sizeof(sv_tmpl
));
367 u_sampler_view_default_template(&sv_tmpl
, res
, res
->format
);
369 sv_idx
= context
->create_sampler_view(context
, res
, &sv_tmpl
);
370 pipe_resource_reference(&res
, NULL
);
375 memset(&res_tmpl
, 0, sizeof(res_tmpl
));
376 res_tmpl
.target
= PIPE_TEXTURE_1D
;
377 res_tmpl
.format
= colortbl_format
;
378 res_tmpl
.width0
= 1 << util_format_get_component_bits(
379 index_format
, UTIL_FORMAT_COLORSPACE_RGB
, 0);
380 res_tmpl
.height0
= 1;
382 res_tmpl
.array_size
= 1;
383 res_tmpl
.usage
= PIPE_USAGE_STAGING
;
384 res_tmpl
.bind
= PIPE_BIND_SAMPLER_VIEW
;
386 res
= context
->screen
->resource_create(context
->screen
, &res_tmpl
);
390 box
.x
= box
.y
= box
.z
= 0;
391 box
.width
= res
->width0
;
392 box
.height
= res
->height0
;
393 box
.depth
= res
->depth0
;
395 context
->texture_subdata(context
, res
, 0, PIPE_TRANSFER_WRITE
, &box
, color_table
,
396 util_format_get_stride(colortbl_format
, res
->width0
), 0);
398 memset(&sv_tmpl
, 0, sizeof(sv_tmpl
));
399 u_sampler_view_default_template(&sv_tmpl
, res
, res
->format
);
401 sv_tbl
= context
->create_sampler_view(context
, res
, &sv_tmpl
);
402 pipe_resource_reference(&res
, NULL
);
407 vl_compositor_clear_layers(cstate
);
408 vl_compositor_set_palette_layer(cstate
, compositor
, 0, sv_idx
, sv_tbl
, NULL
, NULL
, false);
409 vl_compositor_set_layer_dst_area(cstate
, 0, RectToPipe(destination_rect
, &dst_rect
));
410 vl_compositor_render(cstate
, compositor
, vlsurface
->surface
, &vlsurface
->dirty_area
, false);
412 pipe_sampler_view_reference(&sv_idx
, NULL
);
413 pipe_sampler_view_reference(&sv_tbl
, NULL
);
414 mtx_unlock(&vlsurface
->device
->mutex
);
416 return VDP_STATUS_OK
;
419 pipe_sampler_view_reference(&sv_idx
, NULL
);
420 pipe_sampler_view_reference(&sv_tbl
, NULL
);
421 mtx_unlock(&vlsurface
->device
->mutex
);
422 return VDP_STATUS_RESOURCES
;
426 * Copy image data from application memory in a specific YCbCr format to
427 * a VdpOutputSurface.
430 vlVdpOutputSurfacePutBitsYCbCr(VdpOutputSurface surface
,
431 VdpYCbCrFormat source_ycbcr_format
,
432 void const *const *source_data
,
433 uint32_t const *source_pitches
,
434 VdpRect
const *destination_rect
,
435 VdpCSCMatrix
const *csc_matrix
)
437 vlVdpOutputSurface
*vlsurface
;
438 struct vl_compositor
*compositor
;
439 struct vl_compositor_state
*cstate
;
441 struct pipe_context
*pipe
;
442 enum pipe_format format
;
443 struct pipe_video_buffer vtmpl
, *vbuffer
;
444 struct u_rect dst_rect
;
445 struct pipe_sampler_view
**sampler_views
;
449 vlsurface
= vlGetDataHTAB(surface
);
451 return VDP_STATUS_INVALID_HANDLE
;
454 pipe
= vlsurface
->device
->context
;
455 compositor
= &vlsurface
->device
->compositor
;
456 cstate
= &vlsurface
->cstate
;
458 format
= FormatYCBCRToPipe(source_ycbcr_format
);
459 if (format
== PIPE_FORMAT_NONE
)
460 return VDP_STATUS_INVALID_Y_CB_CR_FORMAT
;
462 if (!source_data
|| !source_pitches
)
463 return VDP_STATUS_INVALID_POINTER
;
465 mtx_lock(&vlsurface
->device
->mutex
);
466 memset(&vtmpl
, 0, sizeof(vtmpl
));
467 vtmpl
.buffer_format
= format
;
468 vtmpl
.chroma_format
= FormatYCBCRToPipeChroma(source_ycbcr_format
);
470 if (destination_rect
) {
471 vtmpl
.width
= abs(destination_rect
->x0
-destination_rect
->x1
);
472 vtmpl
.height
= abs(destination_rect
->y0
-destination_rect
->y1
);
474 vtmpl
.width
= vlsurface
->surface
->texture
->width0
;
475 vtmpl
.height
= vlsurface
->surface
->texture
->height0
;
478 vbuffer
= pipe
->create_video_buffer(pipe
, &vtmpl
);
480 mtx_unlock(&vlsurface
->device
->mutex
);
481 return VDP_STATUS_RESOURCES
;
484 sampler_views
= vbuffer
->get_sampler_view_planes(vbuffer
);
485 if (!sampler_views
) {
486 vbuffer
->destroy(vbuffer
);
487 mtx_unlock(&vlsurface
->device
->mutex
);
488 return VDP_STATUS_RESOURCES
;
491 for (i
= 0; i
< 3; ++i
) {
492 struct pipe_sampler_view
*sv
= sampler_views
[i
];
495 struct pipe_box dst_box
= {
497 sv
->texture
->width0
, sv
->texture
->height0
, 1
500 pipe
->texture_subdata(pipe
, sv
->texture
, 0, PIPE_TRANSFER_WRITE
, &dst_box
,
501 source_data
[i
], source_pitches
[i
], 0);
506 vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_BT_601
, NULL
, 1, &csc
);
507 if (!vl_compositor_set_csc_matrix(cstate
, (const vl_csc_matrix
*)&csc
, 1.0f
, 0.0f
))
510 if (!vl_compositor_set_csc_matrix(cstate
, csc_matrix
, 1.0f
, 0.0f
))
514 vl_compositor_clear_layers(cstate
);
515 vl_compositor_set_buffer_layer(cstate
, compositor
, 0, vbuffer
, NULL
, NULL
, VL_COMPOSITOR_WEAVE
);
516 vl_compositor_set_layer_dst_area(cstate
, 0, RectToPipe(destination_rect
, &dst_rect
));
517 vl_compositor_render(cstate
, compositor
, vlsurface
->surface
, &vlsurface
->dirty_area
, false);
519 vbuffer
->destroy(vbuffer
);
520 mtx_unlock(&vlsurface
->device
->mutex
);
522 return VDP_STATUS_OK
;
524 vbuffer
->destroy(vbuffer
);
525 mtx_unlock(&vlsurface
->device
->mutex
);
526 return VDP_STATUS_ERROR
;
530 BlendFactorToPipe(VdpOutputSurfaceRenderBlendFactor factor
)
533 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ZERO
:
534 return PIPE_BLENDFACTOR_ZERO
;
535 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE
:
536 return PIPE_BLENDFACTOR_ONE
;
537 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_COLOR
:
538 return PIPE_BLENDFACTOR_SRC_COLOR
;
539 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_COLOR
:
540 return PIPE_BLENDFACTOR_INV_SRC_COLOR
;
541 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_ALPHA
:
542 return PIPE_BLENDFACTOR_SRC_ALPHA
;
543 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA
:
544 return PIPE_BLENDFACTOR_INV_SRC_ALPHA
;
545 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_DST_ALPHA
:
546 return PIPE_BLENDFACTOR_DST_ALPHA
;
547 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_DST_ALPHA
:
548 return PIPE_BLENDFACTOR_INV_DST_ALPHA
;
549 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_DST_COLOR
:
550 return PIPE_BLENDFACTOR_DST_COLOR
;
551 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_DST_COLOR
:
552 return PIPE_BLENDFACTOR_INV_DST_COLOR
;
553 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_ALPHA_SATURATE
:
554 return PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE
;
555 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_CONSTANT_COLOR
:
556 return PIPE_BLENDFACTOR_CONST_COLOR
;
557 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR
:
558 return PIPE_BLENDFACTOR_INV_CONST_COLOR
;
559 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_CONSTANT_ALPHA
:
560 return PIPE_BLENDFACTOR_CONST_ALPHA
;
561 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA
:
562 return PIPE_BLENDFACTOR_INV_CONST_ALPHA
;
565 return PIPE_BLENDFACTOR_ONE
;
570 BlendEquationToPipe(VdpOutputSurfaceRenderBlendEquation equation
)
573 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_SUBTRACT
:
574 return PIPE_BLEND_SUBTRACT
;
575 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_REVERSE_SUBTRACT
:
576 return PIPE_BLEND_REVERSE_SUBTRACT
;
577 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD
:
578 return PIPE_BLEND_ADD
;
579 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_MIN
:
580 return PIPE_BLEND_MIN
;
581 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_MAX
:
582 return PIPE_BLEND_MAX
;
585 return PIPE_BLEND_ADD
;
590 BlenderToPipe(struct pipe_context
*context
,
591 VdpOutputSurfaceRenderBlendState
const *blend_state
)
593 struct pipe_blend_state blend
;
595 memset(&blend
, 0, sizeof blend
);
596 blend
.independent_blend_enable
= 0;
599 blend
.rt
[0].blend_enable
= 1;
600 blend
.rt
[0].rgb_src_factor
= BlendFactorToPipe(blend_state
->blend_factor_source_color
);
601 blend
.rt
[0].rgb_dst_factor
= BlendFactorToPipe(blend_state
->blend_factor_destination_color
);
602 blend
.rt
[0].alpha_src_factor
= BlendFactorToPipe(blend_state
->blend_factor_source_alpha
);
603 blend
.rt
[0].alpha_dst_factor
= BlendFactorToPipe(blend_state
->blend_factor_destination_alpha
);
604 blend
.rt
[0].rgb_func
= BlendEquationToPipe(blend_state
->blend_equation_color
);
605 blend
.rt
[0].alpha_func
= BlendEquationToPipe(blend_state
->blend_equation_alpha
);
607 blend
.rt
[0].blend_enable
= 0;
610 blend
.logicop_enable
= 0;
611 blend
.logicop_func
= PIPE_LOGICOP_CLEAR
;
612 blend
.rt
[0].colormask
= PIPE_MASK_RGBA
;
615 return context
->create_blend_state(context
, &blend
);
618 static struct vertex4f
*
619 ColorsToPipe(VdpColor
const *colors
, uint32_t flags
, struct vertex4f result
[4])
622 struct vertex4f
*dst
= result
;
627 for (i
= 0; i
< 4; ++i
) {
628 dst
->x
= colors
->red
;
629 dst
->y
= colors
->green
;
630 dst
->z
= colors
->blue
;
631 dst
->w
= colors
->alpha
;
634 if (flags
& VDP_OUTPUT_SURFACE_RENDER_COLOR_PER_VERTEX
)
641 * Composite a sub-rectangle of a VdpOutputSurface into a sub-rectangle of
642 * another VdpOutputSurface; Output Surface object VdpOutputSurface.
645 vlVdpOutputSurfaceRenderOutputSurface(VdpOutputSurface destination_surface
,
646 VdpRect
const *destination_rect
,
647 VdpOutputSurface source_surface
,
648 VdpRect
const *source_rect
,
649 VdpColor
const *colors
,
650 VdpOutputSurfaceRenderBlendState
const *blend_state
,
653 vlVdpOutputSurface
*dst_vlsurface
;
655 struct pipe_context
*context
;
656 struct pipe_sampler_view
*src_sv
;
657 struct vl_compositor
*compositor
;
658 struct vl_compositor_state
*cstate
;
660 struct u_rect src_rect
, dst_rect
;
662 struct vertex4f vlcolors
[4];
665 dst_vlsurface
= vlGetDataHTAB(destination_surface
);
667 return VDP_STATUS_INVALID_HANDLE
;
669 if (source_surface
== VDP_INVALID_HANDLE
) {
670 src_sv
= dst_vlsurface
->device
->dummy_sv
;
673 vlVdpOutputSurface
*src_vlsurface
= vlGetDataHTAB(source_surface
);
675 return VDP_STATUS_INVALID_HANDLE
;
677 if (dst_vlsurface
->device
!= src_vlsurface
->device
)
678 return VDP_STATUS_HANDLE_DEVICE_MISMATCH
;
680 src_sv
= src_vlsurface
->sampler_view
;
683 mtx_lock(&dst_vlsurface
->device
->mutex
);
685 context
= dst_vlsurface
->device
->context
;
686 compositor
= &dst_vlsurface
->device
->compositor
;
687 cstate
= &dst_vlsurface
->cstate
;
689 blend
= BlenderToPipe(context
, blend_state
);
691 vl_compositor_clear_layers(cstate
);
692 vl_compositor_set_layer_blend(cstate
, 0, blend
, false);
693 vl_compositor_set_rgba_layer(cstate
, compositor
, 0, src_sv
,
694 RectToPipe(source_rect
, &src_rect
), NULL
,
695 ColorsToPipe(colors
, flags
, vlcolors
));
696 STATIC_ASSERT(VL_COMPOSITOR_ROTATE_0
== VDP_OUTPUT_SURFACE_RENDER_ROTATE_0
);
697 STATIC_ASSERT(VL_COMPOSITOR_ROTATE_90
== VDP_OUTPUT_SURFACE_RENDER_ROTATE_90
);
698 STATIC_ASSERT(VL_COMPOSITOR_ROTATE_180
== VDP_OUTPUT_SURFACE_RENDER_ROTATE_180
);
699 STATIC_ASSERT(VL_COMPOSITOR_ROTATE_270
== VDP_OUTPUT_SURFACE_RENDER_ROTATE_270
);
700 vl_compositor_set_layer_rotation(cstate
, 0, flags
& 3);
701 vl_compositor_set_layer_dst_area(cstate
, 0, RectToPipe(destination_rect
, &dst_rect
));
702 vl_compositor_render(cstate
, compositor
, dst_vlsurface
->surface
, &dst_vlsurface
->dirty_area
, false);
704 context
->delete_blend_state(context
, blend
);
705 mtx_unlock(&dst_vlsurface
->device
->mutex
);
707 return VDP_STATUS_OK
;
711 * Composite a sub-rectangle of a VdpBitmapSurface into a sub-rectangle of
712 * a VdpOutputSurface; Output Surface object VdpOutputSurface.
715 vlVdpOutputSurfaceRenderBitmapSurface(VdpOutputSurface destination_surface
,
716 VdpRect
const *destination_rect
,
717 VdpBitmapSurface source_surface
,
718 VdpRect
const *source_rect
,
719 VdpColor
const *colors
,
720 VdpOutputSurfaceRenderBlendState
const *blend_state
,
723 vlVdpOutputSurface
*dst_vlsurface
;
725 struct pipe_context
*context
;
726 struct pipe_sampler_view
*src_sv
;
727 struct vl_compositor
*compositor
;
728 struct vl_compositor_state
*cstate
;
730 struct u_rect src_rect
, dst_rect
;
732 struct vertex4f vlcolors
[4];
735 dst_vlsurface
= vlGetDataHTAB(destination_surface
);
737 return VDP_STATUS_INVALID_HANDLE
;
739 if (source_surface
== VDP_INVALID_HANDLE
) {
740 src_sv
= dst_vlsurface
->device
->dummy_sv
;
743 vlVdpBitmapSurface
*src_vlsurface
= vlGetDataHTAB(source_surface
);
745 return VDP_STATUS_INVALID_HANDLE
;
747 if (dst_vlsurface
->device
!= src_vlsurface
->device
)
748 return VDP_STATUS_HANDLE_DEVICE_MISMATCH
;
750 src_sv
= src_vlsurface
->sampler_view
;
753 context
= dst_vlsurface
->device
->context
;
754 compositor
= &dst_vlsurface
->device
->compositor
;
755 cstate
= &dst_vlsurface
->cstate
;
757 mtx_lock(&dst_vlsurface
->device
->mutex
);
759 blend
= BlenderToPipe(context
, blend_state
);
761 vl_compositor_clear_layers(cstate
);
762 vl_compositor_set_layer_blend(cstate
, 0, blend
, false);
763 vl_compositor_set_rgba_layer(cstate
, compositor
, 0, src_sv
,
764 RectToPipe(source_rect
, &src_rect
), NULL
,
765 ColorsToPipe(colors
, flags
, vlcolors
));
766 vl_compositor_set_layer_rotation(cstate
, 0, flags
& 3);
767 vl_compositor_set_layer_dst_area(cstate
, 0, RectToPipe(destination_rect
, &dst_rect
));
768 vl_compositor_render(cstate
, compositor
, dst_vlsurface
->surface
, &dst_vlsurface
->dirty_area
, false);
770 context
->delete_blend_state(context
, blend
);
771 mtx_unlock(&dst_vlsurface
->device
->mutex
);
773 return VDP_STATUS_OK
;
776 struct pipe_resource
*vlVdpOutputSurfaceGallium(VdpOutputSurface surface
)
778 vlVdpOutputSurface
*vlsurface
;
780 vlsurface
= vlGetDataHTAB(surface
);
781 if (!vlsurface
|| !vlsurface
->surface
)
784 mtx_lock(&vlsurface
->device
->mutex
);
785 vlsurface
->device
->context
->flush(vlsurface
->device
->context
, NULL
, 0);
786 mtx_unlock(&vlsurface
->device
->mutex
);
788 return vlsurface
->surface
->texture
;
791 VdpStatus
vlVdpOutputSurfaceDMABuf(VdpOutputSurface surface
,
792 struct VdpSurfaceDMABufDesc
*result
)
794 vlVdpOutputSurface
*vlsurface
;
795 struct pipe_screen
*pscreen
;
796 struct winsys_handle whandle
;
798 memset(result
, 0, sizeof(*result
));
801 vlsurface
= vlGetDataHTAB(surface
);
802 if (!vlsurface
|| !vlsurface
->surface
)
803 return VDP_STATUS_INVALID_HANDLE
;
805 mtx_lock(&vlsurface
->device
->mutex
);
806 vlsurface
->device
->context
->flush(vlsurface
->device
->context
, NULL
, 0);
808 memset(&whandle
, 0, sizeof(struct winsys_handle
));
809 whandle
.type
= WINSYS_HANDLE_TYPE_FD
;
811 pscreen
= vlsurface
->surface
->texture
->screen
;
812 if (!pscreen
->resource_get_handle(pscreen
, vlsurface
->device
->context
,
813 vlsurface
->surface
->texture
, &whandle
,
814 PIPE_HANDLE_USAGE_READ_WRITE
)) {
815 mtx_unlock(&vlsurface
->device
->mutex
);
816 return VDP_STATUS_NO_IMPLEMENTATION
;
819 mtx_unlock(&vlsurface
->device
->mutex
);
821 result
->handle
= whandle
.handle
;
822 result
->width
= vlsurface
->surface
->width
;
823 result
->height
= vlsurface
->surface
->height
;
824 result
->offset
= whandle
.offset
;
825 result
->stride
= whandle
.stride
;
826 result
->format
= PipeToFormatRGBA(vlsurface
->surface
->format
);
828 return VDP_STATUS_OK
;