Path: blob/21.2-virgl/src/gallium/frontends/vdpau/device.c
4565 views
/**************************************************************************1*2* Copyright 2010 Younes Manton og Thomas Balling Sørensen.3* All Rights Reserved.4*5* Permission is hereby granted, free of charge, to any person obtaining a6* copy of this software and associated documentation files (the7* "Software"), to deal in the Software without restriction, including8* without limitation the rights to use, copy, modify, merge, publish,9* distribute, sub license, and/or sell copies of the Software, and to10* permit persons to whom the Software is furnished to do so, subject to11* the following conditions:12*13* The above copyright notice and this permission notice (including the14* next paragraph) shall be included in all copies or substantial portions15* of the Software.16*17* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS18* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.20* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR21* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,22* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE23* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.24*25**************************************************************************/2627#include "pipe/p_compiler.h"2829#include "util/u_memory.h"30#include "util/u_debug.h"31#include "util/format/u_format.h"32#include "util/u_sampler.h"3334#include "vdpau_private.h"3536/**37* Create a VdpDevice object for use with X11.38*/39PUBLIC VdpStatus40vdp_imp_device_create_x11(Display *display, int screen, VdpDevice *device,41VdpGetProcAddress **get_proc_address)42{43struct pipe_screen *pscreen;44struct pipe_resource *res, res_tmpl;45struct pipe_sampler_view sv_tmpl;46vlVdpDevice *dev = NULL;47VdpStatus ret;4849if (!(display && device && get_proc_address))50return VDP_STATUS_INVALID_POINTER;5152if (!vlCreateHTAB()) {53ret = VDP_STATUS_RESOURCES;54goto no_htab;55}5657dev = CALLOC(1, sizeof(vlVdpDevice));58if (!dev) {59ret = VDP_STATUS_RESOURCES;60goto no_dev;61}6263pipe_reference_init(&dev->reference, 1);6465dev->vscreen = vl_dri3_screen_create(display, screen);66if (!dev->vscreen)67dev->vscreen = vl_dri2_screen_create(display, screen);68if (!dev->vscreen) {69ret = VDP_STATUS_RESOURCES;70goto no_vscreen;71}7273pscreen = dev->vscreen->pscreen;74dev->context = pipe_create_multimedia_context(pscreen);75if (!dev->context) {76ret = VDP_STATUS_RESOURCES;77goto no_context;78}7980if (!pscreen->get_param(pscreen, PIPE_CAP_NPOT_TEXTURES)) {81ret = VDP_STATUS_NO_IMPLEMENTATION;82goto no_context;83}8485memset(&res_tmpl, 0, sizeof(res_tmpl));8687res_tmpl.target = PIPE_TEXTURE_2D;88res_tmpl.format = PIPE_FORMAT_R8G8B8A8_UNORM;89res_tmpl.width0 = 1;90res_tmpl.height0 = 1;91res_tmpl.depth0 = 1;92res_tmpl.array_size = 1;93res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW;94res_tmpl.usage = PIPE_USAGE_DEFAULT;9596if (!CheckSurfaceParams(pscreen, &res_tmpl)) {97ret = VDP_STATUS_NO_IMPLEMENTATION;98goto no_resource;99}100101res = pscreen->resource_create(pscreen, &res_tmpl);102if (!res) {103ret = VDP_STATUS_RESOURCES;104goto no_resource;105}106107memset(&sv_tmpl, 0, sizeof(sv_tmpl));108u_sampler_view_default_template(&sv_tmpl, res, res->format);109110sv_tmpl.swizzle_r = PIPE_SWIZZLE_1;111sv_tmpl.swizzle_g = PIPE_SWIZZLE_1;112sv_tmpl.swizzle_b = PIPE_SWIZZLE_1;113sv_tmpl.swizzle_a = PIPE_SWIZZLE_1;114115dev->dummy_sv = dev->context->create_sampler_view(dev->context, res, &sv_tmpl);116pipe_resource_reference(&res, NULL);117if (!dev->dummy_sv) {118ret = VDP_STATUS_RESOURCES;119goto no_resource;120}121122*device = vlAddDataHTAB(dev);123if (*device == 0) {124ret = VDP_STATUS_ERROR;125goto no_handle;126}127128if (!vl_compositor_init(&dev->compositor, dev->context)) {129ret = VDP_STATUS_ERROR;130goto no_compositor;131}132133(void) mtx_init(&dev->mutex, mtx_plain);134135*get_proc_address = &vlVdpGetProcAddress;136137return VDP_STATUS_OK;138139no_compositor:140vlRemoveDataHTAB(*device);141no_handle:142pipe_sampler_view_reference(&dev->dummy_sv, NULL);143no_resource:144dev->context->destroy(dev->context);145no_context:146dev->vscreen->destroy(dev->vscreen);147no_vscreen:148FREE(dev);149no_dev:150vlDestroyHTAB();151no_htab:152return ret;153}154155/**156* Create a VdpPresentationQueueTarget for use with X11.157*/158VdpStatus159vlVdpPresentationQueueTargetCreateX11(VdpDevice device, Drawable drawable,160VdpPresentationQueueTarget *target)161{162vlVdpPresentationQueueTarget *pqt;163VdpStatus ret;164165if (!drawable)166return VDP_STATUS_INVALID_HANDLE;167168vlVdpDevice *dev = vlGetDataHTAB(device);169if (!dev)170return VDP_STATUS_INVALID_HANDLE;171172pqt = CALLOC(1, sizeof(vlVdpPresentationQueueTarget));173if (!pqt)174return VDP_STATUS_RESOURCES;175176DeviceReference(&pqt->device, dev);177pqt->drawable = drawable;178179*target = vlAddDataHTAB(pqt);180if (*target == 0) {181ret = VDP_STATUS_ERROR;182goto no_handle;183}184185return VDP_STATUS_OK;186187no_handle:188FREE(pqt);189return ret;190}191192/**193* Destroy a VdpPresentationQueueTarget.194*/195VdpStatus196vlVdpPresentationQueueTargetDestroy(VdpPresentationQueueTarget presentation_queue_target)197{198vlVdpPresentationQueueTarget *pqt;199200pqt = vlGetDataHTAB(presentation_queue_target);201if (!pqt)202return VDP_STATUS_INVALID_HANDLE;203204vlRemoveDataHTAB(presentation_queue_target);205DeviceReference(&pqt->device, NULL);206FREE(pqt);207208return VDP_STATUS_OK;209}210211/**212* Destroy a VdpDevice.213*/214VdpStatus215vlVdpDeviceDestroy(VdpDevice device)216{217vlVdpDevice *dev = vlGetDataHTAB(device);218if (!dev)219return VDP_STATUS_INVALID_HANDLE;220221vlRemoveDataHTAB(device);222DeviceReference(&dev, NULL);223224return VDP_STATUS_OK;225}226227/**228* Free a VdpDevice.229*/230void231vlVdpDeviceFree(vlVdpDevice *dev)232{233mtx_destroy(&dev->mutex);234vl_compositor_cleanup(&dev->compositor);235pipe_sampler_view_reference(&dev->dummy_sv, NULL);236dev->context->destroy(dev->context);237dev->vscreen->destroy(dev->vscreen);238FREE(dev);239vlDestroyHTAB();240}241242/**243* Retrieve a VDPAU function pointer.244*/245VdpStatus246vlVdpGetProcAddress(VdpDevice device, VdpFuncId function_id, void **function_pointer)247{248vlVdpDevice *dev = vlGetDataHTAB(device);249if (!dev)250return VDP_STATUS_INVALID_HANDLE;251252if (!function_pointer)253return VDP_STATUS_INVALID_POINTER;254255if (!vlGetFuncFTAB(function_id, function_pointer))256return VDP_STATUS_INVALID_FUNC_ID;257258VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Got proc address %p for id %d\n", *function_pointer, function_id);259260return VDP_STATUS_OK;261}262263#define _ERROR_TYPE(TYPE,STRING) case TYPE: return STRING;264265/**266* Retrieve a string describing an error code.267*/268char const *269vlVdpGetErrorString (VdpStatus status)270{271switch (status) {272_ERROR_TYPE(VDP_STATUS_OK,"The operation completed successfully; no error.");273_ERROR_TYPE(VDP_STATUS_NO_IMPLEMENTATION,"No backend implementation could be loaded.");274_ERROR_TYPE(VDP_STATUS_DISPLAY_PREEMPTED,"The display was preempted, or a fatal error occurred. The application must re-initialize VDPAU.");275_ERROR_TYPE(VDP_STATUS_INVALID_HANDLE,"An invalid handle value was provided. Either the handle does not exist at all, or refers to an object of an incorrect type.");276_ERROR_TYPE(VDP_STATUS_INVALID_POINTER,"An invalid pointer was provided. Typically, this means that a NULL pointer was provided for an 'output' parameter.");277_ERROR_TYPE(VDP_STATUS_INVALID_CHROMA_TYPE,"An invalid/unsupported VdpChromaType value was supplied.");278_ERROR_TYPE(VDP_STATUS_INVALID_Y_CB_CR_FORMAT,"An invalid/unsupported VdpYCbCrFormat value was supplied.");279_ERROR_TYPE(VDP_STATUS_INVALID_RGBA_FORMAT,"An invalid/unsupported VdpRGBAFormat value was supplied.");280_ERROR_TYPE(VDP_STATUS_INVALID_INDEXED_FORMAT,"An invalid/unsupported VdpIndexedFormat value was supplied.");281_ERROR_TYPE(VDP_STATUS_INVALID_COLOR_STANDARD,"An invalid/unsupported VdpColorStandard value was supplied.");282_ERROR_TYPE(VDP_STATUS_INVALID_COLOR_TABLE_FORMAT,"An invalid/unsupported VdpColorTableFormat value was supplied.");283_ERROR_TYPE(VDP_STATUS_INVALID_BLEND_FACTOR,"An invalid/unsupported VdpOutputSurfaceRenderBlendFactor value was supplied.");284_ERROR_TYPE(VDP_STATUS_INVALID_BLEND_EQUATION,"An invalid/unsupported VdpOutputSurfaceRenderBlendEquation value was supplied.");285_ERROR_TYPE(VDP_STATUS_INVALID_FLAG,"An invalid/unsupported flag value/combination was supplied.");286_ERROR_TYPE(VDP_STATUS_INVALID_DECODER_PROFILE,"An invalid/unsupported VdpDecoderProfile value was supplied.");287_ERROR_TYPE(VDP_STATUS_INVALID_VIDEO_MIXER_FEATURE,"An invalid/unsupported VdpVideoMixerFeature value was supplied.");288_ERROR_TYPE(VDP_STATUS_INVALID_VIDEO_MIXER_PARAMETER,"An invalid/unsupported VdpVideoMixerParameter value was supplied.");289_ERROR_TYPE(VDP_STATUS_INVALID_VIDEO_MIXER_ATTRIBUTE,"An invalid/unsupported VdpVideoMixerAttribute value was supplied.");290_ERROR_TYPE(VDP_STATUS_INVALID_VIDEO_MIXER_PICTURE_STRUCTURE,"An invalid/unsupported VdpVideoMixerPictureStructure value was supplied.");291_ERROR_TYPE(VDP_STATUS_INVALID_FUNC_ID,"An invalid/unsupported VdpFuncId value was supplied.");292_ERROR_TYPE(VDP_STATUS_INVALID_SIZE,"The size of a supplied object does not match the object it is being used with.\293For example, a VdpVideoMixer is configured to process VdpVideoSurface objects of a specific size.\294If presented with a VdpVideoSurface of a different size, this error will be raised.");295_ERROR_TYPE(VDP_STATUS_INVALID_VALUE,"An invalid/unsupported value was supplied.\296This is a catch-all error code for values of type other than those with a specific error code.");297_ERROR_TYPE(VDP_STATUS_INVALID_STRUCT_VERSION,"An invalid/unsupported structure version was specified in a versioned structure. \298This implies that the implementation is older than the header file the application was built against.");299_ERROR_TYPE(VDP_STATUS_RESOURCES,"The system does not have enough resources to complete the requested operation at this time.");300_ERROR_TYPE(VDP_STATUS_HANDLE_DEVICE_MISMATCH,"The set of handles supplied are not all related to the same VdpDevice.When performing operations \301that operate on multiple surfaces, such as VdpOutputSurfaceRenderOutputSurface or VdpVideoMixerRender, \302all supplied surfaces must have been created within the context of the same VdpDevice object. \303This error is raised if they were not.");304_ERROR_TYPE(VDP_STATUS_ERROR,"A catch-all error, used when no other error code applies.");305default: return "Unknown Error";306}307}308309void310vlVdpDefaultSamplerViewTemplate(struct pipe_sampler_view *templ, struct pipe_resource *res)311{312const struct util_format_description *desc;313314memset(templ, 0, sizeof(*templ));315u_sampler_view_default_template(templ, res, res->format);316317desc = util_format_description(res->format);318if (desc->swizzle[0] == PIPE_SWIZZLE_0)319templ->swizzle_r = PIPE_SWIZZLE_1;320if (desc->swizzle[1] == PIPE_SWIZZLE_0)321templ->swizzle_g = PIPE_SWIZZLE_1;322if (desc->swizzle[2] == PIPE_SWIZZLE_0)323templ->swizzle_b = PIPE_SWIZZLE_1;324if (desc->swizzle[3] == PIPE_SWIZZLE_0)325templ->swizzle_a = PIPE_SWIZZLE_1;326}327328329