Path: blob/21.2-virgl/src/gallium/frontends/vdpau/output.c
4565 views
/**************************************************************************1*2* Copyright 2010 Thomas Balling Sørensen.3* Copyright 2011 Christian König.4* All Rights Reserved.5*6* Permission is hereby granted, free of charge, to any person obtaining a7* copy of this software and associated documentation files (the8* "Software"), to deal in the Software without restriction, including9* without limitation the rights to use, copy, modify, merge, publish,10* distribute, sub license, and/or sell copies of the Software, and to11* permit persons to whom the Software is furnished to do so, subject to12* the following conditions:13*14* The above copyright notice and this permission notice (including the15* next paragraph) shall be included in all copies or substantial portions16* of the Software.17*18* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS19* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF20* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.21* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR22* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,23* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE24* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.25*26**************************************************************************/2728#include <vdpau/vdpau.h>2930#include "util/u_debug.h"31#include "util/u_memory.h"32#include "util/u_sampler.h"33#include "util/format/u_format.h"34#include "util/u_surface.h"3536#include "vl/vl_csc.h"3738#include "frontend/drm_driver.h"3940#include "vdpau_private.h"4142/**43* Create a VdpOutputSurface.44*/45VdpStatus46vlVdpOutputSurfaceCreate(VdpDevice device,47VdpRGBAFormat rgba_format,48uint32_t width, uint32_t height,49VdpOutputSurface *surface)50{51struct pipe_context *pipe;52struct pipe_resource res_tmpl, *res;53struct pipe_sampler_view sv_templ;54struct pipe_surface surf_templ;5556vlVdpOutputSurface *vlsurface = NULL;5758if (!(width && height))59return VDP_STATUS_INVALID_SIZE;6061vlVdpDevice *dev = vlGetDataHTAB(device);62if (!dev)63return VDP_STATUS_INVALID_HANDLE;6465pipe = dev->context;66if (!pipe)67return VDP_STATUS_INVALID_HANDLE;6869vlsurface = CALLOC(1, sizeof(vlVdpOutputSurface));70if (!vlsurface)71return VDP_STATUS_RESOURCES;7273DeviceReference(&vlsurface->device, dev);7475memset(&res_tmpl, 0, sizeof(res_tmpl));7677/*78* The output won't look correctly when this buffer is send to X,79* if the VDPAU RGB component order doesn't match the X11 one so80* we only allow the X11 format81*/82vlsurface->send_to_X = dev->vscreen->color_depth == 24 &&83rgba_format == VDP_RGBA_FORMAT_B8G8R8A8;8485res_tmpl.target = PIPE_TEXTURE_2D;86res_tmpl.format = VdpFormatRGBAToPipe(rgba_format);87res_tmpl.width0 = width;88res_tmpl.height0 = height;89res_tmpl.depth0 = 1;90res_tmpl.array_size = 1;91res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET |92PIPE_BIND_SHARED | PIPE_BIND_SCANOUT;93res_tmpl.usage = PIPE_USAGE_DEFAULT;9495mtx_lock(&dev->mutex);9697if (!CheckSurfaceParams(pipe->screen, &res_tmpl))98goto err_unlock;99100res = pipe->screen->resource_create(pipe->screen, &res_tmpl);101if (!res)102goto err_unlock;103104vlVdpDefaultSamplerViewTemplate(&sv_templ, res);105vlsurface->sampler_view = pipe->create_sampler_view(pipe, res, &sv_templ);106if (!vlsurface->sampler_view)107goto err_resource;108109memset(&surf_templ, 0, sizeof(surf_templ));110surf_templ.format = res->format;111vlsurface->surface = pipe->create_surface(pipe, res, &surf_templ);112if (!vlsurface->surface)113goto err_resource;114115*surface = vlAddDataHTAB(vlsurface);116if (*surface == 0)117goto err_resource;118119pipe_resource_reference(&res, NULL);120121if (!vl_compositor_init_state(&vlsurface->cstate, pipe))122goto err_resource;123124vl_compositor_reset_dirty_area(&vlsurface->dirty_area);125mtx_unlock(&dev->mutex);126127return VDP_STATUS_OK;128129err_resource:130pipe_sampler_view_reference(&vlsurface->sampler_view, NULL);131pipe_surface_reference(&vlsurface->surface, NULL);132pipe_resource_reference(&res, NULL);133err_unlock:134mtx_unlock(&dev->mutex);135DeviceReference(&vlsurface->device, NULL);136FREE(vlsurface);137return VDP_STATUS_ERROR;138}139140/**141* Destroy a VdpOutputSurface.142*/143VdpStatus144vlVdpOutputSurfaceDestroy(VdpOutputSurface surface)145{146vlVdpOutputSurface *vlsurface;147struct pipe_context *pipe;148149vlsurface = vlGetDataHTAB(surface);150if (!vlsurface)151return VDP_STATUS_INVALID_HANDLE;152153pipe = vlsurface->device->context;154155mtx_lock(&vlsurface->device->mutex);156157pipe_surface_reference(&vlsurface->surface, NULL);158pipe_sampler_view_reference(&vlsurface->sampler_view, NULL);159pipe->screen->fence_reference(pipe->screen, &vlsurface->fence, NULL);160vl_compositor_cleanup_state(&vlsurface->cstate);161mtx_unlock(&vlsurface->device->mutex);162163vlRemoveDataHTAB(surface);164DeviceReference(&vlsurface->device, NULL);165FREE(vlsurface);166167return VDP_STATUS_OK;168}169170/**171* Retrieve the parameters used to create a VdpOutputSurface.172*/173VdpStatus174vlVdpOutputSurfaceGetParameters(VdpOutputSurface surface,175VdpRGBAFormat *rgba_format,176uint32_t *width, uint32_t *height)177{178vlVdpOutputSurface *vlsurface;179180vlsurface = vlGetDataHTAB(surface);181if (!vlsurface)182return VDP_STATUS_INVALID_HANDLE;183184*rgba_format = PipeToFormatRGBA(vlsurface->sampler_view->texture->format);185*width = vlsurface->sampler_view->texture->width0;186*height = vlsurface->sampler_view->texture->height0;187188return VDP_STATUS_OK;189}190191/**192* Copy image data from a VdpOutputSurface to application memory in the193* surface's native format.194*/195VdpStatus196vlVdpOutputSurfaceGetBitsNative(VdpOutputSurface surface,197VdpRect const *source_rect,198void *const *destination_data,199uint32_t const *destination_pitches)200{201vlVdpOutputSurface *vlsurface;202struct pipe_context *pipe;203struct pipe_resource *res;204struct pipe_box box;205struct pipe_transfer *transfer;206uint8_t *map;207208vlsurface = vlGetDataHTAB(surface);209if (!vlsurface)210return VDP_STATUS_INVALID_HANDLE;211212pipe = vlsurface->device->context;213if (!pipe)214return VDP_STATUS_INVALID_HANDLE;215216if (!destination_data || !destination_pitches)217return VDP_STATUS_INVALID_POINTER;218219mtx_lock(&vlsurface->device->mutex);220221res = vlsurface->sampler_view->texture;222box = RectToPipeBox(source_rect, res);223map = pipe->texture_map(pipe, res, 0, PIPE_MAP_READ, &box, &transfer);224if (!map) {225mtx_unlock(&vlsurface->device->mutex);226return VDP_STATUS_RESOURCES;227}228229util_copy_rect(*destination_data, res->format, *destination_pitches, 0, 0,230box.width, box.height, map, transfer->stride, 0, 0);231232pipe_texture_unmap(pipe, transfer);233mtx_unlock(&vlsurface->device->mutex);234235return VDP_STATUS_OK;236}237238/**239* Copy image data from application memory in the surface's native format to240* a VdpOutputSurface.241*/242VdpStatus243vlVdpOutputSurfacePutBitsNative(VdpOutputSurface surface,244void const *const *source_data,245uint32_t const *source_pitches,246VdpRect const *destination_rect)247{248vlVdpOutputSurface *vlsurface;249struct pipe_box dst_box;250struct pipe_context *pipe;251252vlsurface = vlGetDataHTAB(surface);253if (!vlsurface)254return VDP_STATUS_INVALID_HANDLE;255256pipe = vlsurface->device->context;257if (!pipe)258return VDP_STATUS_INVALID_HANDLE;259260if (!source_data || !source_pitches)261return VDP_STATUS_INVALID_POINTER;262263mtx_lock(&vlsurface->device->mutex);264265dst_box = RectToPipeBox(destination_rect, vlsurface->sampler_view->texture);266267/* Check for a no-op. (application bug?) */268if (!dst_box.width || !dst_box.height) {269mtx_unlock(&vlsurface->device->mutex);270return VDP_STATUS_OK;271}272273pipe->texture_subdata(pipe, vlsurface->sampler_view->texture, 0,274PIPE_MAP_WRITE, &dst_box, *source_data,275*source_pitches, 0);276mtx_unlock(&vlsurface->device->mutex);277278return VDP_STATUS_OK;279}280281/**282* Copy image data from application memory in a specific indexed format to283* a VdpOutputSurface.284*/285VdpStatus286vlVdpOutputSurfacePutBitsIndexed(VdpOutputSurface surface,287VdpIndexedFormat source_indexed_format,288void const *const *source_data,289uint32_t const *source_pitch,290VdpRect const *destination_rect,291VdpColorTableFormat color_table_format,292void const *color_table)293{294vlVdpOutputSurface *vlsurface;295struct pipe_context *context;296struct vl_compositor *compositor;297struct vl_compositor_state *cstate;298299enum pipe_format index_format;300enum pipe_format colortbl_format;301302struct pipe_resource *res, res_tmpl;303struct pipe_sampler_view sv_tmpl;304struct pipe_sampler_view *sv_idx = NULL, *sv_tbl = NULL;305306struct pipe_box box;307struct u_rect dst_rect;308309vlsurface = vlGetDataHTAB(surface);310if (!vlsurface)311return VDP_STATUS_INVALID_HANDLE;312313context = vlsurface->device->context;314compositor = &vlsurface->device->compositor;315cstate = &vlsurface->cstate;316317index_format = FormatIndexedToPipe(source_indexed_format);318if (index_format == PIPE_FORMAT_NONE)319return VDP_STATUS_INVALID_INDEXED_FORMAT;320321if (!source_data || !source_pitch)322return VDP_STATUS_INVALID_POINTER;323324colortbl_format = FormatColorTableToPipe(color_table_format);325if (colortbl_format == PIPE_FORMAT_NONE)326return VDP_STATUS_INVALID_COLOR_TABLE_FORMAT;327328if (!color_table)329return VDP_STATUS_INVALID_POINTER;330331memset(&res_tmpl, 0, sizeof(res_tmpl));332res_tmpl.target = PIPE_TEXTURE_2D;333res_tmpl.format = index_format;334335if (destination_rect) {336if (destination_rect->x1 > destination_rect->x0 &&337destination_rect->y1 > destination_rect->y0) {338res_tmpl.width0 = destination_rect->x1 - destination_rect->x0;339res_tmpl.height0 = destination_rect->y1 - destination_rect->y0;340}341} else {342res_tmpl.width0 = vlsurface->surface->texture->width0;343res_tmpl.height0 = vlsurface->surface->texture->height0;344}345res_tmpl.depth0 = 1;346res_tmpl.array_size = 1;347res_tmpl.usage = PIPE_USAGE_STAGING;348res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW;349350mtx_lock(&vlsurface->device->mutex);351352if (!CheckSurfaceParams(context->screen, &res_tmpl))353goto error_resource;354355res = context->screen->resource_create(context->screen, &res_tmpl);356if (!res)357goto error_resource;358359box.x = box.y = box.z = 0;360box.width = res->width0;361box.height = res->height0;362box.depth = res->depth0;363364context->texture_subdata(context, res, 0, PIPE_MAP_WRITE, &box,365source_data[0], source_pitch[0],366source_pitch[0] * res->height0);367368memset(&sv_tmpl, 0, sizeof(sv_tmpl));369u_sampler_view_default_template(&sv_tmpl, res, res->format);370371sv_idx = context->create_sampler_view(context, res, &sv_tmpl);372pipe_resource_reference(&res, NULL);373374if (!sv_idx)375goto error_resource;376377memset(&res_tmpl, 0, sizeof(res_tmpl));378res_tmpl.target = PIPE_TEXTURE_1D;379res_tmpl.format = colortbl_format;380res_tmpl.width0 = 1 << util_format_get_component_bits(381index_format, UTIL_FORMAT_COLORSPACE_RGB, 0);382res_tmpl.height0 = 1;383res_tmpl.depth0 = 1;384res_tmpl.array_size = 1;385res_tmpl.usage = PIPE_USAGE_STAGING;386res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW;387388res = context->screen->resource_create(context->screen, &res_tmpl);389if (!res)390goto error_resource;391392box.x = box.y = box.z = 0;393box.width = res->width0;394box.height = res->height0;395box.depth = res->depth0;396397context->texture_subdata(context, res, 0, PIPE_MAP_WRITE, &box, color_table,398util_format_get_stride(colortbl_format, res->width0), 0);399400memset(&sv_tmpl, 0, sizeof(sv_tmpl));401u_sampler_view_default_template(&sv_tmpl, res, res->format);402403sv_tbl = context->create_sampler_view(context, res, &sv_tmpl);404pipe_resource_reference(&res, NULL);405406if (!sv_tbl)407goto error_resource;408409vl_compositor_clear_layers(cstate);410vl_compositor_set_palette_layer(cstate, compositor, 0, sv_idx, sv_tbl, NULL, NULL, false);411vl_compositor_set_layer_dst_area(cstate, 0, RectToPipe(destination_rect, &dst_rect));412vl_compositor_render(cstate, compositor, vlsurface->surface, &vlsurface->dirty_area, false);413414pipe_sampler_view_reference(&sv_idx, NULL);415pipe_sampler_view_reference(&sv_tbl, NULL);416mtx_unlock(&vlsurface->device->mutex);417418return VDP_STATUS_OK;419420error_resource:421pipe_sampler_view_reference(&sv_idx, NULL);422pipe_sampler_view_reference(&sv_tbl, NULL);423mtx_unlock(&vlsurface->device->mutex);424return VDP_STATUS_RESOURCES;425}426427/**428* Copy image data from application memory in a specific YCbCr format to429* a VdpOutputSurface.430*/431VdpStatus432vlVdpOutputSurfacePutBitsYCbCr(VdpOutputSurface surface,433VdpYCbCrFormat source_ycbcr_format,434void const *const *source_data,435uint32_t const *source_pitches,436VdpRect const *destination_rect,437VdpCSCMatrix const *csc_matrix)438{439vlVdpOutputSurface *vlsurface;440struct vl_compositor *compositor;441struct vl_compositor_state *cstate;442443struct pipe_context *pipe;444enum pipe_format format;445struct pipe_video_buffer vtmpl, *vbuffer;446struct u_rect dst_rect;447struct pipe_sampler_view **sampler_views;448449unsigned i;450451vlsurface = vlGetDataHTAB(surface);452if (!vlsurface)453return VDP_STATUS_INVALID_HANDLE;454455456pipe = vlsurface->device->context;457compositor = &vlsurface->device->compositor;458cstate = &vlsurface->cstate;459460format = FormatYCBCRToPipe(source_ycbcr_format);461if (format == PIPE_FORMAT_NONE)462return VDP_STATUS_INVALID_Y_CB_CR_FORMAT;463464if (!source_data || !source_pitches)465return VDP_STATUS_INVALID_POINTER;466467mtx_lock(&vlsurface->device->mutex);468memset(&vtmpl, 0, sizeof(vtmpl));469vtmpl.buffer_format = format;470471if (destination_rect) {472if (destination_rect->x1 > destination_rect->x0 &&473destination_rect->y1 > destination_rect->y0) {474vtmpl.width = destination_rect->x1 - destination_rect->x0;475vtmpl.height = destination_rect->y1 - destination_rect->y0;476}477} else {478vtmpl.width = vlsurface->surface->texture->width0;479vtmpl.height = vlsurface->surface->texture->height0;480}481482vbuffer = pipe->create_video_buffer(pipe, &vtmpl);483if (!vbuffer) {484mtx_unlock(&vlsurface->device->mutex);485return VDP_STATUS_RESOURCES;486}487488sampler_views = vbuffer->get_sampler_view_planes(vbuffer);489if (!sampler_views) {490vbuffer->destroy(vbuffer);491mtx_unlock(&vlsurface->device->mutex);492return VDP_STATUS_RESOURCES;493}494495for (i = 0; i < 3; ++i) {496struct pipe_sampler_view *sv = sampler_views[i];497if (!sv) continue;498499struct pipe_box dst_box = {5000, 0, 0,501sv->texture->width0, sv->texture->height0, 1502};503504pipe->texture_subdata(pipe, sv->texture, 0, PIPE_MAP_WRITE, &dst_box,505source_data[i], source_pitches[i], 0);506}507508if (!csc_matrix) {509vl_csc_matrix csc;510vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_BT_601, NULL, 1, &csc);511if (!vl_compositor_set_csc_matrix(cstate, (const vl_csc_matrix*)&csc, 1.0f, 0.0f))512goto err_csc_matrix;513} else {514if (!vl_compositor_set_csc_matrix(cstate, csc_matrix, 1.0f, 0.0f))515goto err_csc_matrix;516}517518vl_compositor_clear_layers(cstate);519vl_compositor_set_buffer_layer(cstate, compositor, 0, vbuffer, NULL, NULL, VL_COMPOSITOR_WEAVE);520vl_compositor_set_layer_dst_area(cstate, 0, RectToPipe(destination_rect, &dst_rect));521vl_compositor_render(cstate, compositor, vlsurface->surface, &vlsurface->dirty_area, false);522523vbuffer->destroy(vbuffer);524mtx_unlock(&vlsurface->device->mutex);525526return VDP_STATUS_OK;527err_csc_matrix:528vbuffer->destroy(vbuffer);529mtx_unlock(&vlsurface->device->mutex);530return VDP_STATUS_ERROR;531}532533static unsigned534BlendFactorToPipe(VdpOutputSurfaceRenderBlendFactor factor)535{536switch (factor) {537case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ZERO:538return PIPE_BLENDFACTOR_ZERO;539case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE:540return PIPE_BLENDFACTOR_ONE;541case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_COLOR:542return PIPE_BLENDFACTOR_SRC_COLOR;543case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_COLOR:544return PIPE_BLENDFACTOR_INV_SRC_COLOR;545case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_ALPHA:546return PIPE_BLENDFACTOR_SRC_ALPHA;547case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA:548return PIPE_BLENDFACTOR_INV_SRC_ALPHA;549case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_DST_ALPHA:550return PIPE_BLENDFACTOR_DST_ALPHA;551case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_DST_ALPHA:552return PIPE_BLENDFACTOR_INV_DST_ALPHA;553case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_DST_COLOR:554return PIPE_BLENDFACTOR_DST_COLOR;555case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_DST_COLOR:556return PIPE_BLENDFACTOR_INV_DST_COLOR;557case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_ALPHA_SATURATE:558return PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE;559case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_CONSTANT_COLOR:560return PIPE_BLENDFACTOR_CONST_COLOR;561case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR:562return PIPE_BLENDFACTOR_INV_CONST_COLOR;563case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_CONSTANT_ALPHA:564return PIPE_BLENDFACTOR_CONST_ALPHA;565case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA:566return PIPE_BLENDFACTOR_INV_CONST_ALPHA;567default:568assert(0);569return PIPE_BLENDFACTOR_ONE;570}571}572573static unsigned574BlendEquationToPipe(VdpOutputSurfaceRenderBlendEquation equation)575{576switch (equation) {577case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_SUBTRACT:578return PIPE_BLEND_SUBTRACT;579case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_REVERSE_SUBTRACT:580return PIPE_BLEND_REVERSE_SUBTRACT;581case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD:582return PIPE_BLEND_ADD;583case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_MIN:584return PIPE_BLEND_MIN;585case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_MAX:586return PIPE_BLEND_MAX;587default:588assert(0);589return PIPE_BLEND_ADD;590}591}592593static void *594BlenderToPipe(struct pipe_context *context,595VdpOutputSurfaceRenderBlendState const *blend_state)596{597struct pipe_blend_state blend;598599memset(&blend, 0, sizeof blend);600blend.independent_blend_enable = 0;601602if (blend_state) {603blend.rt[0].blend_enable = 1;604blend.rt[0].rgb_src_factor = BlendFactorToPipe(blend_state->blend_factor_source_color);605blend.rt[0].rgb_dst_factor = BlendFactorToPipe(blend_state->blend_factor_destination_color);606blend.rt[0].alpha_src_factor = BlendFactorToPipe(blend_state->blend_factor_source_alpha);607blend.rt[0].alpha_dst_factor = BlendFactorToPipe(blend_state->blend_factor_destination_alpha);608blend.rt[0].rgb_func = BlendEquationToPipe(blend_state->blend_equation_color);609blend.rt[0].alpha_func = BlendEquationToPipe(blend_state->blend_equation_alpha);610} else {611blend.rt[0].blend_enable = 0;612}613614blend.logicop_enable = 0;615blend.logicop_func = PIPE_LOGICOP_CLEAR;616blend.rt[0].colormask = PIPE_MASK_RGBA;617blend.dither = 0;618619return context->create_blend_state(context, &blend);620}621622static struct vertex4f *623ColorsToPipe(VdpColor const *colors, uint32_t flags, struct vertex4f result[4])624{625unsigned i;626struct vertex4f *dst = result;627628if (!colors)629return NULL;630631for (i = 0; i < 4; ++i) {632dst->x = colors->red;633dst->y = colors->green;634dst->z = colors->blue;635dst->w = colors->alpha;636637++dst;638if (flags & VDP_OUTPUT_SURFACE_RENDER_COLOR_PER_VERTEX)639++colors;640}641return result;642}643644/**645* Composite a sub-rectangle of a VdpOutputSurface into a sub-rectangle of646* another VdpOutputSurface; Output Surface object VdpOutputSurface.647*/648VdpStatus649vlVdpOutputSurfaceRenderOutputSurface(VdpOutputSurface destination_surface,650VdpRect const *destination_rect,651VdpOutputSurface source_surface,652VdpRect const *source_rect,653VdpColor const *colors,654VdpOutputSurfaceRenderBlendState const *blend_state,655uint32_t flags)656{657vlVdpOutputSurface *dst_vlsurface;658659struct pipe_context *context;660struct pipe_sampler_view *src_sv;661struct vl_compositor *compositor;662struct vl_compositor_state *cstate;663664struct u_rect src_rect, dst_rect;665666struct vertex4f vlcolors[4];667void *blend;668669dst_vlsurface = vlGetDataHTAB(destination_surface);670if (!dst_vlsurface)671return VDP_STATUS_INVALID_HANDLE;672673if (source_surface == VDP_INVALID_HANDLE) {674src_sv = dst_vlsurface->device->dummy_sv;675676} else {677vlVdpOutputSurface *src_vlsurface = vlGetDataHTAB(source_surface);678if (!src_vlsurface)679return VDP_STATUS_INVALID_HANDLE;680681if (dst_vlsurface->device != src_vlsurface->device)682return VDP_STATUS_HANDLE_DEVICE_MISMATCH;683684src_sv = src_vlsurface->sampler_view;685}686687mtx_lock(&dst_vlsurface->device->mutex);688689context = dst_vlsurface->device->context;690compositor = &dst_vlsurface->device->compositor;691cstate = &dst_vlsurface->cstate;692693blend = BlenderToPipe(context, blend_state);694695vl_compositor_clear_layers(cstate);696vl_compositor_set_layer_blend(cstate, 0, blend, false);697vl_compositor_set_rgba_layer(cstate, compositor, 0, src_sv,698RectToPipe(source_rect, &src_rect), NULL,699ColorsToPipe(colors, flags, vlcolors));700STATIC_ASSERT(VL_COMPOSITOR_ROTATE_0 == VDP_OUTPUT_SURFACE_RENDER_ROTATE_0);701STATIC_ASSERT(VL_COMPOSITOR_ROTATE_90 == VDP_OUTPUT_SURFACE_RENDER_ROTATE_90);702STATIC_ASSERT(VL_COMPOSITOR_ROTATE_180 == VDP_OUTPUT_SURFACE_RENDER_ROTATE_180);703STATIC_ASSERT(VL_COMPOSITOR_ROTATE_270 == VDP_OUTPUT_SURFACE_RENDER_ROTATE_270);704vl_compositor_set_layer_rotation(cstate, 0, flags & 3);705vl_compositor_set_layer_dst_area(cstate, 0, RectToPipe(destination_rect, &dst_rect));706vl_compositor_render(cstate, compositor, dst_vlsurface->surface, &dst_vlsurface->dirty_area, false);707708context->delete_blend_state(context, blend);709mtx_unlock(&dst_vlsurface->device->mutex);710711return VDP_STATUS_OK;712}713714/**715* Composite a sub-rectangle of a VdpBitmapSurface into a sub-rectangle of716* a VdpOutputSurface; Output Surface object VdpOutputSurface.717*/718VdpStatus719vlVdpOutputSurfaceRenderBitmapSurface(VdpOutputSurface destination_surface,720VdpRect const *destination_rect,721VdpBitmapSurface source_surface,722VdpRect const *source_rect,723VdpColor const *colors,724VdpOutputSurfaceRenderBlendState const *blend_state,725uint32_t flags)726{727vlVdpOutputSurface *dst_vlsurface;728729struct pipe_context *context;730struct pipe_sampler_view *src_sv;731struct vl_compositor *compositor;732struct vl_compositor_state *cstate;733734struct u_rect src_rect, dst_rect;735736struct vertex4f vlcolors[4];737void *blend;738739dst_vlsurface = vlGetDataHTAB(destination_surface);740if (!dst_vlsurface)741return VDP_STATUS_INVALID_HANDLE;742743if (source_surface == VDP_INVALID_HANDLE) {744src_sv = dst_vlsurface->device->dummy_sv;745746} else {747vlVdpBitmapSurface *src_vlsurface = vlGetDataHTAB(source_surface);748if (!src_vlsurface)749return VDP_STATUS_INVALID_HANDLE;750751if (dst_vlsurface->device != src_vlsurface->device)752return VDP_STATUS_HANDLE_DEVICE_MISMATCH;753754src_sv = src_vlsurface->sampler_view;755}756757context = dst_vlsurface->device->context;758compositor = &dst_vlsurface->device->compositor;759cstate = &dst_vlsurface->cstate;760761mtx_lock(&dst_vlsurface->device->mutex);762763blend = BlenderToPipe(context, blend_state);764765vl_compositor_clear_layers(cstate);766vl_compositor_set_layer_blend(cstate, 0, blend, false);767vl_compositor_set_rgba_layer(cstate, compositor, 0, src_sv,768RectToPipe(source_rect, &src_rect), NULL,769ColorsToPipe(colors, flags, vlcolors));770vl_compositor_set_layer_rotation(cstate, 0, flags & 3);771vl_compositor_set_layer_dst_area(cstate, 0, RectToPipe(destination_rect, &dst_rect));772vl_compositor_render(cstate, compositor, dst_vlsurface->surface, &dst_vlsurface->dirty_area, false);773774context->delete_blend_state(context, blend);775mtx_unlock(&dst_vlsurface->device->mutex);776777return VDP_STATUS_OK;778}779780struct pipe_resource *vlVdpOutputSurfaceGallium(VdpOutputSurface surface)781{782vlVdpOutputSurface *vlsurface;783784vlsurface = vlGetDataHTAB(surface);785if (!vlsurface || !vlsurface->surface)786return NULL;787788mtx_lock(&vlsurface->device->mutex);789vlsurface->device->context->flush(vlsurface->device->context, NULL, 0);790mtx_unlock(&vlsurface->device->mutex);791792return vlsurface->surface->texture;793}794795VdpStatus vlVdpOutputSurfaceDMABuf(VdpOutputSurface surface,796struct VdpSurfaceDMABufDesc *result)797{798vlVdpOutputSurface *vlsurface;799struct pipe_screen *pscreen;800struct winsys_handle whandle;801802memset(result, 0, sizeof(*result));803result->handle = -1;804805vlsurface = vlGetDataHTAB(surface);806if (!vlsurface || !vlsurface->surface)807return VDP_STATUS_INVALID_HANDLE;808809mtx_lock(&vlsurface->device->mutex);810vlsurface->device->context->flush(vlsurface->device->context, NULL, 0);811812memset(&whandle, 0, sizeof(struct winsys_handle));813whandle.type = WINSYS_HANDLE_TYPE_FD;814815pscreen = vlsurface->surface->texture->screen;816if (!pscreen->resource_get_handle(pscreen, vlsurface->device->context,817vlsurface->surface->texture, &whandle,818PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE)) {819mtx_unlock(&vlsurface->device->mutex);820return VDP_STATUS_NO_IMPLEMENTATION;821}822823mtx_unlock(&vlsurface->device->mutex);824825result->handle = whandle.handle;826result->width = vlsurface->surface->width;827result->height = vlsurface->surface->height;828result->offset = whandle.offset;829result->stride = whandle.stride;830result->format = PipeToFormatRGBA(vlsurface->surface->format);831832return VDP_STATUS_OK;833}834835836