1bf215546Sopenharmony_ci/********************************************************** 2bf215546Sopenharmony_ci * Copyright 2009-2011 VMware, Inc. All rights reserved. 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person 5bf215546Sopenharmony_ci * obtaining a copy of this software and associated documentation 6bf215546Sopenharmony_ci * files (the "Software"), to deal in the Software without 7bf215546Sopenharmony_ci * restriction, including without limitation the rights to use, copy, 8bf215546Sopenharmony_ci * modify, merge, publish, distribute, sublicense, and/or sell copies 9bf215546Sopenharmony_ci * of the Software, and to permit persons to whom the Software is 10bf215546Sopenharmony_ci * furnished to do so, subject to the following conditions: 11bf215546Sopenharmony_ci * 12bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be 13bf215546Sopenharmony_ci * included in all copies or substantial portions of the Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16bf215546Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18bf215546Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19bf215546Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20bf215546Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21bf215546Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22bf215546Sopenharmony_ci * SOFTWARE. 23bf215546Sopenharmony_ci * 24bf215546Sopenharmony_ci ********************************************************* 25bf215546Sopenharmony_ci * Authors: 26bf215546Sopenharmony_ci * Thomas Hellstrom <thellstrom-at-vmware-dot-com> 27bf215546Sopenharmony_ci */ 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ci#include <unistd.h> 30bf215546Sopenharmony_ci#include "xa_tracker.h" 31bf215546Sopenharmony_ci#include "xa_priv.h" 32bf215546Sopenharmony_ci#include "pipe/p_state.h" 33bf215546Sopenharmony_ci#include "pipe/p_format.h" 34bf215546Sopenharmony_ci#include "pipe-loader/pipe_loader.h" 35bf215546Sopenharmony_ci#include "frontend/drm_driver.h" 36bf215546Sopenharmony_ci#include "util/u_inlines.h" 37bf215546Sopenharmony_ci 38bf215546Sopenharmony_ci/* 39bf215546Sopenharmony_ci * format_map [xa_surface_type][first..last in list]. 40bf215546Sopenharmony_ci * Needs to be updated when enum xa_formats is updated. 41bf215546Sopenharmony_ci */ 42bf215546Sopenharmony_ci 43bf215546Sopenharmony_cistatic const enum xa_formats preferred_a[] = { xa_format_a8 }; 44bf215546Sopenharmony_ci 45bf215546Sopenharmony_cistatic const enum xa_formats preferred_argb[] = 46bf215546Sopenharmony_ci { xa_format_a8r8g8b8, xa_format_x8r8g8b8, xa_format_r5g6b5, 47bf215546Sopenharmony_ci xa_format_x1r5g5b5 48bf215546Sopenharmony_ci}; 49bf215546Sopenharmony_cistatic const enum xa_formats preferred_z[] = 50bf215546Sopenharmony_ci { xa_format_z32, xa_format_z24, xa_format_z16 }; 51bf215546Sopenharmony_cistatic const enum xa_formats preferred_sz[] = 52bf215546Sopenharmony_ci { xa_format_x8z24, xa_format_s8z24 }; 53bf215546Sopenharmony_cistatic const enum xa_formats preferred_zs[] = 54bf215546Sopenharmony_ci { xa_format_z24x8, xa_format_z24s8 }; 55bf215546Sopenharmony_cistatic const enum xa_formats preferred_yuv[] = { xa_format_yuv8 }; 56bf215546Sopenharmony_ci 57bf215546Sopenharmony_cistatic const enum xa_formats *preferred[] = 58bf215546Sopenharmony_ci { NULL, preferred_a, preferred_argb, NULL, NULL, 59bf215546Sopenharmony_ci preferred_z, preferred_zs, preferred_sz, preferred_yuv 60bf215546Sopenharmony_ci}; 61bf215546Sopenharmony_ci 62bf215546Sopenharmony_cistatic const unsigned int num_preferred[] = { 0, 63bf215546Sopenharmony_ci sizeof(preferred_a) / sizeof(enum xa_formats), 64bf215546Sopenharmony_ci sizeof(preferred_argb) / sizeof(enum xa_formats), 65bf215546Sopenharmony_ci 0, 66bf215546Sopenharmony_ci 0, 67bf215546Sopenharmony_ci sizeof(preferred_z) / sizeof(enum xa_formats), 68bf215546Sopenharmony_ci sizeof(preferred_zs) / sizeof(enum xa_formats), 69bf215546Sopenharmony_ci sizeof(preferred_sz) / sizeof(enum xa_formats), 70bf215546Sopenharmony_ci sizeof(preferred_yuv) / sizeof(enum xa_formats) 71bf215546Sopenharmony_ci}; 72bf215546Sopenharmony_ci 73bf215546Sopenharmony_cistatic const unsigned int stype_bind[XA_LAST_SURFACE_TYPE] = { 0, 74bf215546Sopenharmony_ci PIPE_BIND_SAMPLER_VIEW, 75bf215546Sopenharmony_ci PIPE_BIND_SAMPLER_VIEW, 76bf215546Sopenharmony_ci PIPE_BIND_SAMPLER_VIEW, 77bf215546Sopenharmony_ci PIPE_BIND_SAMPLER_VIEW, 78bf215546Sopenharmony_ci PIPE_BIND_DEPTH_STENCIL, 79bf215546Sopenharmony_ci PIPE_BIND_DEPTH_STENCIL, 80bf215546Sopenharmony_ci PIPE_BIND_DEPTH_STENCIL, 81bf215546Sopenharmony_ci PIPE_BIND_SAMPLER_VIEW 82bf215546Sopenharmony_ci}; 83bf215546Sopenharmony_ci 84bf215546Sopenharmony_cistatic struct xa_format_descriptor 85bf215546Sopenharmony_cixa_get_pipe_format(struct xa_tracker *xa, enum xa_formats xa_format) 86bf215546Sopenharmony_ci{ 87bf215546Sopenharmony_ci struct xa_format_descriptor fdesc; 88bf215546Sopenharmony_ci 89bf215546Sopenharmony_ci fdesc.xa_format = xa_format; 90bf215546Sopenharmony_ci 91bf215546Sopenharmony_ci switch (xa_format) { 92bf215546Sopenharmony_ci case xa_format_a8: 93bf215546Sopenharmony_ci if (xa->screen->is_format_supported(xa->screen, PIPE_FORMAT_R8_UNORM, 94bf215546Sopenharmony_ci PIPE_TEXTURE_2D, 0, 0, 95bf215546Sopenharmony_ci stype_bind[xa_type_a] | 96bf215546Sopenharmony_ci PIPE_BIND_RENDER_TARGET)) 97bf215546Sopenharmony_ci fdesc.format = PIPE_FORMAT_R8_UNORM; 98bf215546Sopenharmony_ci else 99bf215546Sopenharmony_ci fdesc.format = PIPE_FORMAT_L8_UNORM; 100bf215546Sopenharmony_ci break; 101bf215546Sopenharmony_ci case xa_format_a8r8g8b8: 102bf215546Sopenharmony_ci fdesc.format = PIPE_FORMAT_B8G8R8A8_UNORM; 103bf215546Sopenharmony_ci break; 104bf215546Sopenharmony_ci case xa_format_x8r8g8b8: 105bf215546Sopenharmony_ci fdesc.format = PIPE_FORMAT_B8G8R8X8_UNORM; 106bf215546Sopenharmony_ci break; 107bf215546Sopenharmony_ci case xa_format_r5g6b5: 108bf215546Sopenharmony_ci fdesc.format = PIPE_FORMAT_B5G6R5_UNORM; 109bf215546Sopenharmony_ci break; 110bf215546Sopenharmony_ci case xa_format_x1r5g5b5: 111bf215546Sopenharmony_ci fdesc.format = PIPE_FORMAT_B5G5R5A1_UNORM; 112bf215546Sopenharmony_ci break; 113bf215546Sopenharmony_ci case xa_format_a4r4g4b4: 114bf215546Sopenharmony_ci fdesc.format = PIPE_FORMAT_B4G4R4A4_UNORM; 115bf215546Sopenharmony_ci break; 116bf215546Sopenharmony_ci case xa_format_a2b10g10r10: 117bf215546Sopenharmony_ci fdesc.format = PIPE_FORMAT_R10G10B10A2_UNORM; 118bf215546Sopenharmony_ci break; 119bf215546Sopenharmony_ci case xa_format_x2b10g10r10: 120bf215546Sopenharmony_ci fdesc.format = PIPE_FORMAT_R10G10B10X2_UNORM; 121bf215546Sopenharmony_ci break; 122bf215546Sopenharmony_ci case xa_format_b8g8r8a8: 123bf215546Sopenharmony_ci fdesc.format = PIPE_FORMAT_A8R8G8B8_UNORM; 124bf215546Sopenharmony_ci break; 125bf215546Sopenharmony_ci case xa_format_b8g8r8x8: 126bf215546Sopenharmony_ci fdesc.format = PIPE_FORMAT_X8R8G8B8_UNORM; 127bf215546Sopenharmony_ci break; 128bf215546Sopenharmony_ci case xa_format_z24: 129bf215546Sopenharmony_ci fdesc.format = PIPE_FORMAT_Z24X8_UNORM; 130bf215546Sopenharmony_ci break; 131bf215546Sopenharmony_ci case xa_format_z16: 132bf215546Sopenharmony_ci fdesc.format = PIPE_FORMAT_Z16_UNORM; 133bf215546Sopenharmony_ci break; 134bf215546Sopenharmony_ci case xa_format_z32: 135bf215546Sopenharmony_ci fdesc.format = PIPE_FORMAT_Z32_UNORM; 136bf215546Sopenharmony_ci break; 137bf215546Sopenharmony_ci case xa_format_x8z24: 138bf215546Sopenharmony_ci fdesc.format = PIPE_FORMAT_Z24X8_UNORM; 139bf215546Sopenharmony_ci break; 140bf215546Sopenharmony_ci case xa_format_z24x8: 141bf215546Sopenharmony_ci fdesc.format = PIPE_FORMAT_X8Z24_UNORM; 142bf215546Sopenharmony_ci break; 143bf215546Sopenharmony_ci case xa_format_s8z24: 144bf215546Sopenharmony_ci fdesc.format = PIPE_FORMAT_Z24_UNORM_S8_UINT; 145bf215546Sopenharmony_ci break; 146bf215546Sopenharmony_ci case xa_format_z24s8: 147bf215546Sopenharmony_ci fdesc.format = PIPE_FORMAT_S8_UINT_Z24_UNORM; 148bf215546Sopenharmony_ci break; 149bf215546Sopenharmony_ci case xa_format_yuv8: 150bf215546Sopenharmony_ci if (xa->screen->is_format_supported(xa->screen, PIPE_FORMAT_R8_UNORM, 151bf215546Sopenharmony_ci PIPE_TEXTURE_2D, 0, 0, 152bf215546Sopenharmony_ci stype_bind[xa_type_yuv_component])) 153bf215546Sopenharmony_ci fdesc.format = PIPE_FORMAT_R8_UNORM; 154bf215546Sopenharmony_ci else 155bf215546Sopenharmony_ci fdesc.format = PIPE_FORMAT_L8_UNORM; 156bf215546Sopenharmony_ci break; 157bf215546Sopenharmony_ci default: 158bf215546Sopenharmony_ci unreachable("Unexpected format"); 159bf215546Sopenharmony_ci break; 160bf215546Sopenharmony_ci } 161bf215546Sopenharmony_ci return fdesc; 162bf215546Sopenharmony_ci} 163bf215546Sopenharmony_ci 164bf215546Sopenharmony_ciXA_EXPORT struct xa_tracker * 165bf215546Sopenharmony_cixa_tracker_create(int drm_fd) 166bf215546Sopenharmony_ci{ 167bf215546Sopenharmony_ci struct xa_tracker *xa = calloc(1, sizeof(struct xa_tracker)); 168bf215546Sopenharmony_ci enum xa_surface_type stype; 169bf215546Sopenharmony_ci unsigned int num_formats; 170bf215546Sopenharmony_ci 171bf215546Sopenharmony_ci if (!xa) 172bf215546Sopenharmony_ci return NULL; 173bf215546Sopenharmony_ci 174bf215546Sopenharmony_ci if (pipe_loader_drm_probe_fd(&xa->dev, drm_fd)) 175bf215546Sopenharmony_ci xa->screen = pipe_loader_create_screen(xa->dev); 176bf215546Sopenharmony_ci 177bf215546Sopenharmony_ci if (!xa->screen) 178bf215546Sopenharmony_ci goto out_no_screen; 179bf215546Sopenharmony_ci 180bf215546Sopenharmony_ci xa->default_ctx = xa_context_create(xa); 181bf215546Sopenharmony_ci if (!xa->default_ctx) 182bf215546Sopenharmony_ci goto out_no_pipe; 183bf215546Sopenharmony_ci 184bf215546Sopenharmony_ci num_formats = 0; 185bf215546Sopenharmony_ci for (stype = 0; stype < XA_LAST_SURFACE_TYPE; ++stype) 186bf215546Sopenharmony_ci num_formats += num_preferred[stype]; 187bf215546Sopenharmony_ci 188bf215546Sopenharmony_ci num_formats += 1; 189bf215546Sopenharmony_ci xa->supported_formats = calloc(num_formats, sizeof(*xa->supported_formats)); 190bf215546Sopenharmony_ci if (!xa->supported_formats) 191bf215546Sopenharmony_ci goto out_sf_alloc_fail; 192bf215546Sopenharmony_ci 193bf215546Sopenharmony_ci xa->supported_formats[0] = xa_format_unknown; 194bf215546Sopenharmony_ci num_formats = 1; 195bf215546Sopenharmony_ci memset(xa->format_map, 0, sizeof(xa->format_map)); 196bf215546Sopenharmony_ci 197bf215546Sopenharmony_ci for (stype = 0; stype < XA_LAST_SURFACE_TYPE; ++stype) { 198bf215546Sopenharmony_ci unsigned int bind = stype_bind[stype]; 199bf215546Sopenharmony_ci enum xa_formats xa_format; 200bf215546Sopenharmony_ci int i; 201bf215546Sopenharmony_ci 202bf215546Sopenharmony_ci for (i = 0; i < num_preferred[stype]; ++i) { 203bf215546Sopenharmony_ci xa_format = preferred[stype][i]; 204bf215546Sopenharmony_ci 205bf215546Sopenharmony_ci struct xa_format_descriptor fdesc = 206bf215546Sopenharmony_ci xa_get_pipe_format(xa, xa_format); 207bf215546Sopenharmony_ci 208bf215546Sopenharmony_ci if (xa->screen->is_format_supported(xa->screen, fdesc.format, 209bf215546Sopenharmony_ci PIPE_TEXTURE_2D, 0, 0, bind)) { 210bf215546Sopenharmony_ci if (xa->format_map[stype][0] == 0) 211bf215546Sopenharmony_ci xa->format_map[stype][0] = num_formats; 212bf215546Sopenharmony_ci xa->format_map[stype][1] = num_formats; 213bf215546Sopenharmony_ci xa->supported_formats[num_formats++] = xa_format; 214bf215546Sopenharmony_ci } 215bf215546Sopenharmony_ci } 216bf215546Sopenharmony_ci } 217bf215546Sopenharmony_ci return xa; 218bf215546Sopenharmony_ci 219bf215546Sopenharmony_ci out_sf_alloc_fail: 220bf215546Sopenharmony_ci xa_context_destroy(xa->default_ctx); 221bf215546Sopenharmony_ci out_no_pipe: 222bf215546Sopenharmony_ci xa->screen->destroy(xa->screen); 223bf215546Sopenharmony_ci out_no_screen: 224bf215546Sopenharmony_ci if (xa->dev) 225bf215546Sopenharmony_ci pipe_loader_release(&xa->dev, 1); 226bf215546Sopenharmony_ci 227bf215546Sopenharmony_ci free(xa); 228bf215546Sopenharmony_ci return NULL; 229bf215546Sopenharmony_ci} 230bf215546Sopenharmony_ci 231bf215546Sopenharmony_ciXA_EXPORT void 232bf215546Sopenharmony_cixa_tracker_destroy(struct xa_tracker *xa) 233bf215546Sopenharmony_ci{ 234bf215546Sopenharmony_ci free(xa->supported_formats); 235bf215546Sopenharmony_ci xa_context_destroy(xa->default_ctx); 236bf215546Sopenharmony_ci xa->screen->destroy(xa->screen); 237bf215546Sopenharmony_ci pipe_loader_release(&xa->dev, 1); 238bf215546Sopenharmony_ci /* CHECK: The XA API user preserves ownership of the original fd */ 239bf215546Sopenharmony_ci free(xa); 240bf215546Sopenharmony_ci} 241bf215546Sopenharmony_ci 242bf215546Sopenharmony_cistatic int 243bf215546Sopenharmony_cixa_flags_compat(unsigned int old_flags, unsigned int new_flags) 244bf215546Sopenharmony_ci{ 245bf215546Sopenharmony_ci unsigned int flag_diff = (old_flags ^ new_flags); 246bf215546Sopenharmony_ci 247bf215546Sopenharmony_ci if (flag_diff == 0) 248bf215546Sopenharmony_ci return 1; 249bf215546Sopenharmony_ci 250bf215546Sopenharmony_ci if (flag_diff & XA_FLAG_SHARED) 251bf215546Sopenharmony_ci return 0; 252bf215546Sopenharmony_ci /* 253bf215546Sopenharmony_ci * Don't recreate if we're dropping the render target flag. 254bf215546Sopenharmony_ci */ 255bf215546Sopenharmony_ci if (flag_diff & XA_FLAG_RENDER_TARGET) 256bf215546Sopenharmony_ci return ((new_flags & XA_FLAG_RENDER_TARGET) == 0); 257bf215546Sopenharmony_ci 258bf215546Sopenharmony_ci /* 259bf215546Sopenharmony_ci * Don't recreate if we're dropping the scanout flag. 260bf215546Sopenharmony_ci */ 261bf215546Sopenharmony_ci if (flag_diff & XA_FLAG_SCANOUT) 262bf215546Sopenharmony_ci return ((new_flags & XA_FLAG_SCANOUT) == 0); 263bf215546Sopenharmony_ci 264bf215546Sopenharmony_ci /* 265bf215546Sopenharmony_ci * Always recreate for unknown / unimplemented flags. 266bf215546Sopenharmony_ci */ 267bf215546Sopenharmony_ci return 0; 268bf215546Sopenharmony_ci} 269bf215546Sopenharmony_ci 270bf215546Sopenharmony_cistatic struct xa_format_descriptor 271bf215546Sopenharmony_cixa_get_format_stype_depth(struct xa_tracker *xa, 272bf215546Sopenharmony_ci enum xa_surface_type stype, unsigned int depth) 273bf215546Sopenharmony_ci{ 274bf215546Sopenharmony_ci unsigned int i; 275bf215546Sopenharmony_ci struct xa_format_descriptor fdesc; 276bf215546Sopenharmony_ci int found = 0; 277bf215546Sopenharmony_ci 278bf215546Sopenharmony_ci for (i = xa->format_map[stype][0]; i <= xa->format_map[stype][1]; ++i) { 279bf215546Sopenharmony_ci fdesc = xa_get_pipe_format(xa, xa->supported_formats[i]); 280bf215546Sopenharmony_ci if (fdesc.xa_format != xa_format_unknown && 281bf215546Sopenharmony_ci xa_format_depth(fdesc.xa_format) == depth) { 282bf215546Sopenharmony_ci found = 1; 283bf215546Sopenharmony_ci break; 284bf215546Sopenharmony_ci } 285bf215546Sopenharmony_ci } 286bf215546Sopenharmony_ci 287bf215546Sopenharmony_ci if (!found) 288bf215546Sopenharmony_ci fdesc.xa_format = xa_format_unknown; 289bf215546Sopenharmony_ci 290bf215546Sopenharmony_ci return fdesc; 291bf215546Sopenharmony_ci} 292bf215546Sopenharmony_ci 293bf215546Sopenharmony_ciXA_EXPORT int 294bf215546Sopenharmony_cixa_format_check_supported(struct xa_tracker *xa, 295bf215546Sopenharmony_ci enum xa_formats xa_format, unsigned int flags) 296bf215546Sopenharmony_ci{ 297bf215546Sopenharmony_ci struct xa_format_descriptor fdesc = xa_get_pipe_format(xa, xa_format); 298bf215546Sopenharmony_ci unsigned int bind; 299bf215546Sopenharmony_ci 300bf215546Sopenharmony_ci if (fdesc.xa_format == xa_format_unknown) 301bf215546Sopenharmony_ci return -XA_ERR_INVAL; 302bf215546Sopenharmony_ci 303bf215546Sopenharmony_ci bind = stype_bind[xa_format_type(fdesc.xa_format)]; 304bf215546Sopenharmony_ci if (flags & XA_FLAG_SHARED) 305bf215546Sopenharmony_ci bind |= PIPE_BIND_SHARED; 306bf215546Sopenharmony_ci if (flags & XA_FLAG_RENDER_TARGET) 307bf215546Sopenharmony_ci bind |= PIPE_BIND_RENDER_TARGET; 308bf215546Sopenharmony_ci if (flags & XA_FLAG_SCANOUT) 309bf215546Sopenharmony_ci bind |= PIPE_BIND_SCANOUT; 310bf215546Sopenharmony_ci 311bf215546Sopenharmony_ci if (!xa->screen->is_format_supported(xa->screen, fdesc.format, 312bf215546Sopenharmony_ci PIPE_TEXTURE_2D, 0, 0, bind)) 313bf215546Sopenharmony_ci return -XA_ERR_INVAL; 314bf215546Sopenharmony_ci 315bf215546Sopenharmony_ci return XA_ERR_NONE; 316bf215546Sopenharmony_ci} 317bf215546Sopenharmony_ci 318bf215546Sopenharmony_cistatic unsigned 319bf215546Sopenharmony_cihandle_type(enum xa_handle_type type) 320bf215546Sopenharmony_ci{ 321bf215546Sopenharmony_ci switch (type) { 322bf215546Sopenharmony_ci case xa_handle_type_kms: 323bf215546Sopenharmony_ci return WINSYS_HANDLE_TYPE_KMS; 324bf215546Sopenharmony_ci case xa_handle_type_fd: 325bf215546Sopenharmony_ci return WINSYS_HANDLE_TYPE_FD; 326bf215546Sopenharmony_ci case xa_handle_type_shared: 327bf215546Sopenharmony_ci default: 328bf215546Sopenharmony_ci return WINSYS_HANDLE_TYPE_SHARED; 329bf215546Sopenharmony_ci } 330bf215546Sopenharmony_ci} 331bf215546Sopenharmony_ci 332bf215546Sopenharmony_cistatic struct xa_surface * 333bf215546Sopenharmony_cisurface_create(struct xa_tracker *xa, 334bf215546Sopenharmony_ci int width, 335bf215546Sopenharmony_ci int height, 336bf215546Sopenharmony_ci int depth, 337bf215546Sopenharmony_ci enum xa_surface_type stype, 338bf215546Sopenharmony_ci enum xa_formats xa_format, unsigned int flags, 339bf215546Sopenharmony_ci struct winsys_handle *whandle) 340bf215546Sopenharmony_ci{ 341bf215546Sopenharmony_ci struct pipe_resource *template; 342bf215546Sopenharmony_ci struct xa_surface *srf; 343bf215546Sopenharmony_ci struct xa_format_descriptor fdesc; 344bf215546Sopenharmony_ci 345bf215546Sopenharmony_ci if (xa_format == xa_format_unknown) 346bf215546Sopenharmony_ci fdesc = xa_get_format_stype_depth(xa, stype, depth); 347bf215546Sopenharmony_ci else 348bf215546Sopenharmony_ci fdesc = xa_get_pipe_format(xa, xa_format); 349bf215546Sopenharmony_ci 350bf215546Sopenharmony_ci if (fdesc.xa_format == xa_format_unknown) 351bf215546Sopenharmony_ci return NULL; 352bf215546Sopenharmony_ci 353bf215546Sopenharmony_ci srf = calloc(1, sizeof(*srf)); 354bf215546Sopenharmony_ci if (!srf) 355bf215546Sopenharmony_ci return NULL; 356bf215546Sopenharmony_ci 357bf215546Sopenharmony_ci template = &srf->template; 358bf215546Sopenharmony_ci template->format = fdesc.format; 359bf215546Sopenharmony_ci template->target = PIPE_TEXTURE_2D; 360bf215546Sopenharmony_ci template->width0 = width; 361bf215546Sopenharmony_ci template->height0 = height; 362bf215546Sopenharmony_ci template->depth0 = 1; 363bf215546Sopenharmony_ci template->array_size = 1; 364bf215546Sopenharmony_ci template->last_level = 0; 365bf215546Sopenharmony_ci template->bind = stype_bind[xa_format_type(fdesc.xa_format)]; 366bf215546Sopenharmony_ci 367bf215546Sopenharmony_ci if (flags & XA_FLAG_SHARED) 368bf215546Sopenharmony_ci template->bind |= PIPE_BIND_SHARED; 369bf215546Sopenharmony_ci if (flags & XA_FLAG_RENDER_TARGET) 370bf215546Sopenharmony_ci template->bind |= PIPE_BIND_RENDER_TARGET; 371bf215546Sopenharmony_ci if (flags & XA_FLAG_SCANOUT) 372bf215546Sopenharmony_ci template->bind |= PIPE_BIND_SCANOUT; 373bf215546Sopenharmony_ci 374bf215546Sopenharmony_ci if (whandle) 375bf215546Sopenharmony_ci srf->tex = xa->screen->resource_from_handle(xa->screen, template, whandle, 376bf215546Sopenharmony_ci PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE); 377bf215546Sopenharmony_ci else 378bf215546Sopenharmony_ci srf->tex = xa->screen->resource_create(xa->screen, template); 379bf215546Sopenharmony_ci if (!srf->tex) 380bf215546Sopenharmony_ci goto out_no_tex; 381bf215546Sopenharmony_ci 382bf215546Sopenharmony_ci srf->refcount = 1; 383bf215546Sopenharmony_ci srf->xa = xa; 384bf215546Sopenharmony_ci srf->flags = flags; 385bf215546Sopenharmony_ci srf->fdesc = fdesc; 386bf215546Sopenharmony_ci 387bf215546Sopenharmony_ci return srf; 388bf215546Sopenharmony_ci out_no_tex: 389bf215546Sopenharmony_ci free(srf); 390bf215546Sopenharmony_ci return NULL; 391bf215546Sopenharmony_ci} 392bf215546Sopenharmony_ci 393bf215546Sopenharmony_ci 394bf215546Sopenharmony_ciXA_EXPORT struct xa_surface * 395bf215546Sopenharmony_cixa_surface_create(struct xa_tracker *xa, 396bf215546Sopenharmony_ci int width, 397bf215546Sopenharmony_ci int height, 398bf215546Sopenharmony_ci int depth, 399bf215546Sopenharmony_ci enum xa_surface_type stype, 400bf215546Sopenharmony_ci enum xa_formats xa_format, unsigned int flags) 401bf215546Sopenharmony_ci{ 402bf215546Sopenharmony_ci return surface_create(xa, width, height, depth, stype, xa_format, flags, NULL); 403bf215546Sopenharmony_ci} 404bf215546Sopenharmony_ci 405bf215546Sopenharmony_ci 406bf215546Sopenharmony_ciXA_EXPORT struct xa_surface * 407bf215546Sopenharmony_cixa_surface_from_handle(struct xa_tracker *xa, 408bf215546Sopenharmony_ci int width, 409bf215546Sopenharmony_ci int height, 410bf215546Sopenharmony_ci int depth, 411bf215546Sopenharmony_ci enum xa_surface_type stype, 412bf215546Sopenharmony_ci enum xa_formats xa_format, unsigned int flags, 413bf215546Sopenharmony_ci uint32_t handle, uint32_t stride) 414bf215546Sopenharmony_ci{ 415bf215546Sopenharmony_ci return xa_surface_from_handle2(xa, width, height, depth, stype, xa_format, 416bf215546Sopenharmony_ci WINSYS_HANDLE_TYPE_SHARED, flags, handle, 417bf215546Sopenharmony_ci stride); 418bf215546Sopenharmony_ci} 419bf215546Sopenharmony_ci 420bf215546Sopenharmony_ciXA_EXPORT struct xa_surface * 421bf215546Sopenharmony_cixa_surface_from_handle2(struct xa_tracker *xa, 422bf215546Sopenharmony_ci int width, 423bf215546Sopenharmony_ci int height, 424bf215546Sopenharmony_ci int depth, 425bf215546Sopenharmony_ci enum xa_surface_type stype, 426bf215546Sopenharmony_ci enum xa_formats xa_format, unsigned int flags, 427bf215546Sopenharmony_ci enum xa_handle_type type, 428bf215546Sopenharmony_ci uint32_t handle, uint32_t stride) 429bf215546Sopenharmony_ci{ 430bf215546Sopenharmony_ci struct winsys_handle whandle; 431bf215546Sopenharmony_ci memset(&whandle, 0, sizeof(whandle)); 432bf215546Sopenharmony_ci whandle.type = handle_type(type); 433bf215546Sopenharmony_ci whandle.handle = handle; 434bf215546Sopenharmony_ci whandle.stride = stride; 435bf215546Sopenharmony_ci return surface_create(xa, width, height, depth, stype, xa_format, flags, &whandle); 436bf215546Sopenharmony_ci} 437bf215546Sopenharmony_ci 438bf215546Sopenharmony_ciXA_EXPORT int 439bf215546Sopenharmony_cixa_surface_redefine(struct xa_surface *srf, 440bf215546Sopenharmony_ci int width, 441bf215546Sopenharmony_ci int height, 442bf215546Sopenharmony_ci int depth, 443bf215546Sopenharmony_ci enum xa_surface_type stype, 444bf215546Sopenharmony_ci enum xa_formats xa_format, 445bf215546Sopenharmony_ci unsigned int new_flags, 446bf215546Sopenharmony_ci int copy_contents) 447bf215546Sopenharmony_ci{ 448bf215546Sopenharmony_ci struct pipe_resource *template = &srf->template; 449bf215546Sopenharmony_ci struct pipe_resource *texture; 450bf215546Sopenharmony_ci struct pipe_box src_box; 451bf215546Sopenharmony_ci struct xa_tracker *xa = srf->xa; 452bf215546Sopenharmony_ci int save_width; 453bf215546Sopenharmony_ci int save_height; 454bf215546Sopenharmony_ci unsigned int save_format; 455bf215546Sopenharmony_ci struct xa_format_descriptor fdesc; 456bf215546Sopenharmony_ci 457bf215546Sopenharmony_ci 458bf215546Sopenharmony_ci if (xa_format == xa_format_unknown) 459bf215546Sopenharmony_ci fdesc = xa_get_format_stype_depth(xa, stype, depth); 460bf215546Sopenharmony_ci else 461bf215546Sopenharmony_ci fdesc = xa_get_pipe_format(xa, xa_format); 462bf215546Sopenharmony_ci 463bf215546Sopenharmony_ci if (width == template->width0 && height == template->height0 && 464bf215546Sopenharmony_ci template->format == fdesc.format && 465bf215546Sopenharmony_ci xa_flags_compat(srf->flags, new_flags)) 466bf215546Sopenharmony_ci return XA_ERR_NONE; 467bf215546Sopenharmony_ci 468bf215546Sopenharmony_ci template->bind = stype_bind[xa_format_type(fdesc.xa_format)]; 469bf215546Sopenharmony_ci if (new_flags & XA_FLAG_SHARED) 470bf215546Sopenharmony_ci template->bind |= PIPE_BIND_SHARED; 471bf215546Sopenharmony_ci if (new_flags & XA_FLAG_RENDER_TARGET) 472bf215546Sopenharmony_ci template->bind |= PIPE_BIND_RENDER_TARGET; 473bf215546Sopenharmony_ci if (new_flags & XA_FLAG_SCANOUT) 474bf215546Sopenharmony_ci template->bind |= PIPE_BIND_SCANOUT; 475bf215546Sopenharmony_ci 476bf215546Sopenharmony_ci if (copy_contents) { 477bf215546Sopenharmony_ci if (!xa_format_type_is_color(fdesc.xa_format) || 478bf215546Sopenharmony_ci xa_format_type(fdesc.xa_format) == xa_type_a) 479bf215546Sopenharmony_ci return -XA_ERR_INVAL; 480bf215546Sopenharmony_ci 481bf215546Sopenharmony_ci if (!xa->screen->is_format_supported(xa->screen, fdesc.format, 482bf215546Sopenharmony_ci PIPE_TEXTURE_2D, 0, 0, 483bf215546Sopenharmony_ci template->bind | 484bf215546Sopenharmony_ci PIPE_BIND_RENDER_TARGET)) 485bf215546Sopenharmony_ci return -XA_ERR_INVAL; 486bf215546Sopenharmony_ci } 487bf215546Sopenharmony_ci 488bf215546Sopenharmony_ci save_width = template->width0; 489bf215546Sopenharmony_ci save_height = template->height0; 490bf215546Sopenharmony_ci save_format = template->format; 491bf215546Sopenharmony_ci 492bf215546Sopenharmony_ci template->width0 = width; 493bf215546Sopenharmony_ci template->height0 = height; 494bf215546Sopenharmony_ci template->format = fdesc.format; 495bf215546Sopenharmony_ci 496bf215546Sopenharmony_ci texture = xa->screen->resource_create(xa->screen, template); 497bf215546Sopenharmony_ci if (!texture) { 498bf215546Sopenharmony_ci template->width0 = save_width; 499bf215546Sopenharmony_ci template->height0 = save_height; 500bf215546Sopenharmony_ci template->format = save_format; 501bf215546Sopenharmony_ci return -XA_ERR_NORES; 502bf215546Sopenharmony_ci } 503bf215546Sopenharmony_ci 504bf215546Sopenharmony_ci if (copy_contents) { 505bf215546Sopenharmony_ci struct pipe_context *pipe = xa->default_ctx->pipe; 506bf215546Sopenharmony_ci 507bf215546Sopenharmony_ci u_box_origin_2d(xa_min(save_width, template->width0), 508bf215546Sopenharmony_ci xa_min(save_height, template->height0), &src_box); 509bf215546Sopenharmony_ci pipe->resource_copy_region(pipe, texture, 510bf215546Sopenharmony_ci 0, 0, 0, 0, srf->tex, 0, &src_box); 511bf215546Sopenharmony_ci xa_context_flush(xa->default_ctx); 512bf215546Sopenharmony_ci } 513bf215546Sopenharmony_ci 514bf215546Sopenharmony_ci pipe_resource_reference(&srf->tex, texture); 515bf215546Sopenharmony_ci pipe_resource_reference(&texture, NULL); 516bf215546Sopenharmony_ci srf->fdesc = fdesc; 517bf215546Sopenharmony_ci srf->flags = new_flags; 518bf215546Sopenharmony_ci 519bf215546Sopenharmony_ci return XA_ERR_NONE; 520bf215546Sopenharmony_ci} 521bf215546Sopenharmony_ci 522bf215546Sopenharmony_ciXA_EXPORT struct xa_surface* 523bf215546Sopenharmony_cixa_surface_ref(struct xa_surface *srf) 524bf215546Sopenharmony_ci{ 525bf215546Sopenharmony_ci if (srf == NULL) { 526bf215546Sopenharmony_ci return NULL; 527bf215546Sopenharmony_ci } 528bf215546Sopenharmony_ci srf->refcount++; 529bf215546Sopenharmony_ci return srf; 530bf215546Sopenharmony_ci} 531bf215546Sopenharmony_ci 532bf215546Sopenharmony_ciXA_EXPORT void 533bf215546Sopenharmony_cixa_surface_unref(struct xa_surface *srf) 534bf215546Sopenharmony_ci{ 535bf215546Sopenharmony_ci if (srf == NULL || --srf->refcount) { 536bf215546Sopenharmony_ci return; 537bf215546Sopenharmony_ci } 538bf215546Sopenharmony_ci pipe_resource_reference(&srf->tex, NULL); 539bf215546Sopenharmony_ci free(srf); 540bf215546Sopenharmony_ci} 541bf215546Sopenharmony_ci 542bf215546Sopenharmony_ciXA_EXPORT void 543bf215546Sopenharmony_cixa_tracker_version(int *major, int *minor, int *patch) 544bf215546Sopenharmony_ci{ 545bf215546Sopenharmony_ci *major = XA_TRACKER_VERSION_MAJOR; 546bf215546Sopenharmony_ci *minor = XA_TRACKER_VERSION_MINOR; 547bf215546Sopenharmony_ci *patch = XA_TRACKER_VERSION_PATCH; 548bf215546Sopenharmony_ci} 549bf215546Sopenharmony_ci 550bf215546Sopenharmony_ciXA_EXPORT int 551bf215546Sopenharmony_cixa_surface_handle(struct xa_surface *srf, 552bf215546Sopenharmony_ci enum xa_handle_type type, 553bf215546Sopenharmony_ci uint32_t * handle, unsigned int *stride) 554bf215546Sopenharmony_ci{ 555bf215546Sopenharmony_ci struct winsys_handle whandle; 556bf215546Sopenharmony_ci 557bf215546Sopenharmony_ci struct pipe_screen *screen = srf->xa->screen; 558bf215546Sopenharmony_ci boolean res; 559bf215546Sopenharmony_ci 560bf215546Sopenharmony_ci memset(&whandle, 0, sizeof(whandle)); 561bf215546Sopenharmony_ci whandle.type = handle_type(type); 562bf215546Sopenharmony_ci res = screen->resource_get_handle(screen, srf->xa->default_ctx->pipe, 563bf215546Sopenharmony_ci srf->tex, &whandle, 564bf215546Sopenharmony_ci PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE); 565bf215546Sopenharmony_ci if (!res) 566bf215546Sopenharmony_ci return -XA_ERR_INVAL; 567bf215546Sopenharmony_ci 568bf215546Sopenharmony_ci *handle = whandle.handle; 569bf215546Sopenharmony_ci *stride = whandle.stride; 570bf215546Sopenharmony_ci 571bf215546Sopenharmony_ci return XA_ERR_NONE; 572bf215546Sopenharmony_ci} 573bf215546Sopenharmony_ci 574bf215546Sopenharmony_ciXA_EXPORT enum xa_formats 575bf215546Sopenharmony_cixa_surface_format(const struct xa_surface *srf) 576bf215546Sopenharmony_ci{ 577bf215546Sopenharmony_ci return srf->fdesc.xa_format; 578bf215546Sopenharmony_ci} 579