17ec681f3Smrg/************************************************************************** 27ec681f3Smrg * 37ec681f3Smrg * Copyright 2010 Thomas Balling Sørensen. 47ec681f3Smrg * Copyright 2011 Christian König. 57ec681f3Smrg * All Rights Reserved. 67ec681f3Smrg * 77ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 87ec681f3Smrg * copy of this software and associated documentation files (the 97ec681f3Smrg * "Software"), to deal in the Software without restriction, including 107ec681f3Smrg * without limitation the rights to use, copy, modify, merge, publish, 117ec681f3Smrg * distribute, sub license, and/or sell copies of the Software, and to 127ec681f3Smrg * permit persons to whom the Software is furnished to do so, subject to 137ec681f3Smrg * the following conditions: 147ec681f3Smrg * 157ec681f3Smrg * The above copyright notice and this permission notice (including the 167ec681f3Smrg * next paragraph) shall be included in all copies or substantial portions 177ec681f3Smrg * of the Software. 187ec681f3Smrg * 197ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 207ec681f3Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 217ec681f3Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 227ec681f3Smrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 237ec681f3Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 247ec681f3Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 257ec681f3Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 267ec681f3Smrg * 277ec681f3Smrg **************************************************************************/ 287ec681f3Smrg 297ec681f3Smrg#include <vdpau/vdpau.h> 307ec681f3Smrg 317ec681f3Smrg#include "util/u_debug.h" 327ec681f3Smrg#include "util/u_memory.h" 337ec681f3Smrg#include "util/u_sampler.h" 347ec681f3Smrg#include "util/format/u_format.h" 357ec681f3Smrg#include "util/u_surface.h" 367ec681f3Smrg 377ec681f3Smrg#include "vl/vl_csc.h" 387ec681f3Smrg 397ec681f3Smrg#include "frontend/drm_driver.h" 407ec681f3Smrg 417ec681f3Smrg#include "vdpau_private.h" 427ec681f3Smrg 437ec681f3Smrg/** 447ec681f3Smrg * Create a VdpOutputSurface. 457ec681f3Smrg */ 467ec681f3SmrgVdpStatus 477ec681f3SmrgvlVdpOutputSurfaceCreate(VdpDevice device, 487ec681f3Smrg VdpRGBAFormat rgba_format, 497ec681f3Smrg uint32_t width, uint32_t height, 507ec681f3Smrg VdpOutputSurface *surface) 517ec681f3Smrg{ 527ec681f3Smrg struct pipe_context *pipe; 537ec681f3Smrg struct pipe_resource res_tmpl, *res; 547ec681f3Smrg struct pipe_sampler_view sv_templ; 557ec681f3Smrg struct pipe_surface surf_templ; 567ec681f3Smrg 577ec681f3Smrg vlVdpOutputSurface *vlsurface = NULL; 587ec681f3Smrg 597ec681f3Smrg if (!(width && height)) 607ec681f3Smrg return VDP_STATUS_INVALID_SIZE; 617ec681f3Smrg 627ec681f3Smrg vlVdpDevice *dev = vlGetDataHTAB(device); 637ec681f3Smrg if (!dev) 647ec681f3Smrg return VDP_STATUS_INVALID_HANDLE; 657ec681f3Smrg 667ec681f3Smrg pipe = dev->context; 677ec681f3Smrg if (!pipe) 687ec681f3Smrg return VDP_STATUS_INVALID_HANDLE; 697ec681f3Smrg 707ec681f3Smrg vlsurface = CALLOC(1, sizeof(vlVdpOutputSurface)); 717ec681f3Smrg if (!vlsurface) 727ec681f3Smrg return VDP_STATUS_RESOURCES; 737ec681f3Smrg 747ec681f3Smrg DeviceReference(&vlsurface->device, dev); 757ec681f3Smrg 767ec681f3Smrg memset(&res_tmpl, 0, sizeof(res_tmpl)); 777ec681f3Smrg 787ec681f3Smrg /* 797ec681f3Smrg * The output won't look correctly when this buffer is send to X, 807ec681f3Smrg * if the VDPAU RGB component order doesn't match the X11 one so 817ec681f3Smrg * we only allow the X11 format 827ec681f3Smrg */ 837ec681f3Smrg vlsurface->send_to_X = dev->vscreen->color_depth == 24 && 847ec681f3Smrg rgba_format == VDP_RGBA_FORMAT_B8G8R8A8; 857ec681f3Smrg 867ec681f3Smrg res_tmpl.target = PIPE_TEXTURE_2D; 877ec681f3Smrg res_tmpl.format = VdpFormatRGBAToPipe(rgba_format); 887ec681f3Smrg res_tmpl.width0 = width; 897ec681f3Smrg res_tmpl.height0 = height; 907ec681f3Smrg res_tmpl.depth0 = 1; 917ec681f3Smrg res_tmpl.array_size = 1; 927ec681f3Smrg res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET | 937ec681f3Smrg PIPE_BIND_SHARED | PIPE_BIND_SCANOUT; 947ec681f3Smrg res_tmpl.usage = PIPE_USAGE_DEFAULT; 957ec681f3Smrg 967ec681f3Smrg mtx_lock(&dev->mutex); 977ec681f3Smrg 987ec681f3Smrg if (!CheckSurfaceParams(pipe->screen, &res_tmpl)) 997ec681f3Smrg goto err_unlock; 1007ec681f3Smrg 1017ec681f3Smrg res = pipe->screen->resource_create(pipe->screen, &res_tmpl); 1027ec681f3Smrg if (!res) 1037ec681f3Smrg goto err_unlock; 1047ec681f3Smrg 1057ec681f3Smrg vlVdpDefaultSamplerViewTemplate(&sv_templ, res); 1067ec681f3Smrg vlsurface->sampler_view = pipe->create_sampler_view(pipe, res, &sv_templ); 1077ec681f3Smrg if (!vlsurface->sampler_view) 1087ec681f3Smrg goto err_resource; 1097ec681f3Smrg 1107ec681f3Smrg memset(&surf_templ, 0, sizeof(surf_templ)); 1117ec681f3Smrg surf_templ.format = res->format; 1127ec681f3Smrg vlsurface->surface = pipe->create_surface(pipe, res, &surf_templ); 1137ec681f3Smrg if (!vlsurface->surface) 1147ec681f3Smrg goto err_resource; 1157ec681f3Smrg 1167ec681f3Smrg *surface = vlAddDataHTAB(vlsurface); 1177ec681f3Smrg if (*surface == 0) 1187ec681f3Smrg goto err_resource; 1197ec681f3Smrg 1207ec681f3Smrg pipe_resource_reference(&res, NULL); 1217ec681f3Smrg 1227ec681f3Smrg if (!vl_compositor_init_state(&vlsurface->cstate, pipe)) 1237ec681f3Smrg goto err_resource; 1247ec681f3Smrg 1257ec681f3Smrg vl_compositor_reset_dirty_area(&vlsurface->dirty_area); 1267ec681f3Smrg mtx_unlock(&dev->mutex); 1277ec681f3Smrg 1287ec681f3Smrg return VDP_STATUS_OK; 1297ec681f3Smrg 1307ec681f3Smrgerr_resource: 1317ec681f3Smrg pipe_sampler_view_reference(&vlsurface->sampler_view, NULL); 1327ec681f3Smrg pipe_surface_reference(&vlsurface->surface, NULL); 1337ec681f3Smrg pipe_resource_reference(&res, NULL); 1347ec681f3Smrgerr_unlock: 1357ec681f3Smrg mtx_unlock(&dev->mutex); 1367ec681f3Smrg DeviceReference(&vlsurface->device, NULL); 1377ec681f3Smrg FREE(vlsurface); 1387ec681f3Smrg return VDP_STATUS_ERROR; 1397ec681f3Smrg} 1407ec681f3Smrg 1417ec681f3Smrg/** 1427ec681f3Smrg * Destroy a VdpOutputSurface. 1437ec681f3Smrg */ 1447ec681f3SmrgVdpStatus 1457ec681f3SmrgvlVdpOutputSurfaceDestroy(VdpOutputSurface surface) 1467ec681f3Smrg{ 1477ec681f3Smrg vlVdpOutputSurface *vlsurface; 1487ec681f3Smrg struct pipe_context *pipe; 1497ec681f3Smrg 1507ec681f3Smrg vlsurface = vlGetDataHTAB(surface); 1517ec681f3Smrg if (!vlsurface) 1527ec681f3Smrg return VDP_STATUS_INVALID_HANDLE; 1537ec681f3Smrg 1547ec681f3Smrg pipe = vlsurface->device->context; 1557ec681f3Smrg 1567ec681f3Smrg mtx_lock(&vlsurface->device->mutex); 1577ec681f3Smrg 1587ec681f3Smrg pipe_surface_reference(&vlsurface->surface, NULL); 1597ec681f3Smrg pipe_sampler_view_reference(&vlsurface->sampler_view, NULL); 1607ec681f3Smrg pipe->screen->fence_reference(pipe->screen, &vlsurface->fence, NULL); 1617ec681f3Smrg vl_compositor_cleanup_state(&vlsurface->cstate); 1627ec681f3Smrg mtx_unlock(&vlsurface->device->mutex); 1637ec681f3Smrg 1647ec681f3Smrg vlRemoveDataHTAB(surface); 1657ec681f3Smrg DeviceReference(&vlsurface->device, NULL); 1667ec681f3Smrg FREE(vlsurface); 1677ec681f3Smrg 1687ec681f3Smrg return VDP_STATUS_OK; 1697ec681f3Smrg} 1707ec681f3Smrg 1717ec681f3Smrg/** 1727ec681f3Smrg * Retrieve the parameters used to create a VdpOutputSurface. 1737ec681f3Smrg */ 1747ec681f3SmrgVdpStatus 1757ec681f3SmrgvlVdpOutputSurfaceGetParameters(VdpOutputSurface surface, 1767ec681f3Smrg VdpRGBAFormat *rgba_format, 1777ec681f3Smrg uint32_t *width, uint32_t *height) 1787ec681f3Smrg{ 1797ec681f3Smrg vlVdpOutputSurface *vlsurface; 1807ec681f3Smrg 1817ec681f3Smrg vlsurface = vlGetDataHTAB(surface); 1827ec681f3Smrg if (!vlsurface) 1837ec681f3Smrg return VDP_STATUS_INVALID_HANDLE; 1847ec681f3Smrg 1857ec681f3Smrg *rgba_format = PipeToFormatRGBA(vlsurface->sampler_view->texture->format); 1867ec681f3Smrg *width = vlsurface->sampler_view->texture->width0; 1877ec681f3Smrg *height = vlsurface->sampler_view->texture->height0; 1887ec681f3Smrg 1897ec681f3Smrg return VDP_STATUS_OK; 1907ec681f3Smrg} 1917ec681f3Smrg 1927ec681f3Smrg/** 1937ec681f3Smrg * Copy image data from a VdpOutputSurface to application memory in the 1947ec681f3Smrg * surface's native format. 1957ec681f3Smrg */ 1967ec681f3SmrgVdpStatus 1977ec681f3SmrgvlVdpOutputSurfaceGetBitsNative(VdpOutputSurface surface, 1987ec681f3Smrg VdpRect const *source_rect, 1997ec681f3Smrg void *const *destination_data, 2007ec681f3Smrg uint32_t const *destination_pitches) 2017ec681f3Smrg{ 2027ec681f3Smrg vlVdpOutputSurface *vlsurface; 2037ec681f3Smrg struct pipe_context *pipe; 2047ec681f3Smrg struct pipe_resource *res; 2057ec681f3Smrg struct pipe_box box; 2067ec681f3Smrg struct pipe_transfer *transfer; 2077ec681f3Smrg uint8_t *map; 2087ec681f3Smrg 2097ec681f3Smrg vlsurface = vlGetDataHTAB(surface); 2107ec681f3Smrg if (!vlsurface) 2117ec681f3Smrg return VDP_STATUS_INVALID_HANDLE; 2127ec681f3Smrg 2137ec681f3Smrg pipe = vlsurface->device->context; 2147ec681f3Smrg if (!pipe) 2157ec681f3Smrg return VDP_STATUS_INVALID_HANDLE; 2167ec681f3Smrg 2177ec681f3Smrg if (!destination_data || !destination_pitches) 2187ec681f3Smrg return VDP_STATUS_INVALID_POINTER; 2197ec681f3Smrg 2207ec681f3Smrg mtx_lock(&vlsurface->device->mutex); 2217ec681f3Smrg 2227ec681f3Smrg res = vlsurface->sampler_view->texture; 2237ec681f3Smrg box = RectToPipeBox(source_rect, res); 2247ec681f3Smrg map = pipe->texture_map(pipe, res, 0, PIPE_MAP_READ, &box, &transfer); 2257ec681f3Smrg if (!map) { 2267ec681f3Smrg mtx_unlock(&vlsurface->device->mutex); 2277ec681f3Smrg return VDP_STATUS_RESOURCES; 2287ec681f3Smrg } 2297ec681f3Smrg 2307ec681f3Smrg util_copy_rect(*destination_data, res->format, *destination_pitches, 0, 0, 2317ec681f3Smrg box.width, box.height, map, transfer->stride, 0, 0); 2327ec681f3Smrg 2337ec681f3Smrg pipe_texture_unmap(pipe, transfer); 2347ec681f3Smrg mtx_unlock(&vlsurface->device->mutex); 2357ec681f3Smrg 2367ec681f3Smrg return VDP_STATUS_OK; 2377ec681f3Smrg} 2387ec681f3Smrg 2397ec681f3Smrg/** 2407ec681f3Smrg * Copy image data from application memory in the surface's native format to 2417ec681f3Smrg * a VdpOutputSurface. 2427ec681f3Smrg */ 2437ec681f3SmrgVdpStatus 2447ec681f3SmrgvlVdpOutputSurfacePutBitsNative(VdpOutputSurface surface, 2457ec681f3Smrg void const *const *source_data, 2467ec681f3Smrg uint32_t const *source_pitches, 2477ec681f3Smrg VdpRect const *destination_rect) 2487ec681f3Smrg{ 2497ec681f3Smrg vlVdpOutputSurface *vlsurface; 2507ec681f3Smrg struct pipe_box dst_box; 2517ec681f3Smrg struct pipe_context *pipe; 2527ec681f3Smrg 2537ec681f3Smrg vlsurface = vlGetDataHTAB(surface); 2547ec681f3Smrg if (!vlsurface) 2557ec681f3Smrg return VDP_STATUS_INVALID_HANDLE; 2567ec681f3Smrg 2577ec681f3Smrg pipe = vlsurface->device->context; 2587ec681f3Smrg if (!pipe) 2597ec681f3Smrg return VDP_STATUS_INVALID_HANDLE; 2607ec681f3Smrg 2617ec681f3Smrg if (!source_data || !source_pitches) 2627ec681f3Smrg return VDP_STATUS_INVALID_POINTER; 2637ec681f3Smrg 2647ec681f3Smrg mtx_lock(&vlsurface->device->mutex); 2657ec681f3Smrg 2667ec681f3Smrg dst_box = RectToPipeBox(destination_rect, vlsurface->sampler_view->texture); 2677ec681f3Smrg 2687ec681f3Smrg /* Check for a no-op. (application bug?) */ 2697ec681f3Smrg if (!dst_box.width || !dst_box.height) { 2707ec681f3Smrg mtx_unlock(&vlsurface->device->mutex); 2717ec681f3Smrg return VDP_STATUS_OK; 2727ec681f3Smrg } 2737ec681f3Smrg 2747ec681f3Smrg pipe->texture_subdata(pipe, vlsurface->sampler_view->texture, 0, 2757ec681f3Smrg PIPE_MAP_WRITE, &dst_box, *source_data, 2767ec681f3Smrg *source_pitches, 0); 2777ec681f3Smrg mtx_unlock(&vlsurface->device->mutex); 2787ec681f3Smrg 2797ec681f3Smrg return VDP_STATUS_OK; 2807ec681f3Smrg} 2817ec681f3Smrg 2827ec681f3Smrg/** 2837ec681f3Smrg * Copy image data from application memory in a specific indexed format to 2847ec681f3Smrg * a VdpOutputSurface. 2857ec681f3Smrg */ 2867ec681f3SmrgVdpStatus 2877ec681f3SmrgvlVdpOutputSurfacePutBitsIndexed(VdpOutputSurface surface, 2887ec681f3Smrg VdpIndexedFormat source_indexed_format, 2897ec681f3Smrg void const *const *source_data, 2907ec681f3Smrg uint32_t const *source_pitch, 2917ec681f3Smrg VdpRect const *destination_rect, 2927ec681f3Smrg VdpColorTableFormat color_table_format, 2937ec681f3Smrg void const *color_table) 2947ec681f3Smrg{ 2957ec681f3Smrg vlVdpOutputSurface *vlsurface; 2967ec681f3Smrg struct pipe_context *context; 2977ec681f3Smrg struct vl_compositor *compositor; 2987ec681f3Smrg struct vl_compositor_state *cstate; 2997ec681f3Smrg 3007ec681f3Smrg enum pipe_format index_format; 3017ec681f3Smrg enum pipe_format colortbl_format; 3027ec681f3Smrg 3037ec681f3Smrg struct pipe_resource *res, res_tmpl; 3047ec681f3Smrg struct pipe_sampler_view sv_tmpl; 3057ec681f3Smrg struct pipe_sampler_view *sv_idx = NULL, *sv_tbl = NULL; 3067ec681f3Smrg 3077ec681f3Smrg struct pipe_box box; 3087ec681f3Smrg struct u_rect dst_rect; 3097ec681f3Smrg 3107ec681f3Smrg vlsurface = vlGetDataHTAB(surface); 3117ec681f3Smrg if (!vlsurface) 3127ec681f3Smrg return VDP_STATUS_INVALID_HANDLE; 3137ec681f3Smrg 3147ec681f3Smrg context = vlsurface->device->context; 3157ec681f3Smrg compositor = &vlsurface->device->compositor; 3167ec681f3Smrg cstate = &vlsurface->cstate; 3177ec681f3Smrg 3187ec681f3Smrg index_format = FormatIndexedToPipe(source_indexed_format); 3197ec681f3Smrg if (index_format == PIPE_FORMAT_NONE) 3207ec681f3Smrg return VDP_STATUS_INVALID_INDEXED_FORMAT; 3217ec681f3Smrg 3227ec681f3Smrg if (!source_data || !source_pitch) 3237ec681f3Smrg return VDP_STATUS_INVALID_POINTER; 3247ec681f3Smrg 3257ec681f3Smrg colortbl_format = FormatColorTableToPipe(color_table_format); 3267ec681f3Smrg if (colortbl_format == PIPE_FORMAT_NONE) 3277ec681f3Smrg return VDP_STATUS_INVALID_COLOR_TABLE_FORMAT; 3287ec681f3Smrg 3297ec681f3Smrg if (!color_table) 3307ec681f3Smrg return VDP_STATUS_INVALID_POINTER; 3317ec681f3Smrg 3327ec681f3Smrg memset(&res_tmpl, 0, sizeof(res_tmpl)); 3337ec681f3Smrg res_tmpl.target = PIPE_TEXTURE_2D; 3347ec681f3Smrg res_tmpl.format = index_format; 3357ec681f3Smrg 3367ec681f3Smrg if (destination_rect) { 3377ec681f3Smrg if (destination_rect->x1 > destination_rect->x0 && 3387ec681f3Smrg destination_rect->y1 > destination_rect->y0) { 3397ec681f3Smrg res_tmpl.width0 = destination_rect->x1 - destination_rect->x0; 3407ec681f3Smrg res_tmpl.height0 = destination_rect->y1 - destination_rect->y0; 3417ec681f3Smrg } 3427ec681f3Smrg } else { 3437ec681f3Smrg res_tmpl.width0 = vlsurface->surface->texture->width0; 3447ec681f3Smrg res_tmpl.height0 = vlsurface->surface->texture->height0; 3457ec681f3Smrg } 3467ec681f3Smrg res_tmpl.depth0 = 1; 3477ec681f3Smrg res_tmpl.array_size = 1; 3487ec681f3Smrg res_tmpl.usage = PIPE_USAGE_STAGING; 3497ec681f3Smrg res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW; 3507ec681f3Smrg 3517ec681f3Smrg mtx_lock(&vlsurface->device->mutex); 3527ec681f3Smrg 3537ec681f3Smrg if (!CheckSurfaceParams(context->screen, &res_tmpl)) 3547ec681f3Smrg goto error_resource; 3557ec681f3Smrg 3567ec681f3Smrg res = context->screen->resource_create(context->screen, &res_tmpl); 3577ec681f3Smrg if (!res) 3587ec681f3Smrg goto error_resource; 3597ec681f3Smrg 3607ec681f3Smrg box.x = box.y = box.z = 0; 3617ec681f3Smrg box.width = res->width0; 3627ec681f3Smrg box.height = res->height0; 3637ec681f3Smrg box.depth = res->depth0; 3647ec681f3Smrg 3657ec681f3Smrg context->texture_subdata(context, res, 0, PIPE_MAP_WRITE, &box, 3667ec681f3Smrg source_data[0], source_pitch[0], 3677ec681f3Smrg source_pitch[0] * res->height0); 3687ec681f3Smrg 3697ec681f3Smrg memset(&sv_tmpl, 0, sizeof(sv_tmpl)); 3707ec681f3Smrg u_sampler_view_default_template(&sv_tmpl, res, res->format); 3717ec681f3Smrg 3727ec681f3Smrg sv_idx = context->create_sampler_view(context, res, &sv_tmpl); 3737ec681f3Smrg pipe_resource_reference(&res, NULL); 3747ec681f3Smrg 3757ec681f3Smrg if (!sv_idx) 3767ec681f3Smrg goto error_resource; 3777ec681f3Smrg 3787ec681f3Smrg memset(&res_tmpl, 0, sizeof(res_tmpl)); 3797ec681f3Smrg res_tmpl.target = PIPE_TEXTURE_1D; 3807ec681f3Smrg res_tmpl.format = colortbl_format; 3817ec681f3Smrg res_tmpl.width0 = 1 << util_format_get_component_bits( 3827ec681f3Smrg index_format, UTIL_FORMAT_COLORSPACE_RGB, 0); 3837ec681f3Smrg res_tmpl.height0 = 1; 3847ec681f3Smrg res_tmpl.depth0 = 1; 3857ec681f3Smrg res_tmpl.array_size = 1; 3867ec681f3Smrg res_tmpl.usage = PIPE_USAGE_STAGING; 3877ec681f3Smrg res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW; 3887ec681f3Smrg 3897ec681f3Smrg res = context->screen->resource_create(context->screen, &res_tmpl); 3907ec681f3Smrg if (!res) 3917ec681f3Smrg goto error_resource; 3927ec681f3Smrg 3937ec681f3Smrg box.x = box.y = box.z = 0; 3947ec681f3Smrg box.width = res->width0; 3957ec681f3Smrg box.height = res->height0; 3967ec681f3Smrg box.depth = res->depth0; 3977ec681f3Smrg 3987ec681f3Smrg context->texture_subdata(context, res, 0, PIPE_MAP_WRITE, &box, color_table, 3997ec681f3Smrg util_format_get_stride(colortbl_format, res->width0), 0); 4007ec681f3Smrg 4017ec681f3Smrg memset(&sv_tmpl, 0, sizeof(sv_tmpl)); 4027ec681f3Smrg u_sampler_view_default_template(&sv_tmpl, res, res->format); 4037ec681f3Smrg 4047ec681f3Smrg sv_tbl = context->create_sampler_view(context, res, &sv_tmpl); 4057ec681f3Smrg pipe_resource_reference(&res, NULL); 4067ec681f3Smrg 4077ec681f3Smrg if (!sv_tbl) 4087ec681f3Smrg goto error_resource; 4097ec681f3Smrg 4107ec681f3Smrg vl_compositor_clear_layers(cstate); 4117ec681f3Smrg vl_compositor_set_palette_layer(cstate, compositor, 0, sv_idx, sv_tbl, NULL, NULL, false); 4127ec681f3Smrg vl_compositor_set_layer_dst_area(cstate, 0, RectToPipe(destination_rect, &dst_rect)); 4137ec681f3Smrg vl_compositor_render(cstate, compositor, vlsurface->surface, &vlsurface->dirty_area, false); 4147ec681f3Smrg 4157ec681f3Smrg pipe_sampler_view_reference(&sv_idx, NULL); 4167ec681f3Smrg pipe_sampler_view_reference(&sv_tbl, NULL); 4177ec681f3Smrg mtx_unlock(&vlsurface->device->mutex); 4187ec681f3Smrg 4197ec681f3Smrg return VDP_STATUS_OK; 4207ec681f3Smrg 4217ec681f3Smrgerror_resource: 4227ec681f3Smrg pipe_sampler_view_reference(&sv_idx, NULL); 4237ec681f3Smrg pipe_sampler_view_reference(&sv_tbl, NULL); 4247ec681f3Smrg mtx_unlock(&vlsurface->device->mutex); 4257ec681f3Smrg return VDP_STATUS_RESOURCES; 4267ec681f3Smrg} 4277ec681f3Smrg 4287ec681f3Smrg/** 4297ec681f3Smrg * Copy image data from application memory in a specific YCbCr format to 4307ec681f3Smrg * a VdpOutputSurface. 4317ec681f3Smrg */ 4327ec681f3SmrgVdpStatus 4337ec681f3SmrgvlVdpOutputSurfacePutBitsYCbCr(VdpOutputSurface surface, 4347ec681f3Smrg VdpYCbCrFormat source_ycbcr_format, 4357ec681f3Smrg void const *const *source_data, 4367ec681f3Smrg uint32_t const *source_pitches, 4377ec681f3Smrg VdpRect const *destination_rect, 4387ec681f3Smrg VdpCSCMatrix const *csc_matrix) 4397ec681f3Smrg{ 4407ec681f3Smrg vlVdpOutputSurface *vlsurface; 4417ec681f3Smrg struct vl_compositor *compositor; 4427ec681f3Smrg struct vl_compositor_state *cstate; 4437ec681f3Smrg 4447ec681f3Smrg struct pipe_context *pipe; 4457ec681f3Smrg enum pipe_format format; 4467ec681f3Smrg struct pipe_video_buffer vtmpl, *vbuffer; 4477ec681f3Smrg struct u_rect dst_rect; 4487ec681f3Smrg struct pipe_sampler_view **sampler_views; 4497ec681f3Smrg 4507ec681f3Smrg unsigned i; 4517ec681f3Smrg 4527ec681f3Smrg vlsurface = vlGetDataHTAB(surface); 4537ec681f3Smrg if (!vlsurface) 4547ec681f3Smrg return VDP_STATUS_INVALID_HANDLE; 4557ec681f3Smrg 4567ec681f3Smrg 4577ec681f3Smrg pipe = vlsurface->device->context; 4587ec681f3Smrg compositor = &vlsurface->device->compositor; 4597ec681f3Smrg cstate = &vlsurface->cstate; 4607ec681f3Smrg 4617ec681f3Smrg format = FormatYCBCRToPipe(source_ycbcr_format); 4627ec681f3Smrg if (format == PIPE_FORMAT_NONE) 4637ec681f3Smrg return VDP_STATUS_INVALID_Y_CB_CR_FORMAT; 4647ec681f3Smrg 4657ec681f3Smrg if (!source_data || !source_pitches) 4667ec681f3Smrg return VDP_STATUS_INVALID_POINTER; 4677ec681f3Smrg 4687ec681f3Smrg mtx_lock(&vlsurface->device->mutex); 4697ec681f3Smrg memset(&vtmpl, 0, sizeof(vtmpl)); 4707ec681f3Smrg vtmpl.buffer_format = format; 4717ec681f3Smrg 4727ec681f3Smrg if (destination_rect) { 4737ec681f3Smrg if (destination_rect->x1 > destination_rect->x0 && 4747ec681f3Smrg destination_rect->y1 > destination_rect->y0) { 4757ec681f3Smrg vtmpl.width = destination_rect->x1 - destination_rect->x0; 4767ec681f3Smrg vtmpl.height = destination_rect->y1 - destination_rect->y0; 4777ec681f3Smrg } 4787ec681f3Smrg } else { 4797ec681f3Smrg vtmpl.width = vlsurface->surface->texture->width0; 4807ec681f3Smrg vtmpl.height = vlsurface->surface->texture->height0; 4817ec681f3Smrg } 4827ec681f3Smrg 4837ec681f3Smrg vbuffer = pipe->create_video_buffer(pipe, &vtmpl); 4847ec681f3Smrg if (!vbuffer) { 4857ec681f3Smrg mtx_unlock(&vlsurface->device->mutex); 4867ec681f3Smrg return VDP_STATUS_RESOURCES; 4877ec681f3Smrg } 4887ec681f3Smrg 4897ec681f3Smrg sampler_views = vbuffer->get_sampler_view_planes(vbuffer); 4907ec681f3Smrg if (!sampler_views) { 4917ec681f3Smrg vbuffer->destroy(vbuffer); 4927ec681f3Smrg mtx_unlock(&vlsurface->device->mutex); 4937ec681f3Smrg return VDP_STATUS_RESOURCES; 4947ec681f3Smrg } 4957ec681f3Smrg 4967ec681f3Smrg for (i = 0; i < 3; ++i) { 4977ec681f3Smrg struct pipe_sampler_view *sv = sampler_views[i]; 4987ec681f3Smrg if (!sv) continue; 4997ec681f3Smrg 5007ec681f3Smrg struct pipe_box dst_box = { 5017ec681f3Smrg 0, 0, 0, 5027ec681f3Smrg sv->texture->width0, sv->texture->height0, 1 5037ec681f3Smrg }; 5047ec681f3Smrg 5057ec681f3Smrg pipe->texture_subdata(pipe, sv->texture, 0, PIPE_MAP_WRITE, &dst_box, 5067ec681f3Smrg source_data[i], source_pitches[i], 0); 5077ec681f3Smrg } 5087ec681f3Smrg 5097ec681f3Smrg if (!csc_matrix) { 5107ec681f3Smrg vl_csc_matrix csc; 5117ec681f3Smrg vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_BT_601, NULL, 1, &csc); 5127ec681f3Smrg if (!vl_compositor_set_csc_matrix(cstate, (const vl_csc_matrix*)&csc, 1.0f, 0.0f)) 5137ec681f3Smrg goto err_csc_matrix; 5147ec681f3Smrg } else { 5157ec681f3Smrg if (!vl_compositor_set_csc_matrix(cstate, csc_matrix, 1.0f, 0.0f)) 5167ec681f3Smrg goto err_csc_matrix; 5177ec681f3Smrg } 5187ec681f3Smrg 5197ec681f3Smrg vl_compositor_clear_layers(cstate); 5207ec681f3Smrg vl_compositor_set_buffer_layer(cstate, compositor, 0, vbuffer, NULL, NULL, VL_COMPOSITOR_WEAVE); 5217ec681f3Smrg vl_compositor_set_layer_dst_area(cstate, 0, RectToPipe(destination_rect, &dst_rect)); 5227ec681f3Smrg vl_compositor_render(cstate, compositor, vlsurface->surface, &vlsurface->dirty_area, false); 5237ec681f3Smrg 5247ec681f3Smrg vbuffer->destroy(vbuffer); 5257ec681f3Smrg mtx_unlock(&vlsurface->device->mutex); 5267ec681f3Smrg 5277ec681f3Smrg return VDP_STATUS_OK; 5287ec681f3Smrgerr_csc_matrix: 5297ec681f3Smrg vbuffer->destroy(vbuffer); 5307ec681f3Smrg mtx_unlock(&vlsurface->device->mutex); 5317ec681f3Smrg return VDP_STATUS_ERROR; 5327ec681f3Smrg} 5337ec681f3Smrg 5347ec681f3Smrgstatic unsigned 5357ec681f3SmrgBlendFactorToPipe(VdpOutputSurfaceRenderBlendFactor factor) 5367ec681f3Smrg{ 5377ec681f3Smrg switch (factor) { 5387ec681f3Smrg case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ZERO: 5397ec681f3Smrg return PIPE_BLENDFACTOR_ZERO; 5407ec681f3Smrg case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE: 5417ec681f3Smrg return PIPE_BLENDFACTOR_ONE; 5427ec681f3Smrg case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_COLOR: 5437ec681f3Smrg return PIPE_BLENDFACTOR_SRC_COLOR; 5447ec681f3Smrg case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_COLOR: 5457ec681f3Smrg return PIPE_BLENDFACTOR_INV_SRC_COLOR; 5467ec681f3Smrg case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_ALPHA: 5477ec681f3Smrg return PIPE_BLENDFACTOR_SRC_ALPHA; 5487ec681f3Smrg case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA: 5497ec681f3Smrg return PIPE_BLENDFACTOR_INV_SRC_ALPHA; 5507ec681f3Smrg case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_DST_ALPHA: 5517ec681f3Smrg return PIPE_BLENDFACTOR_DST_ALPHA; 5527ec681f3Smrg case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_DST_ALPHA: 5537ec681f3Smrg return PIPE_BLENDFACTOR_INV_DST_ALPHA; 5547ec681f3Smrg case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_DST_COLOR: 5557ec681f3Smrg return PIPE_BLENDFACTOR_DST_COLOR; 5567ec681f3Smrg case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_DST_COLOR: 5577ec681f3Smrg return PIPE_BLENDFACTOR_INV_DST_COLOR; 5587ec681f3Smrg case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_ALPHA_SATURATE: 5597ec681f3Smrg return PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE; 5607ec681f3Smrg case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_CONSTANT_COLOR: 5617ec681f3Smrg return PIPE_BLENDFACTOR_CONST_COLOR; 5627ec681f3Smrg case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR: 5637ec681f3Smrg return PIPE_BLENDFACTOR_INV_CONST_COLOR; 5647ec681f3Smrg case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_CONSTANT_ALPHA: 5657ec681f3Smrg return PIPE_BLENDFACTOR_CONST_ALPHA; 5667ec681f3Smrg case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA: 5677ec681f3Smrg return PIPE_BLENDFACTOR_INV_CONST_ALPHA; 5687ec681f3Smrg default: 5697ec681f3Smrg assert(0); 5707ec681f3Smrg return PIPE_BLENDFACTOR_ONE; 5717ec681f3Smrg } 5727ec681f3Smrg} 5737ec681f3Smrg 5747ec681f3Smrgstatic unsigned 5757ec681f3SmrgBlendEquationToPipe(VdpOutputSurfaceRenderBlendEquation equation) 5767ec681f3Smrg{ 5777ec681f3Smrg switch (equation) { 5787ec681f3Smrg case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_SUBTRACT: 5797ec681f3Smrg return PIPE_BLEND_SUBTRACT; 5807ec681f3Smrg case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_REVERSE_SUBTRACT: 5817ec681f3Smrg return PIPE_BLEND_REVERSE_SUBTRACT; 5827ec681f3Smrg case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD: 5837ec681f3Smrg return PIPE_BLEND_ADD; 5847ec681f3Smrg case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_MIN: 5857ec681f3Smrg return PIPE_BLEND_MIN; 5867ec681f3Smrg case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_MAX: 5877ec681f3Smrg return PIPE_BLEND_MAX; 5887ec681f3Smrg default: 5897ec681f3Smrg assert(0); 5907ec681f3Smrg return PIPE_BLEND_ADD; 5917ec681f3Smrg } 5927ec681f3Smrg} 5937ec681f3Smrg 5947ec681f3Smrgstatic void * 5957ec681f3SmrgBlenderToPipe(struct pipe_context *context, 5967ec681f3Smrg VdpOutputSurfaceRenderBlendState const *blend_state) 5977ec681f3Smrg{ 5987ec681f3Smrg struct pipe_blend_state blend; 5997ec681f3Smrg 6007ec681f3Smrg memset(&blend, 0, sizeof blend); 6017ec681f3Smrg blend.independent_blend_enable = 0; 6027ec681f3Smrg 6037ec681f3Smrg if (blend_state) { 6047ec681f3Smrg blend.rt[0].blend_enable = 1; 6057ec681f3Smrg blend.rt[0].rgb_src_factor = BlendFactorToPipe(blend_state->blend_factor_source_color); 6067ec681f3Smrg blend.rt[0].rgb_dst_factor = BlendFactorToPipe(blend_state->blend_factor_destination_color); 6077ec681f3Smrg blend.rt[0].alpha_src_factor = BlendFactorToPipe(blend_state->blend_factor_source_alpha); 6087ec681f3Smrg blend.rt[0].alpha_dst_factor = BlendFactorToPipe(blend_state->blend_factor_destination_alpha); 6097ec681f3Smrg blend.rt[0].rgb_func = BlendEquationToPipe(blend_state->blend_equation_color); 6107ec681f3Smrg blend.rt[0].alpha_func = BlendEquationToPipe(blend_state->blend_equation_alpha); 6117ec681f3Smrg } else { 6127ec681f3Smrg blend.rt[0].blend_enable = 0; 6137ec681f3Smrg } 6147ec681f3Smrg 6157ec681f3Smrg blend.logicop_enable = 0; 6167ec681f3Smrg blend.logicop_func = PIPE_LOGICOP_CLEAR; 6177ec681f3Smrg blend.rt[0].colormask = PIPE_MASK_RGBA; 6187ec681f3Smrg blend.dither = 0; 6197ec681f3Smrg 6207ec681f3Smrg return context->create_blend_state(context, &blend); 6217ec681f3Smrg} 6227ec681f3Smrg 6237ec681f3Smrgstatic struct vertex4f * 6247ec681f3SmrgColorsToPipe(VdpColor const *colors, uint32_t flags, struct vertex4f result[4]) 6257ec681f3Smrg{ 6267ec681f3Smrg unsigned i; 6277ec681f3Smrg struct vertex4f *dst = result; 6287ec681f3Smrg 6297ec681f3Smrg if (!colors) 6307ec681f3Smrg return NULL; 6317ec681f3Smrg 6327ec681f3Smrg for (i = 0; i < 4; ++i) { 6337ec681f3Smrg dst->x = colors->red; 6347ec681f3Smrg dst->y = colors->green; 6357ec681f3Smrg dst->z = colors->blue; 6367ec681f3Smrg dst->w = colors->alpha; 6377ec681f3Smrg 6387ec681f3Smrg ++dst; 6397ec681f3Smrg if (flags & VDP_OUTPUT_SURFACE_RENDER_COLOR_PER_VERTEX) 6407ec681f3Smrg ++colors; 6417ec681f3Smrg } 6427ec681f3Smrg return result; 6437ec681f3Smrg} 6447ec681f3Smrg 6457ec681f3Smrg/** 6467ec681f3Smrg * Composite a sub-rectangle of a VdpOutputSurface into a sub-rectangle of 6477ec681f3Smrg * another VdpOutputSurface; Output Surface object VdpOutputSurface. 6487ec681f3Smrg */ 6497ec681f3SmrgVdpStatus 6507ec681f3SmrgvlVdpOutputSurfaceRenderOutputSurface(VdpOutputSurface destination_surface, 6517ec681f3Smrg VdpRect const *destination_rect, 6527ec681f3Smrg VdpOutputSurface source_surface, 6537ec681f3Smrg VdpRect const *source_rect, 6547ec681f3Smrg VdpColor const *colors, 6557ec681f3Smrg VdpOutputSurfaceRenderBlendState const *blend_state, 6567ec681f3Smrg uint32_t flags) 6577ec681f3Smrg{ 6587ec681f3Smrg vlVdpOutputSurface *dst_vlsurface; 6597ec681f3Smrg 6607ec681f3Smrg struct pipe_context *context; 6617ec681f3Smrg struct pipe_sampler_view *src_sv; 6627ec681f3Smrg struct vl_compositor *compositor; 6637ec681f3Smrg struct vl_compositor_state *cstate; 6647ec681f3Smrg 6657ec681f3Smrg struct u_rect src_rect, dst_rect; 6667ec681f3Smrg 6677ec681f3Smrg struct vertex4f vlcolors[4]; 6687ec681f3Smrg void *blend; 6697ec681f3Smrg 6707ec681f3Smrg dst_vlsurface = vlGetDataHTAB(destination_surface); 6717ec681f3Smrg if (!dst_vlsurface) 6727ec681f3Smrg return VDP_STATUS_INVALID_HANDLE; 6737ec681f3Smrg 6747ec681f3Smrg if (source_surface == VDP_INVALID_HANDLE) { 6757ec681f3Smrg src_sv = dst_vlsurface->device->dummy_sv; 6767ec681f3Smrg 6777ec681f3Smrg } else { 6787ec681f3Smrg vlVdpOutputSurface *src_vlsurface = vlGetDataHTAB(source_surface); 6797ec681f3Smrg if (!src_vlsurface) 6807ec681f3Smrg return VDP_STATUS_INVALID_HANDLE; 6817ec681f3Smrg 6827ec681f3Smrg if (dst_vlsurface->device != src_vlsurface->device) 6837ec681f3Smrg return VDP_STATUS_HANDLE_DEVICE_MISMATCH; 6847ec681f3Smrg 6857ec681f3Smrg src_sv = src_vlsurface->sampler_view; 6867ec681f3Smrg } 6877ec681f3Smrg 6887ec681f3Smrg mtx_lock(&dst_vlsurface->device->mutex); 6897ec681f3Smrg 6907ec681f3Smrg context = dst_vlsurface->device->context; 6917ec681f3Smrg compositor = &dst_vlsurface->device->compositor; 6927ec681f3Smrg cstate = &dst_vlsurface->cstate; 6937ec681f3Smrg 6947ec681f3Smrg blend = BlenderToPipe(context, blend_state); 6957ec681f3Smrg 6967ec681f3Smrg vl_compositor_clear_layers(cstate); 6977ec681f3Smrg vl_compositor_set_layer_blend(cstate, 0, blend, false); 6987ec681f3Smrg vl_compositor_set_rgba_layer(cstate, compositor, 0, src_sv, 6997ec681f3Smrg RectToPipe(source_rect, &src_rect), NULL, 7007ec681f3Smrg ColorsToPipe(colors, flags, vlcolors)); 7017ec681f3Smrg STATIC_ASSERT(VL_COMPOSITOR_ROTATE_0 == VDP_OUTPUT_SURFACE_RENDER_ROTATE_0); 7027ec681f3Smrg STATIC_ASSERT(VL_COMPOSITOR_ROTATE_90 == VDP_OUTPUT_SURFACE_RENDER_ROTATE_90); 7037ec681f3Smrg STATIC_ASSERT(VL_COMPOSITOR_ROTATE_180 == VDP_OUTPUT_SURFACE_RENDER_ROTATE_180); 7047ec681f3Smrg STATIC_ASSERT(VL_COMPOSITOR_ROTATE_270 == VDP_OUTPUT_SURFACE_RENDER_ROTATE_270); 7057ec681f3Smrg vl_compositor_set_layer_rotation(cstate, 0, flags & 3); 7067ec681f3Smrg vl_compositor_set_layer_dst_area(cstate, 0, RectToPipe(destination_rect, &dst_rect)); 7077ec681f3Smrg vl_compositor_render(cstate, compositor, dst_vlsurface->surface, &dst_vlsurface->dirty_area, false); 7087ec681f3Smrg 7097ec681f3Smrg context->delete_blend_state(context, blend); 7107ec681f3Smrg mtx_unlock(&dst_vlsurface->device->mutex); 7117ec681f3Smrg 7127ec681f3Smrg return VDP_STATUS_OK; 7137ec681f3Smrg} 7147ec681f3Smrg 7157ec681f3Smrg/** 7167ec681f3Smrg * Composite a sub-rectangle of a VdpBitmapSurface into a sub-rectangle of 7177ec681f3Smrg * a VdpOutputSurface; Output Surface object VdpOutputSurface. 7187ec681f3Smrg */ 7197ec681f3SmrgVdpStatus 7207ec681f3SmrgvlVdpOutputSurfaceRenderBitmapSurface(VdpOutputSurface destination_surface, 7217ec681f3Smrg VdpRect const *destination_rect, 7227ec681f3Smrg VdpBitmapSurface source_surface, 7237ec681f3Smrg VdpRect const *source_rect, 7247ec681f3Smrg VdpColor const *colors, 7257ec681f3Smrg VdpOutputSurfaceRenderBlendState const *blend_state, 7267ec681f3Smrg uint32_t flags) 7277ec681f3Smrg{ 7287ec681f3Smrg vlVdpOutputSurface *dst_vlsurface; 7297ec681f3Smrg 7307ec681f3Smrg struct pipe_context *context; 7317ec681f3Smrg struct pipe_sampler_view *src_sv; 7327ec681f3Smrg struct vl_compositor *compositor; 7337ec681f3Smrg struct vl_compositor_state *cstate; 7347ec681f3Smrg 7357ec681f3Smrg struct u_rect src_rect, dst_rect; 7367ec681f3Smrg 7377ec681f3Smrg struct vertex4f vlcolors[4]; 7387ec681f3Smrg void *blend; 7397ec681f3Smrg 7407ec681f3Smrg dst_vlsurface = vlGetDataHTAB(destination_surface); 7417ec681f3Smrg if (!dst_vlsurface) 7427ec681f3Smrg return VDP_STATUS_INVALID_HANDLE; 7437ec681f3Smrg 7447ec681f3Smrg if (source_surface == VDP_INVALID_HANDLE) { 7457ec681f3Smrg src_sv = dst_vlsurface->device->dummy_sv; 7467ec681f3Smrg 7477ec681f3Smrg } else { 7487ec681f3Smrg vlVdpBitmapSurface *src_vlsurface = vlGetDataHTAB(source_surface); 7497ec681f3Smrg if (!src_vlsurface) 7507ec681f3Smrg return VDP_STATUS_INVALID_HANDLE; 7517ec681f3Smrg 7527ec681f3Smrg if (dst_vlsurface->device != src_vlsurface->device) 7537ec681f3Smrg return VDP_STATUS_HANDLE_DEVICE_MISMATCH; 7547ec681f3Smrg 7557ec681f3Smrg src_sv = src_vlsurface->sampler_view; 7567ec681f3Smrg } 7577ec681f3Smrg 7587ec681f3Smrg context = dst_vlsurface->device->context; 7597ec681f3Smrg compositor = &dst_vlsurface->device->compositor; 7607ec681f3Smrg cstate = &dst_vlsurface->cstate; 7617ec681f3Smrg 7627ec681f3Smrg mtx_lock(&dst_vlsurface->device->mutex); 7637ec681f3Smrg 7647ec681f3Smrg blend = BlenderToPipe(context, blend_state); 7657ec681f3Smrg 7667ec681f3Smrg vl_compositor_clear_layers(cstate); 7677ec681f3Smrg vl_compositor_set_layer_blend(cstate, 0, blend, false); 7687ec681f3Smrg vl_compositor_set_rgba_layer(cstate, compositor, 0, src_sv, 7697ec681f3Smrg RectToPipe(source_rect, &src_rect), NULL, 7707ec681f3Smrg ColorsToPipe(colors, flags, vlcolors)); 7717ec681f3Smrg vl_compositor_set_layer_rotation(cstate, 0, flags & 3); 7727ec681f3Smrg vl_compositor_set_layer_dst_area(cstate, 0, RectToPipe(destination_rect, &dst_rect)); 7737ec681f3Smrg vl_compositor_render(cstate, compositor, dst_vlsurface->surface, &dst_vlsurface->dirty_area, false); 7747ec681f3Smrg 7757ec681f3Smrg context->delete_blend_state(context, blend); 7767ec681f3Smrg mtx_unlock(&dst_vlsurface->device->mutex); 7777ec681f3Smrg 7787ec681f3Smrg return VDP_STATUS_OK; 7797ec681f3Smrg} 7807ec681f3Smrg 7817ec681f3Smrgstruct pipe_resource *vlVdpOutputSurfaceGallium(VdpOutputSurface surface) 7827ec681f3Smrg{ 7837ec681f3Smrg vlVdpOutputSurface *vlsurface; 7847ec681f3Smrg 7857ec681f3Smrg vlsurface = vlGetDataHTAB(surface); 7867ec681f3Smrg if (!vlsurface || !vlsurface->surface) 7877ec681f3Smrg return NULL; 7887ec681f3Smrg 7897ec681f3Smrg mtx_lock(&vlsurface->device->mutex); 7907ec681f3Smrg vlsurface->device->context->flush(vlsurface->device->context, NULL, 0); 7917ec681f3Smrg mtx_unlock(&vlsurface->device->mutex); 7927ec681f3Smrg 7937ec681f3Smrg return vlsurface->surface->texture; 7947ec681f3Smrg} 7957ec681f3Smrg 7967ec681f3SmrgVdpStatus vlVdpOutputSurfaceDMABuf(VdpOutputSurface surface, 7977ec681f3Smrg struct VdpSurfaceDMABufDesc *result) 7987ec681f3Smrg{ 7997ec681f3Smrg vlVdpOutputSurface *vlsurface; 8007ec681f3Smrg struct pipe_screen *pscreen; 8017ec681f3Smrg struct winsys_handle whandle; 8027ec681f3Smrg 8037ec681f3Smrg memset(result, 0, sizeof(*result)); 8047ec681f3Smrg result->handle = -1; 8057ec681f3Smrg 8067ec681f3Smrg vlsurface = vlGetDataHTAB(surface); 8077ec681f3Smrg if (!vlsurface || !vlsurface->surface) 8087ec681f3Smrg return VDP_STATUS_INVALID_HANDLE; 8097ec681f3Smrg 8107ec681f3Smrg mtx_lock(&vlsurface->device->mutex); 8117ec681f3Smrg vlsurface->device->context->flush(vlsurface->device->context, NULL, 0); 8127ec681f3Smrg 8137ec681f3Smrg memset(&whandle, 0, sizeof(struct winsys_handle)); 8147ec681f3Smrg whandle.type = WINSYS_HANDLE_TYPE_FD; 8157ec681f3Smrg 8167ec681f3Smrg pscreen = vlsurface->surface->texture->screen; 8177ec681f3Smrg if (!pscreen->resource_get_handle(pscreen, vlsurface->device->context, 8187ec681f3Smrg vlsurface->surface->texture, &whandle, 8197ec681f3Smrg PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE)) { 8207ec681f3Smrg mtx_unlock(&vlsurface->device->mutex); 8217ec681f3Smrg return VDP_STATUS_NO_IMPLEMENTATION; 8227ec681f3Smrg } 8237ec681f3Smrg 8247ec681f3Smrg mtx_unlock(&vlsurface->device->mutex); 8257ec681f3Smrg 8267ec681f3Smrg result->handle = whandle.handle; 8277ec681f3Smrg result->width = vlsurface->surface->width; 8287ec681f3Smrg result->height = vlsurface->surface->height; 8297ec681f3Smrg result->offset = whandle.offset; 8307ec681f3Smrg result->stride = whandle.stride; 8317ec681f3Smrg result->format = PipeToFormatRGBA(vlsurface->surface->format); 8327ec681f3Smrg 8337ec681f3Smrg return VDP_STATUS_OK; 8347ec681f3Smrg} 835