17ec681f3Smrg/************************************************************************** 27ec681f3Smrg * 37ec681f3Smrg * Copyright 2010 Thomas Balling Sørensen. 47ec681f3Smrg * All Rights Reserved. 57ec681f3Smrg * 67ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 77ec681f3Smrg * copy of this software and associated documentation files (the 87ec681f3Smrg * "Software"), to deal in the Software without restriction, including 97ec681f3Smrg * without limitation the rights to use, copy, modify, merge, publish, 107ec681f3Smrg * distribute, sub license, and/or sell copies of the Software, and to 117ec681f3Smrg * permit persons to whom the Software is furnished to do so, subject to 127ec681f3Smrg * the following conditions: 137ec681f3Smrg * 147ec681f3Smrg * The above copyright notice and this permission notice (including the 157ec681f3Smrg * next paragraph) shall be included in all copies or substantial portions 167ec681f3Smrg * of the Software. 177ec681f3Smrg * 187ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 197ec681f3Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 207ec681f3Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 217ec681f3Smrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 227ec681f3Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 237ec681f3Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 247ec681f3Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 257ec681f3Smrg * 267ec681f3Smrg **************************************************************************/ 277ec681f3Smrg 287ec681f3Smrg#include <vdpau/vdpau.h> 297ec681f3Smrg 307ec681f3Smrg#include "util/u_memory.h" 317ec681f3Smrg#include "util/u_sampler.h" 327ec681f3Smrg 337ec681f3Smrg#include "vdpau_private.h" 347ec681f3Smrg 357ec681f3Smrg/** 367ec681f3Smrg * Create a VdpBitmapSurface. 377ec681f3Smrg */ 387ec681f3SmrgVdpStatus 397ec681f3SmrgvlVdpBitmapSurfaceCreate(VdpDevice device, 407ec681f3Smrg VdpRGBAFormat rgba_format, 417ec681f3Smrg uint32_t width, uint32_t height, 427ec681f3Smrg VdpBool frequently_accessed, 437ec681f3Smrg VdpBitmapSurface *surface) 447ec681f3Smrg{ 457ec681f3Smrg struct pipe_context *pipe; 467ec681f3Smrg struct pipe_resource res_tmpl, *res; 477ec681f3Smrg struct pipe_sampler_view sv_templ; 487ec681f3Smrg VdpStatus ret; 497ec681f3Smrg 507ec681f3Smrg vlVdpBitmapSurface *vlsurface = NULL; 517ec681f3Smrg 527ec681f3Smrg if (!(width && height)) 537ec681f3Smrg return VDP_STATUS_INVALID_SIZE; 547ec681f3Smrg 557ec681f3Smrg vlVdpDevice *dev = vlGetDataHTAB(device); 567ec681f3Smrg if (!dev) 577ec681f3Smrg return VDP_STATUS_INVALID_HANDLE; 587ec681f3Smrg 597ec681f3Smrg pipe = dev->context; 607ec681f3Smrg if (!pipe) 617ec681f3Smrg return VDP_STATUS_INVALID_HANDLE; 627ec681f3Smrg 637ec681f3Smrg if (!surface) 647ec681f3Smrg return VDP_STATUS_INVALID_POINTER; 657ec681f3Smrg 667ec681f3Smrg vlsurface = CALLOC(1, sizeof(vlVdpBitmapSurface)); 677ec681f3Smrg if (!vlsurface) 687ec681f3Smrg return VDP_STATUS_RESOURCES; 697ec681f3Smrg 707ec681f3Smrg DeviceReference(&vlsurface->device, dev); 717ec681f3Smrg 727ec681f3Smrg memset(&res_tmpl, 0, sizeof(res_tmpl)); 737ec681f3Smrg res_tmpl.target = PIPE_TEXTURE_2D; 747ec681f3Smrg res_tmpl.format = VdpFormatRGBAToPipe(rgba_format); 757ec681f3Smrg res_tmpl.width0 = width; 767ec681f3Smrg res_tmpl.height0 = height; 777ec681f3Smrg res_tmpl.depth0 = 1; 787ec681f3Smrg res_tmpl.array_size = 1; 797ec681f3Smrg res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET; 807ec681f3Smrg res_tmpl.usage = frequently_accessed ? PIPE_USAGE_DYNAMIC : PIPE_USAGE_DEFAULT; 817ec681f3Smrg 827ec681f3Smrg mtx_lock(&dev->mutex); 837ec681f3Smrg 847ec681f3Smrg if (!CheckSurfaceParams(pipe->screen, &res_tmpl)) { 857ec681f3Smrg ret = VDP_STATUS_RESOURCES; 867ec681f3Smrg goto err_unlock; 877ec681f3Smrg } 887ec681f3Smrg 897ec681f3Smrg res = pipe->screen->resource_create(pipe->screen, &res_tmpl); 907ec681f3Smrg if (!res) { 917ec681f3Smrg ret = VDP_STATUS_RESOURCES; 927ec681f3Smrg goto err_unlock; 937ec681f3Smrg } 947ec681f3Smrg 957ec681f3Smrg vlVdpDefaultSamplerViewTemplate(&sv_templ, res); 967ec681f3Smrg vlsurface->sampler_view = pipe->create_sampler_view(pipe, res, &sv_templ); 977ec681f3Smrg 987ec681f3Smrg pipe_resource_reference(&res, NULL); 997ec681f3Smrg 1007ec681f3Smrg if (!vlsurface->sampler_view) { 1017ec681f3Smrg ret = VDP_STATUS_RESOURCES; 1027ec681f3Smrg goto err_unlock; 1037ec681f3Smrg } 1047ec681f3Smrg 1057ec681f3Smrg mtx_unlock(&dev->mutex); 1067ec681f3Smrg 1077ec681f3Smrg *surface = vlAddDataHTAB(vlsurface); 1087ec681f3Smrg if (*surface == 0) { 1097ec681f3Smrg mtx_lock(&dev->mutex); 1107ec681f3Smrg ret = VDP_STATUS_ERROR; 1117ec681f3Smrg goto err_sampler; 1127ec681f3Smrg } 1137ec681f3Smrg 1147ec681f3Smrg return VDP_STATUS_OK; 1157ec681f3Smrg 1167ec681f3Smrgerr_sampler: 1177ec681f3Smrg pipe_sampler_view_reference(&vlsurface->sampler_view, NULL); 1187ec681f3Smrgerr_unlock: 1197ec681f3Smrg mtx_unlock(&dev->mutex); 1207ec681f3Smrg DeviceReference(&vlsurface->device, NULL); 1217ec681f3Smrg FREE(vlsurface); 1227ec681f3Smrg return ret; 1237ec681f3Smrg} 1247ec681f3Smrg 1257ec681f3Smrg/** 1267ec681f3Smrg * Destroy a VdpBitmapSurface. 1277ec681f3Smrg */ 1287ec681f3SmrgVdpStatus 1297ec681f3SmrgvlVdpBitmapSurfaceDestroy(VdpBitmapSurface surface) 1307ec681f3Smrg{ 1317ec681f3Smrg vlVdpBitmapSurface *vlsurface; 1327ec681f3Smrg 1337ec681f3Smrg vlsurface = vlGetDataHTAB(surface); 1347ec681f3Smrg if (!vlsurface) 1357ec681f3Smrg return VDP_STATUS_INVALID_HANDLE; 1367ec681f3Smrg 1377ec681f3Smrg mtx_lock(&vlsurface->device->mutex); 1387ec681f3Smrg pipe_sampler_view_reference(&vlsurface->sampler_view, NULL); 1397ec681f3Smrg mtx_unlock(&vlsurface->device->mutex); 1407ec681f3Smrg 1417ec681f3Smrg vlRemoveDataHTAB(surface); 1427ec681f3Smrg DeviceReference(&vlsurface->device, NULL); 1437ec681f3Smrg FREE(vlsurface); 1447ec681f3Smrg 1457ec681f3Smrg return VDP_STATUS_OK; 1467ec681f3Smrg} 1477ec681f3Smrg 1487ec681f3Smrg/** 1497ec681f3Smrg * Retrieve the parameters used to create a VdpBitmapSurface. 1507ec681f3Smrg */ 1517ec681f3SmrgVdpStatus 1527ec681f3SmrgvlVdpBitmapSurfaceGetParameters(VdpBitmapSurface surface, 1537ec681f3Smrg VdpRGBAFormat *rgba_format, 1547ec681f3Smrg uint32_t *width, uint32_t *height, 1557ec681f3Smrg VdpBool *frequently_accessed) 1567ec681f3Smrg{ 1577ec681f3Smrg vlVdpBitmapSurface *vlsurface; 1587ec681f3Smrg struct pipe_resource *res; 1597ec681f3Smrg 1607ec681f3Smrg vlsurface = vlGetDataHTAB(surface); 1617ec681f3Smrg if (!vlsurface) 1627ec681f3Smrg return VDP_STATUS_INVALID_HANDLE; 1637ec681f3Smrg 1647ec681f3Smrg if (!(rgba_format && width && height && frequently_accessed)) 1657ec681f3Smrg return VDP_STATUS_INVALID_POINTER; 1667ec681f3Smrg 1677ec681f3Smrg res = vlsurface->sampler_view->texture; 1687ec681f3Smrg *rgba_format = PipeToFormatRGBA(res->format); 1697ec681f3Smrg *width = res->width0; 1707ec681f3Smrg *height = res->height0; 1717ec681f3Smrg *frequently_accessed = res->usage == PIPE_USAGE_DYNAMIC; 1727ec681f3Smrg 1737ec681f3Smrg return VDP_STATUS_OK; 1747ec681f3Smrg} 1757ec681f3Smrg 1767ec681f3Smrg/** 1777ec681f3Smrg * Copy image data from application memory in the surface's native format to 1787ec681f3Smrg * a VdpBitmapSurface. 1797ec681f3Smrg */ 1807ec681f3SmrgVdpStatus 1817ec681f3SmrgvlVdpBitmapSurfacePutBitsNative(VdpBitmapSurface surface, 1827ec681f3Smrg void const *const *source_data, 1837ec681f3Smrg uint32_t const *source_pitches, 1847ec681f3Smrg VdpRect const *destination_rect) 1857ec681f3Smrg{ 1867ec681f3Smrg vlVdpBitmapSurface *vlsurface; 1877ec681f3Smrg struct pipe_box dst_box; 1887ec681f3Smrg struct pipe_context *pipe; 1897ec681f3Smrg 1907ec681f3Smrg vlsurface = vlGetDataHTAB(surface); 1917ec681f3Smrg if (!vlsurface) 1927ec681f3Smrg return VDP_STATUS_INVALID_HANDLE; 1937ec681f3Smrg 1947ec681f3Smrg if (!(source_data && source_pitches)) 1957ec681f3Smrg return VDP_STATUS_INVALID_POINTER; 1967ec681f3Smrg 1977ec681f3Smrg pipe = vlsurface->device->context; 1987ec681f3Smrg 1997ec681f3Smrg mtx_lock(&vlsurface->device->mutex); 2007ec681f3Smrg 2017ec681f3Smrg dst_box = RectToPipeBox(destination_rect, vlsurface->sampler_view->texture); 2027ec681f3Smrg pipe->texture_subdata(pipe, vlsurface->sampler_view->texture, 0, 2037ec681f3Smrg PIPE_MAP_WRITE, &dst_box, *source_data, 2047ec681f3Smrg *source_pitches, 0); 2057ec681f3Smrg 2067ec681f3Smrg mtx_unlock(&vlsurface->device->mutex); 2077ec681f3Smrg 2087ec681f3Smrg return VDP_STATUS_OK; 2097ec681f3Smrg} 210