1bf215546Sopenharmony_ci/************************************************************************** 2bf215546Sopenharmony_ci * 3bf215546Sopenharmony_ci * Copyright 2010 Thomas Balling Sørensen. 4bf215546Sopenharmony_ci * All Rights Reserved. 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the 8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to 11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 12bf215546Sopenharmony_ci * the following conditions: 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the 15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 16bf215546Sopenharmony_ci * of the Software. 17bf215546Sopenharmony_ci * 18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21bf215546Sopenharmony_ci * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25bf215546Sopenharmony_ci * 26bf215546Sopenharmony_ci **************************************************************************/ 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci#include <vdpau/vdpau.h> 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci#include "util/u_memory.h" 31bf215546Sopenharmony_ci#include "util/u_sampler.h" 32bf215546Sopenharmony_ci 33bf215546Sopenharmony_ci#include "vdpau_private.h" 34bf215546Sopenharmony_ci 35bf215546Sopenharmony_ci/** 36bf215546Sopenharmony_ci * Create a VdpBitmapSurface. 37bf215546Sopenharmony_ci */ 38bf215546Sopenharmony_ciVdpStatus 39bf215546Sopenharmony_civlVdpBitmapSurfaceCreate(VdpDevice device, 40bf215546Sopenharmony_ci VdpRGBAFormat rgba_format, 41bf215546Sopenharmony_ci uint32_t width, uint32_t height, 42bf215546Sopenharmony_ci VdpBool frequently_accessed, 43bf215546Sopenharmony_ci VdpBitmapSurface *surface) 44bf215546Sopenharmony_ci{ 45bf215546Sopenharmony_ci struct pipe_context *pipe; 46bf215546Sopenharmony_ci struct pipe_resource res_tmpl, *res; 47bf215546Sopenharmony_ci struct pipe_sampler_view sv_templ; 48bf215546Sopenharmony_ci VdpStatus ret; 49bf215546Sopenharmony_ci 50bf215546Sopenharmony_ci vlVdpBitmapSurface *vlsurface = NULL; 51bf215546Sopenharmony_ci 52bf215546Sopenharmony_ci if (!(width && height)) 53bf215546Sopenharmony_ci return VDP_STATUS_INVALID_SIZE; 54bf215546Sopenharmony_ci 55bf215546Sopenharmony_ci vlVdpDevice *dev = vlGetDataHTAB(device); 56bf215546Sopenharmony_ci if (!dev) 57bf215546Sopenharmony_ci return VDP_STATUS_INVALID_HANDLE; 58bf215546Sopenharmony_ci 59bf215546Sopenharmony_ci pipe = dev->context; 60bf215546Sopenharmony_ci if (!pipe) 61bf215546Sopenharmony_ci return VDP_STATUS_INVALID_HANDLE; 62bf215546Sopenharmony_ci 63bf215546Sopenharmony_ci if (!surface) 64bf215546Sopenharmony_ci return VDP_STATUS_INVALID_POINTER; 65bf215546Sopenharmony_ci 66bf215546Sopenharmony_ci vlsurface = CALLOC(1, sizeof(vlVdpBitmapSurface)); 67bf215546Sopenharmony_ci if (!vlsurface) 68bf215546Sopenharmony_ci return VDP_STATUS_RESOURCES; 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_ci DeviceReference(&vlsurface->device, dev); 71bf215546Sopenharmony_ci 72bf215546Sopenharmony_ci memset(&res_tmpl, 0, sizeof(res_tmpl)); 73bf215546Sopenharmony_ci res_tmpl.target = PIPE_TEXTURE_2D; 74bf215546Sopenharmony_ci res_tmpl.format = VdpFormatRGBAToPipe(rgba_format); 75bf215546Sopenharmony_ci res_tmpl.width0 = width; 76bf215546Sopenharmony_ci res_tmpl.height0 = height; 77bf215546Sopenharmony_ci res_tmpl.depth0 = 1; 78bf215546Sopenharmony_ci res_tmpl.array_size = 1; 79bf215546Sopenharmony_ci res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET; 80bf215546Sopenharmony_ci res_tmpl.usage = frequently_accessed ? PIPE_USAGE_DYNAMIC : PIPE_USAGE_DEFAULT; 81bf215546Sopenharmony_ci 82bf215546Sopenharmony_ci mtx_lock(&dev->mutex); 83bf215546Sopenharmony_ci 84bf215546Sopenharmony_ci if (!CheckSurfaceParams(pipe->screen, &res_tmpl)) { 85bf215546Sopenharmony_ci ret = VDP_STATUS_RESOURCES; 86bf215546Sopenharmony_ci goto err_unlock; 87bf215546Sopenharmony_ci } 88bf215546Sopenharmony_ci 89bf215546Sopenharmony_ci res = pipe->screen->resource_create(pipe->screen, &res_tmpl); 90bf215546Sopenharmony_ci if (!res) { 91bf215546Sopenharmony_ci ret = VDP_STATUS_RESOURCES; 92bf215546Sopenharmony_ci goto err_unlock; 93bf215546Sopenharmony_ci } 94bf215546Sopenharmony_ci 95bf215546Sopenharmony_ci vlVdpDefaultSamplerViewTemplate(&sv_templ, res); 96bf215546Sopenharmony_ci vlsurface->sampler_view = pipe->create_sampler_view(pipe, res, &sv_templ); 97bf215546Sopenharmony_ci 98bf215546Sopenharmony_ci pipe_resource_reference(&res, NULL); 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_ci if (!vlsurface->sampler_view) { 101bf215546Sopenharmony_ci ret = VDP_STATUS_RESOURCES; 102bf215546Sopenharmony_ci goto err_unlock; 103bf215546Sopenharmony_ci } 104bf215546Sopenharmony_ci 105bf215546Sopenharmony_ci mtx_unlock(&dev->mutex); 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_ci *surface = vlAddDataHTAB(vlsurface); 108bf215546Sopenharmony_ci if (*surface == 0) { 109bf215546Sopenharmony_ci mtx_lock(&dev->mutex); 110bf215546Sopenharmony_ci ret = VDP_STATUS_ERROR; 111bf215546Sopenharmony_ci goto err_sampler; 112bf215546Sopenharmony_ci } 113bf215546Sopenharmony_ci 114bf215546Sopenharmony_ci return VDP_STATUS_OK; 115bf215546Sopenharmony_ci 116bf215546Sopenharmony_cierr_sampler: 117bf215546Sopenharmony_ci pipe_sampler_view_reference(&vlsurface->sampler_view, NULL); 118bf215546Sopenharmony_cierr_unlock: 119bf215546Sopenharmony_ci mtx_unlock(&dev->mutex); 120bf215546Sopenharmony_ci DeviceReference(&vlsurface->device, NULL); 121bf215546Sopenharmony_ci FREE(vlsurface); 122bf215546Sopenharmony_ci return ret; 123bf215546Sopenharmony_ci} 124bf215546Sopenharmony_ci 125bf215546Sopenharmony_ci/** 126bf215546Sopenharmony_ci * Destroy a VdpBitmapSurface. 127bf215546Sopenharmony_ci */ 128bf215546Sopenharmony_ciVdpStatus 129bf215546Sopenharmony_civlVdpBitmapSurfaceDestroy(VdpBitmapSurface surface) 130bf215546Sopenharmony_ci{ 131bf215546Sopenharmony_ci vlVdpBitmapSurface *vlsurface; 132bf215546Sopenharmony_ci 133bf215546Sopenharmony_ci vlsurface = vlGetDataHTAB(surface); 134bf215546Sopenharmony_ci if (!vlsurface) 135bf215546Sopenharmony_ci return VDP_STATUS_INVALID_HANDLE; 136bf215546Sopenharmony_ci 137bf215546Sopenharmony_ci mtx_lock(&vlsurface->device->mutex); 138bf215546Sopenharmony_ci pipe_sampler_view_reference(&vlsurface->sampler_view, NULL); 139bf215546Sopenharmony_ci mtx_unlock(&vlsurface->device->mutex); 140bf215546Sopenharmony_ci 141bf215546Sopenharmony_ci vlRemoveDataHTAB(surface); 142bf215546Sopenharmony_ci DeviceReference(&vlsurface->device, NULL); 143bf215546Sopenharmony_ci FREE(vlsurface); 144bf215546Sopenharmony_ci 145bf215546Sopenharmony_ci return VDP_STATUS_OK; 146bf215546Sopenharmony_ci} 147bf215546Sopenharmony_ci 148bf215546Sopenharmony_ci/** 149bf215546Sopenharmony_ci * Retrieve the parameters used to create a VdpBitmapSurface. 150bf215546Sopenharmony_ci */ 151bf215546Sopenharmony_ciVdpStatus 152bf215546Sopenharmony_civlVdpBitmapSurfaceGetParameters(VdpBitmapSurface surface, 153bf215546Sopenharmony_ci VdpRGBAFormat *rgba_format, 154bf215546Sopenharmony_ci uint32_t *width, uint32_t *height, 155bf215546Sopenharmony_ci VdpBool *frequently_accessed) 156bf215546Sopenharmony_ci{ 157bf215546Sopenharmony_ci vlVdpBitmapSurface *vlsurface; 158bf215546Sopenharmony_ci struct pipe_resource *res; 159bf215546Sopenharmony_ci 160bf215546Sopenharmony_ci vlsurface = vlGetDataHTAB(surface); 161bf215546Sopenharmony_ci if (!vlsurface) 162bf215546Sopenharmony_ci return VDP_STATUS_INVALID_HANDLE; 163bf215546Sopenharmony_ci 164bf215546Sopenharmony_ci if (!(rgba_format && width && height && frequently_accessed)) 165bf215546Sopenharmony_ci return VDP_STATUS_INVALID_POINTER; 166bf215546Sopenharmony_ci 167bf215546Sopenharmony_ci res = vlsurface->sampler_view->texture; 168bf215546Sopenharmony_ci *rgba_format = PipeToFormatRGBA(res->format); 169bf215546Sopenharmony_ci *width = res->width0; 170bf215546Sopenharmony_ci *height = res->height0; 171bf215546Sopenharmony_ci *frequently_accessed = res->usage == PIPE_USAGE_DYNAMIC; 172bf215546Sopenharmony_ci 173bf215546Sopenharmony_ci return VDP_STATUS_OK; 174bf215546Sopenharmony_ci} 175bf215546Sopenharmony_ci 176bf215546Sopenharmony_ci/** 177bf215546Sopenharmony_ci * Copy image data from application memory in the surface's native format to 178bf215546Sopenharmony_ci * a VdpBitmapSurface. 179bf215546Sopenharmony_ci */ 180bf215546Sopenharmony_ciVdpStatus 181bf215546Sopenharmony_civlVdpBitmapSurfacePutBitsNative(VdpBitmapSurface surface, 182bf215546Sopenharmony_ci void const *const *source_data, 183bf215546Sopenharmony_ci uint32_t const *source_pitches, 184bf215546Sopenharmony_ci VdpRect const *destination_rect) 185bf215546Sopenharmony_ci{ 186bf215546Sopenharmony_ci vlVdpBitmapSurface *vlsurface; 187bf215546Sopenharmony_ci struct pipe_box dst_box; 188bf215546Sopenharmony_ci struct pipe_context *pipe; 189bf215546Sopenharmony_ci 190bf215546Sopenharmony_ci vlsurface = vlGetDataHTAB(surface); 191bf215546Sopenharmony_ci if (!vlsurface) 192bf215546Sopenharmony_ci return VDP_STATUS_INVALID_HANDLE; 193bf215546Sopenharmony_ci 194bf215546Sopenharmony_ci if (!(source_data && source_pitches)) 195bf215546Sopenharmony_ci return VDP_STATUS_INVALID_POINTER; 196bf215546Sopenharmony_ci 197bf215546Sopenharmony_ci pipe = vlsurface->device->context; 198bf215546Sopenharmony_ci 199bf215546Sopenharmony_ci mtx_lock(&vlsurface->device->mutex); 200bf215546Sopenharmony_ci 201bf215546Sopenharmony_ci dst_box = RectToPipeBox(destination_rect, vlsurface->sampler_view->texture); 202bf215546Sopenharmony_ci pipe->texture_subdata(pipe, vlsurface->sampler_view->texture, 0, 203bf215546Sopenharmony_ci PIPE_MAP_WRITE, &dst_box, *source_data, 204bf215546Sopenharmony_ci *source_pitches, 0); 205bf215546Sopenharmony_ci 206bf215546Sopenharmony_ci mtx_unlock(&vlsurface->device->mutex); 207bf215546Sopenharmony_ci 208bf215546Sopenharmony_ci return VDP_STATUS_OK; 209bf215546Sopenharmony_ci} 210