1bf215546Sopenharmony_ci/************************************************************************** 2bf215546Sopenharmony_ci * 3bf215546Sopenharmony_ci * Copyright 2006 VMware, Inc. 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 * Authors: 29bf215546Sopenharmony_ci * Keith Whitwell <keithw@vmware.com> 30bf215546Sopenharmony_ci * Michel Dänzer <daenzer@vmware.com> 31bf215546Sopenharmony_ci */ 32bf215546Sopenharmony_ci 33bf215546Sopenharmony_ci#include <stdio.h> 34bf215546Sopenharmony_ci 35bf215546Sopenharmony_ci#include "pipe/p_context.h" 36bf215546Sopenharmony_ci#include "pipe/p_defines.h" 37bf215546Sopenharmony_ci 38bf215546Sopenharmony_ci#include "util/u_inlines.h" 39bf215546Sopenharmony_ci#include "util/u_cpu_detect.h" 40bf215546Sopenharmony_ci#include "util/format/u_format.h" 41bf215546Sopenharmony_ci#include "util/u_math.h" 42bf215546Sopenharmony_ci#include "util/u_memory.h" 43bf215546Sopenharmony_ci#include "util/u_transfer.h" 44bf215546Sopenharmony_ci 45bf215546Sopenharmony_ci#include "lp_context.h" 46bf215546Sopenharmony_ci#include "lp_flush.h" 47bf215546Sopenharmony_ci#include "lp_screen.h" 48bf215546Sopenharmony_ci#include "lp_texture.h" 49bf215546Sopenharmony_ci#include "lp_setup.h" 50bf215546Sopenharmony_ci#include "lp_state.h" 51bf215546Sopenharmony_ci#include "lp_rast.h" 52bf215546Sopenharmony_ci 53bf215546Sopenharmony_ci#include "frontend/sw_winsys.h" 54bf215546Sopenharmony_ci#include "git_sha1.h" 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_ci#ifndef _WIN32 57bf215546Sopenharmony_ci#include "drm-uapi/drm_fourcc.h" 58bf215546Sopenharmony_ci#endif 59bf215546Sopenharmony_ci 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_ci#ifdef DEBUG 62bf215546Sopenharmony_cistatic struct llvmpipe_resource resource_list; 63bf215546Sopenharmony_cistatic mtx_t resource_list_mutex = _MTX_INITIALIZER_NP; 64bf215546Sopenharmony_ci#endif 65bf215546Sopenharmony_cistatic unsigned id_counter = 0; 66bf215546Sopenharmony_ci 67bf215546Sopenharmony_ci 68bf215546Sopenharmony_ci/** 69bf215546Sopenharmony_ci * Conventional allocation path for non-display textures: 70bf215546Sopenharmony_ci * Compute strides and allocate data (unless asked not to). 71bf215546Sopenharmony_ci */ 72bf215546Sopenharmony_cistatic boolean 73bf215546Sopenharmony_cillvmpipe_texture_layout(struct llvmpipe_screen *screen, 74bf215546Sopenharmony_ci struct llvmpipe_resource *lpr, 75bf215546Sopenharmony_ci boolean allocate) 76bf215546Sopenharmony_ci{ 77bf215546Sopenharmony_ci struct pipe_resource *pt = &lpr->base; 78bf215546Sopenharmony_ci unsigned level; 79bf215546Sopenharmony_ci unsigned width = pt->width0; 80bf215546Sopenharmony_ci unsigned height = pt->height0; 81bf215546Sopenharmony_ci unsigned depth = pt->depth0; 82bf215546Sopenharmony_ci uint64_t total_size = 0; 83bf215546Sopenharmony_ci unsigned layers = pt->array_size; 84bf215546Sopenharmony_ci unsigned num_samples = util_res_sample_count(pt); 85bf215546Sopenharmony_ci 86bf215546Sopenharmony_ci /* XXX: 87bf215546Sopenharmony_ci * This alignment here (same for displaytarget) was added for the purpose of 88bf215546Sopenharmony_ci * ARB_map_buffer_alignment. I am not convinced it's needed for non-buffer 89bf215546Sopenharmony_ci * resources. Otherwise we'd want the max of cacheline size and 16 (max size 90bf215546Sopenharmony_ci * of a block for all formats) though this should not be strictly necessary 91bf215546Sopenharmony_ci * neither. In any case it can only affect compressed or 1d textures. 92bf215546Sopenharmony_ci */ 93bf215546Sopenharmony_ci unsigned mip_align = MAX2(64, util_get_cpu_caps()->cacheline); 94bf215546Sopenharmony_ci 95bf215546Sopenharmony_ci assert(LP_MAX_TEXTURE_2D_LEVELS <= LP_MAX_TEXTURE_LEVELS); 96bf215546Sopenharmony_ci assert(LP_MAX_TEXTURE_3D_LEVELS <= LP_MAX_TEXTURE_LEVELS); 97bf215546Sopenharmony_ci 98bf215546Sopenharmony_ci for (level = 0; level <= pt->last_level; level++) { 99bf215546Sopenharmony_ci uint64_t mipsize; 100bf215546Sopenharmony_ci unsigned align_x, align_y, nblocksx, nblocksy, block_size, num_slices; 101bf215546Sopenharmony_ci 102bf215546Sopenharmony_ci /* Row stride and image stride */ 103bf215546Sopenharmony_ci 104bf215546Sopenharmony_ci /* For non-compressed formats we need 4x4 pixel alignment 105bf215546Sopenharmony_ci * so we can read/write LP_RASTER_BLOCK_SIZE when rendering to them. 106bf215546Sopenharmony_ci * We also want cache line size in x direction, 107bf215546Sopenharmony_ci * otherwise same cache line could end up in multiple threads. 108bf215546Sopenharmony_ci * For explicit 1d resources however we reduce this to 4x1 and 109bf215546Sopenharmony_ci * handle specially in render output code (as we need to do special 110bf215546Sopenharmony_ci * handling there for buffers in any case). 111bf215546Sopenharmony_ci */ 112bf215546Sopenharmony_ci if (util_format_is_compressed(pt->format)) 113bf215546Sopenharmony_ci align_x = align_y = 1; 114bf215546Sopenharmony_ci else { 115bf215546Sopenharmony_ci align_x = LP_RASTER_BLOCK_SIZE; 116bf215546Sopenharmony_ci if (llvmpipe_resource_is_1d(&lpr->base)) 117bf215546Sopenharmony_ci align_y = 1; 118bf215546Sopenharmony_ci else 119bf215546Sopenharmony_ci align_y = LP_RASTER_BLOCK_SIZE; 120bf215546Sopenharmony_ci } 121bf215546Sopenharmony_ci 122bf215546Sopenharmony_ci nblocksx = util_format_get_nblocksx(pt->format, 123bf215546Sopenharmony_ci align(width, align_x)); 124bf215546Sopenharmony_ci nblocksy = util_format_get_nblocksy(pt->format, 125bf215546Sopenharmony_ci align(height, align_y)); 126bf215546Sopenharmony_ci block_size = util_format_get_blocksize(pt->format); 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_ci if (util_format_is_compressed(pt->format)) 129bf215546Sopenharmony_ci lpr->row_stride[level] = nblocksx * block_size; 130bf215546Sopenharmony_ci else 131bf215546Sopenharmony_ci lpr->row_stride[level] = align(nblocksx * block_size, util_get_cpu_caps()->cacheline); 132bf215546Sopenharmony_ci 133bf215546Sopenharmony_ci lpr->img_stride[level] = (uint64_t)lpr->row_stride[level] * nblocksy; 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci /* Number of 3D image slices, cube faces or texture array layers */ 136bf215546Sopenharmony_ci if (lpr->base.target == PIPE_TEXTURE_CUBE) { 137bf215546Sopenharmony_ci assert(layers == 6); 138bf215546Sopenharmony_ci } 139bf215546Sopenharmony_ci 140bf215546Sopenharmony_ci if (lpr->base.target == PIPE_TEXTURE_3D) 141bf215546Sopenharmony_ci num_slices = depth; 142bf215546Sopenharmony_ci else if (lpr->base.target == PIPE_TEXTURE_1D_ARRAY || 143bf215546Sopenharmony_ci lpr->base.target == PIPE_TEXTURE_2D_ARRAY || 144bf215546Sopenharmony_ci lpr->base.target == PIPE_TEXTURE_CUBE || 145bf215546Sopenharmony_ci lpr->base.target == PIPE_TEXTURE_CUBE_ARRAY) 146bf215546Sopenharmony_ci num_slices = layers; 147bf215546Sopenharmony_ci else 148bf215546Sopenharmony_ci num_slices = 1; 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_ci mipsize = lpr->img_stride[level] * num_slices; 151bf215546Sopenharmony_ci lpr->mip_offsets[level] = total_size; 152bf215546Sopenharmony_ci 153bf215546Sopenharmony_ci total_size += align64(mipsize, mip_align); 154bf215546Sopenharmony_ci 155bf215546Sopenharmony_ci /* Compute size of next mipmap level */ 156bf215546Sopenharmony_ci width = u_minify(width, 1); 157bf215546Sopenharmony_ci height = u_minify(height, 1); 158bf215546Sopenharmony_ci depth = u_minify(depth, 1); 159bf215546Sopenharmony_ci } 160bf215546Sopenharmony_ci 161bf215546Sopenharmony_ci lpr->sample_stride = total_size; 162bf215546Sopenharmony_ci total_size *= num_samples; 163bf215546Sopenharmony_ci 164bf215546Sopenharmony_ci lpr->size_required = total_size; 165bf215546Sopenharmony_ci if (allocate) { 166bf215546Sopenharmony_ci if (total_size > LP_MAX_TEXTURE_SIZE) 167bf215546Sopenharmony_ci goto fail; 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_ci lpr->tex_data = align_malloc(total_size, mip_align); 170bf215546Sopenharmony_ci if (!lpr->tex_data) { 171bf215546Sopenharmony_ci return FALSE; 172bf215546Sopenharmony_ci } 173bf215546Sopenharmony_ci else { 174bf215546Sopenharmony_ci memset(lpr->tex_data, 0, total_size); 175bf215546Sopenharmony_ci } 176bf215546Sopenharmony_ci } 177bf215546Sopenharmony_ci 178bf215546Sopenharmony_ci return TRUE; 179bf215546Sopenharmony_ci 180bf215546Sopenharmony_cifail: 181bf215546Sopenharmony_ci return FALSE; 182bf215546Sopenharmony_ci} 183bf215546Sopenharmony_ci 184bf215546Sopenharmony_ci 185bf215546Sopenharmony_ci/** 186bf215546Sopenharmony_ci * Check the size of the texture specified by 'res'. 187bf215546Sopenharmony_ci * \return TRUE if OK, FALSE if too large. 188bf215546Sopenharmony_ci */ 189bf215546Sopenharmony_cistatic bool 190bf215546Sopenharmony_cillvmpipe_can_create_resource(struct pipe_screen *screen, 191bf215546Sopenharmony_ci const struct pipe_resource *res) 192bf215546Sopenharmony_ci{ 193bf215546Sopenharmony_ci struct llvmpipe_resource lpr; 194bf215546Sopenharmony_ci memset(&lpr, 0, sizeof(lpr)); 195bf215546Sopenharmony_ci lpr.base = *res; 196bf215546Sopenharmony_ci if (!llvmpipe_texture_layout(llvmpipe_screen(screen), &lpr, false)) 197bf215546Sopenharmony_ci return false; 198bf215546Sopenharmony_ci 199bf215546Sopenharmony_ci return lpr.size_required <= LP_MAX_TEXTURE_SIZE; 200bf215546Sopenharmony_ci} 201bf215546Sopenharmony_ci 202bf215546Sopenharmony_ci 203bf215546Sopenharmony_cistatic boolean 204bf215546Sopenharmony_cillvmpipe_displaytarget_layout(struct llvmpipe_screen *screen, 205bf215546Sopenharmony_ci struct llvmpipe_resource *lpr, 206bf215546Sopenharmony_ci const void *map_front_private) 207bf215546Sopenharmony_ci{ 208bf215546Sopenharmony_ci struct sw_winsys *winsys = screen->winsys; 209bf215546Sopenharmony_ci 210bf215546Sopenharmony_ci /* Round up the surface size to a multiple of the tile size to 211bf215546Sopenharmony_ci * avoid tile clipping. 212bf215546Sopenharmony_ci */ 213bf215546Sopenharmony_ci const unsigned width = MAX2(1, align(lpr->base.width0, TILE_SIZE)); 214bf215546Sopenharmony_ci const unsigned height = MAX2(1, align(lpr->base.height0, TILE_SIZE)); 215bf215546Sopenharmony_ci 216bf215546Sopenharmony_ci lpr->dt = winsys->displaytarget_create(winsys, 217bf215546Sopenharmony_ci lpr->base.bind, 218bf215546Sopenharmony_ci lpr->base.format, 219bf215546Sopenharmony_ci width, height, 220bf215546Sopenharmony_ci 64, 221bf215546Sopenharmony_ci map_front_private, 222bf215546Sopenharmony_ci &lpr->row_stride[0] ); 223bf215546Sopenharmony_ci 224bf215546Sopenharmony_ci return lpr->dt != NULL; 225bf215546Sopenharmony_ci} 226bf215546Sopenharmony_ci 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_cistatic struct pipe_resource * 229bf215546Sopenharmony_cillvmpipe_resource_create_all(struct pipe_screen *_screen, 230bf215546Sopenharmony_ci const struct pipe_resource *templat, 231bf215546Sopenharmony_ci const void *map_front_private, bool alloc_backing) 232bf215546Sopenharmony_ci{ 233bf215546Sopenharmony_ci struct llvmpipe_screen *screen = llvmpipe_screen(_screen); 234bf215546Sopenharmony_ci struct llvmpipe_resource *lpr = CALLOC_STRUCT(llvmpipe_resource); 235bf215546Sopenharmony_ci if (!lpr) 236bf215546Sopenharmony_ci return NULL; 237bf215546Sopenharmony_ci 238bf215546Sopenharmony_ci lpr->base = *templat; 239bf215546Sopenharmony_ci lpr->screen = screen; 240bf215546Sopenharmony_ci pipe_reference_init(&lpr->base.reference, 1); 241bf215546Sopenharmony_ci lpr->base.screen = &screen->base; 242bf215546Sopenharmony_ci 243bf215546Sopenharmony_ci /* assert(lpr->base.bind); */ 244bf215546Sopenharmony_ci 245bf215546Sopenharmony_ci if (llvmpipe_resource_is_texture(&lpr->base)) { 246bf215546Sopenharmony_ci if (lpr->base.bind & (PIPE_BIND_DISPLAY_TARGET | 247bf215546Sopenharmony_ci PIPE_BIND_SCANOUT | 248bf215546Sopenharmony_ci PIPE_BIND_SHARED)) { 249bf215546Sopenharmony_ci /* displayable surface */ 250bf215546Sopenharmony_ci if (!llvmpipe_displaytarget_layout(screen, lpr, map_front_private)) 251bf215546Sopenharmony_ci goto fail; 252bf215546Sopenharmony_ci } 253bf215546Sopenharmony_ci else { 254bf215546Sopenharmony_ci /* texture map */ 255bf215546Sopenharmony_ci if (!llvmpipe_texture_layout(screen, lpr, alloc_backing)) 256bf215546Sopenharmony_ci goto fail; 257bf215546Sopenharmony_ci } 258bf215546Sopenharmony_ci } 259bf215546Sopenharmony_ci else { 260bf215546Sopenharmony_ci /* other data (vertex buffer, const buffer, etc) */ 261bf215546Sopenharmony_ci const uint bytes = templat->width0; 262bf215546Sopenharmony_ci assert(util_format_get_blocksize(templat->format) == 1); 263bf215546Sopenharmony_ci assert(templat->height0 == 1); 264bf215546Sopenharmony_ci assert(templat->depth0 == 1); 265bf215546Sopenharmony_ci assert(templat->last_level == 0); 266bf215546Sopenharmony_ci /* 267bf215546Sopenharmony_ci * Reserve some extra storage since if we'd render to a buffer we 268bf215546Sopenharmony_ci * read/write always LP_RASTER_BLOCK_SIZE pixels, but the element 269bf215546Sopenharmony_ci * offset doesn't need to be aligned to LP_RASTER_BLOCK_SIZE. 270bf215546Sopenharmony_ci */ 271bf215546Sopenharmony_ci /* 272bf215546Sopenharmony_ci * buffers don't really have stride but it's probably safer 273bf215546Sopenharmony_ci * (for code doing same calculations for buffers and textures) 274bf215546Sopenharmony_ci * to put something sane in there. 275bf215546Sopenharmony_ci */ 276bf215546Sopenharmony_ci lpr->row_stride[0] = bytes; 277bf215546Sopenharmony_ci 278bf215546Sopenharmony_ci lpr->size_required = bytes; 279bf215546Sopenharmony_ci if (!(templat->flags & PIPE_RESOURCE_FLAG_DONT_OVER_ALLOCATE)) 280bf215546Sopenharmony_ci lpr->size_required += (LP_RASTER_BLOCK_SIZE - 1) * 4 * sizeof(float); 281bf215546Sopenharmony_ci 282bf215546Sopenharmony_ci if (alloc_backing) { 283bf215546Sopenharmony_ci lpr->data = align_malloc(lpr->size_required, 64); 284bf215546Sopenharmony_ci 285bf215546Sopenharmony_ci if (!lpr->data) 286bf215546Sopenharmony_ci goto fail; 287bf215546Sopenharmony_ci memset(lpr->data, 0, bytes); 288bf215546Sopenharmony_ci } 289bf215546Sopenharmony_ci } 290bf215546Sopenharmony_ci 291bf215546Sopenharmony_ci lpr->id = id_counter++; 292bf215546Sopenharmony_ci 293bf215546Sopenharmony_ci#ifdef DEBUG 294bf215546Sopenharmony_ci mtx_lock(&resource_list_mutex); 295bf215546Sopenharmony_ci list_addtail(&lpr->list, &resource_list.list); 296bf215546Sopenharmony_ci mtx_unlock(&resource_list_mutex); 297bf215546Sopenharmony_ci#endif 298bf215546Sopenharmony_ci 299bf215546Sopenharmony_ci return &lpr->base; 300bf215546Sopenharmony_ci 301bf215546Sopenharmony_ci fail: 302bf215546Sopenharmony_ci FREE(lpr); 303bf215546Sopenharmony_ci return NULL; 304bf215546Sopenharmony_ci} 305bf215546Sopenharmony_ci 306bf215546Sopenharmony_cistatic struct pipe_resource * 307bf215546Sopenharmony_cillvmpipe_resource_create_front(struct pipe_screen *_screen, 308bf215546Sopenharmony_ci const struct pipe_resource *templat, 309bf215546Sopenharmony_ci const void *map_front_private) 310bf215546Sopenharmony_ci{ 311bf215546Sopenharmony_ci return llvmpipe_resource_create_all(_screen, templat, map_front_private, true); 312bf215546Sopenharmony_ci} 313bf215546Sopenharmony_ci 314bf215546Sopenharmony_cistatic struct pipe_resource * 315bf215546Sopenharmony_cillvmpipe_resource_create(struct pipe_screen *_screen, 316bf215546Sopenharmony_ci const struct pipe_resource *templat) 317bf215546Sopenharmony_ci{ 318bf215546Sopenharmony_ci return llvmpipe_resource_create_front(_screen, templat, NULL); 319bf215546Sopenharmony_ci} 320bf215546Sopenharmony_ci 321bf215546Sopenharmony_cistatic struct pipe_resource * 322bf215546Sopenharmony_cillvmpipe_resource_create_unbacked(struct pipe_screen *_screen, 323bf215546Sopenharmony_ci const struct pipe_resource *templat, 324bf215546Sopenharmony_ci uint64_t *size_required) 325bf215546Sopenharmony_ci{ 326bf215546Sopenharmony_ci struct pipe_resource *pt; 327bf215546Sopenharmony_ci struct llvmpipe_resource *lpr; 328bf215546Sopenharmony_ci pt = llvmpipe_resource_create_all(_screen, templat, NULL, false); 329bf215546Sopenharmony_ci if (!pt) 330bf215546Sopenharmony_ci return pt; 331bf215546Sopenharmony_ci lpr = llvmpipe_resource(pt); 332bf215546Sopenharmony_ci lpr->backable = true; 333bf215546Sopenharmony_ci *size_required = lpr->size_required; 334bf215546Sopenharmony_ci return pt; 335bf215546Sopenharmony_ci} 336bf215546Sopenharmony_ci 337bf215546Sopenharmony_cistatic struct pipe_memory_object * 338bf215546Sopenharmony_cillvmpipe_memobj_create_from_handle(struct pipe_screen *pscreen, 339bf215546Sopenharmony_ci struct winsys_handle *handle, 340bf215546Sopenharmony_ci bool dedicated) 341bf215546Sopenharmony_ci{ 342bf215546Sopenharmony_ci#ifdef PIPE_MEMORY_FD 343bf215546Sopenharmony_ci struct llvmpipe_memory_object *memobj = CALLOC_STRUCT(llvmpipe_memory_object); 344bf215546Sopenharmony_ci 345bf215546Sopenharmony_ci if (handle->type == WINSYS_HANDLE_TYPE_FD && 346bf215546Sopenharmony_ci pscreen->import_memory_fd(pscreen, handle->handle, &memobj->data, &memobj->size)) { 347bf215546Sopenharmony_ci return &memobj->b; 348bf215546Sopenharmony_ci } 349bf215546Sopenharmony_ci free(memobj); 350bf215546Sopenharmony_ci#endif 351bf215546Sopenharmony_ci return NULL; 352bf215546Sopenharmony_ci} 353bf215546Sopenharmony_ci 354bf215546Sopenharmony_cistatic void 355bf215546Sopenharmony_cillvmpipe_memobj_destroy(struct pipe_screen *pscreen, 356bf215546Sopenharmony_ci struct pipe_memory_object *memobj) 357bf215546Sopenharmony_ci{ 358bf215546Sopenharmony_ci if (!memobj) 359bf215546Sopenharmony_ci return; 360bf215546Sopenharmony_ci struct llvmpipe_memory_object *lpmo = llvmpipe_memory_object(memobj); 361bf215546Sopenharmony_ci#ifdef PIPE_MEMORY_FD 362bf215546Sopenharmony_ci pscreen->free_memory_fd(pscreen, lpmo->data); 363bf215546Sopenharmony_ci#endif 364bf215546Sopenharmony_ci free(lpmo); 365bf215546Sopenharmony_ci} 366bf215546Sopenharmony_ci 367bf215546Sopenharmony_cistatic struct pipe_resource * 368bf215546Sopenharmony_cillvmpipe_resource_from_memobj(struct pipe_screen *pscreen, 369bf215546Sopenharmony_ci const struct pipe_resource *templat, 370bf215546Sopenharmony_ci struct pipe_memory_object *memobj, 371bf215546Sopenharmony_ci uint64_t offset) 372bf215546Sopenharmony_ci{ 373bf215546Sopenharmony_ci if (!memobj) 374bf215546Sopenharmony_ci return NULL; 375bf215546Sopenharmony_ci struct llvmpipe_screen *screen = llvmpipe_screen(pscreen); 376bf215546Sopenharmony_ci struct llvmpipe_memory_object *lpmo = llvmpipe_memory_object(memobj); 377bf215546Sopenharmony_ci struct llvmpipe_resource *lpr = CALLOC_STRUCT(llvmpipe_resource); 378bf215546Sopenharmony_ci lpr->base = *templat; 379bf215546Sopenharmony_ci 380bf215546Sopenharmony_ci lpr->screen = screen; 381bf215546Sopenharmony_ci pipe_reference_init(&lpr->base.reference, 1); 382bf215546Sopenharmony_ci lpr->base.screen = &screen->base; 383bf215546Sopenharmony_ci 384bf215546Sopenharmony_ci if (llvmpipe_resource_is_texture(&lpr->base)) { 385bf215546Sopenharmony_ci /* texture map */ 386bf215546Sopenharmony_ci if (!llvmpipe_texture_layout(screen, lpr, false)) 387bf215546Sopenharmony_ci goto fail; 388bf215546Sopenharmony_ci if(lpmo->size < lpr->size_required) 389bf215546Sopenharmony_ci goto fail; 390bf215546Sopenharmony_ci lpr->tex_data = lpmo->data; 391bf215546Sopenharmony_ci } 392bf215546Sopenharmony_ci else { 393bf215546Sopenharmony_ci /* other data (vertex buffer, const buffer, etc) */ 394bf215546Sopenharmony_ci const uint bytes = templat->width0; 395bf215546Sopenharmony_ci assert(util_format_get_blocksize(templat->format) == 1); 396bf215546Sopenharmony_ci assert(templat->height0 == 1); 397bf215546Sopenharmony_ci assert(templat->depth0 == 1); 398bf215546Sopenharmony_ci assert(templat->last_level == 0); 399bf215546Sopenharmony_ci /* 400bf215546Sopenharmony_ci * Reserve some extra storage since if we'd render to a buffer we 401bf215546Sopenharmony_ci * read/write always LP_RASTER_BLOCK_SIZE pixels, but the element 402bf215546Sopenharmony_ci * offset doesn't need to be aligned to LP_RASTER_BLOCK_SIZE. 403bf215546Sopenharmony_ci */ 404bf215546Sopenharmony_ci /* 405bf215546Sopenharmony_ci * buffers don't really have stride but it's probably safer 406bf215546Sopenharmony_ci * (for code doing same calculations for buffers and textures) 407bf215546Sopenharmony_ci * to put something reasonable in there. 408bf215546Sopenharmony_ci */ 409bf215546Sopenharmony_ci lpr->row_stride[0] = bytes; 410bf215546Sopenharmony_ci 411bf215546Sopenharmony_ci lpr->size_required = bytes; 412bf215546Sopenharmony_ci if (!(templat->flags & PIPE_RESOURCE_FLAG_DONT_OVER_ALLOCATE)) 413bf215546Sopenharmony_ci lpr->size_required += (LP_RASTER_BLOCK_SIZE - 1) * 4 * sizeof(float); 414bf215546Sopenharmony_ci 415bf215546Sopenharmony_ci if(lpmo->size < lpr->size_required) 416bf215546Sopenharmony_ci goto fail; 417bf215546Sopenharmony_ci lpr->data = lpmo->data; 418bf215546Sopenharmony_ci } 419bf215546Sopenharmony_ci lpr->id = id_counter++; 420bf215546Sopenharmony_ci lpr->imported_memory = true; 421bf215546Sopenharmony_ci 422bf215546Sopenharmony_ci#ifdef DEBUG 423bf215546Sopenharmony_ci mtx_lock(&resource_list_mutex); 424bf215546Sopenharmony_ci list_addtail(&lpr->list, &resource_list.list); 425bf215546Sopenharmony_ci mtx_unlock(&resource_list_mutex); 426bf215546Sopenharmony_ci#endif 427bf215546Sopenharmony_ci 428bf215546Sopenharmony_ci return &lpr->base; 429bf215546Sopenharmony_ci 430bf215546Sopenharmony_cifail: 431bf215546Sopenharmony_ci free(lpr); 432bf215546Sopenharmony_ci return NULL; 433bf215546Sopenharmony_ci} 434bf215546Sopenharmony_ci 435bf215546Sopenharmony_cistatic void 436bf215546Sopenharmony_cillvmpipe_resource_destroy(struct pipe_screen *pscreen, 437bf215546Sopenharmony_ci struct pipe_resource *pt) 438bf215546Sopenharmony_ci{ 439bf215546Sopenharmony_ci struct llvmpipe_screen *screen = llvmpipe_screen(pscreen); 440bf215546Sopenharmony_ci struct llvmpipe_resource *lpr = llvmpipe_resource(pt); 441bf215546Sopenharmony_ci 442bf215546Sopenharmony_ci if (!lpr->backable && !lpr->user_ptr) { 443bf215546Sopenharmony_ci if (lpr->dt) { 444bf215546Sopenharmony_ci /* display target */ 445bf215546Sopenharmony_ci struct sw_winsys *winsys = screen->winsys; 446bf215546Sopenharmony_ci winsys->displaytarget_destroy(winsys, lpr->dt); 447bf215546Sopenharmony_ci } 448bf215546Sopenharmony_ci else if (llvmpipe_resource_is_texture(pt)) { 449bf215546Sopenharmony_ci /* free linear image data */ 450bf215546Sopenharmony_ci if (lpr->tex_data) { 451bf215546Sopenharmony_ci if (!lpr->imported_memory) 452bf215546Sopenharmony_ci align_free(lpr->tex_data); 453bf215546Sopenharmony_ci lpr->tex_data = NULL; 454bf215546Sopenharmony_ci } 455bf215546Sopenharmony_ci } 456bf215546Sopenharmony_ci else if (lpr->data) { 457bf215546Sopenharmony_ci if (!lpr->imported_memory) 458bf215546Sopenharmony_ci align_free(lpr->data); 459bf215546Sopenharmony_ci } 460bf215546Sopenharmony_ci } 461bf215546Sopenharmony_ci#ifdef DEBUG 462bf215546Sopenharmony_ci mtx_lock(&resource_list_mutex); 463bf215546Sopenharmony_ci if (!list_is_empty(&lpr->list)) 464bf215546Sopenharmony_ci list_del(&lpr->list); 465bf215546Sopenharmony_ci mtx_unlock(&resource_list_mutex); 466bf215546Sopenharmony_ci#endif 467bf215546Sopenharmony_ci 468bf215546Sopenharmony_ci FREE(lpr); 469bf215546Sopenharmony_ci} 470bf215546Sopenharmony_ci 471bf215546Sopenharmony_ci 472bf215546Sopenharmony_ci/** 473bf215546Sopenharmony_ci * Map a resource for read/write. 474bf215546Sopenharmony_ci */ 475bf215546Sopenharmony_civoid * 476bf215546Sopenharmony_cillvmpipe_resource_map(struct pipe_resource *resource, 477bf215546Sopenharmony_ci unsigned level, 478bf215546Sopenharmony_ci unsigned layer, 479bf215546Sopenharmony_ci enum lp_texture_usage tex_usage) 480bf215546Sopenharmony_ci{ 481bf215546Sopenharmony_ci struct llvmpipe_resource *lpr = llvmpipe_resource(resource); 482bf215546Sopenharmony_ci uint8_t *map; 483bf215546Sopenharmony_ci 484bf215546Sopenharmony_ci assert(level < LP_MAX_TEXTURE_LEVELS); 485bf215546Sopenharmony_ci assert(layer < (u_minify(resource->depth0, level) + resource->array_size - 1)); 486bf215546Sopenharmony_ci 487bf215546Sopenharmony_ci assert(tex_usage == LP_TEX_USAGE_READ || 488bf215546Sopenharmony_ci tex_usage == LP_TEX_USAGE_READ_WRITE || 489bf215546Sopenharmony_ci tex_usage == LP_TEX_USAGE_WRITE_ALL); 490bf215546Sopenharmony_ci 491bf215546Sopenharmony_ci if (lpr->dt) { 492bf215546Sopenharmony_ci /* display target */ 493bf215546Sopenharmony_ci struct llvmpipe_screen *screen = lpr->screen; 494bf215546Sopenharmony_ci struct sw_winsys *winsys = screen->winsys; 495bf215546Sopenharmony_ci unsigned dt_usage; 496bf215546Sopenharmony_ci 497bf215546Sopenharmony_ci if (tex_usage == LP_TEX_USAGE_READ) { 498bf215546Sopenharmony_ci dt_usage = PIPE_MAP_READ; 499bf215546Sopenharmony_ci } 500bf215546Sopenharmony_ci else { 501bf215546Sopenharmony_ci dt_usage = PIPE_MAP_READ_WRITE; 502bf215546Sopenharmony_ci } 503bf215546Sopenharmony_ci 504bf215546Sopenharmony_ci assert(level == 0); 505bf215546Sopenharmony_ci assert(layer == 0); 506bf215546Sopenharmony_ci 507bf215546Sopenharmony_ci /* FIXME: keep map count? */ 508bf215546Sopenharmony_ci map = winsys->displaytarget_map(winsys, lpr->dt, dt_usage); 509bf215546Sopenharmony_ci 510bf215546Sopenharmony_ci /* install this linear image in texture data structure */ 511bf215546Sopenharmony_ci lpr->tex_data = map; 512bf215546Sopenharmony_ci 513bf215546Sopenharmony_ci return map; 514bf215546Sopenharmony_ci } 515bf215546Sopenharmony_ci else if (llvmpipe_resource_is_texture(resource)) { 516bf215546Sopenharmony_ci 517bf215546Sopenharmony_ci map = llvmpipe_get_texture_image_address(lpr, layer, level); 518bf215546Sopenharmony_ci return map; 519bf215546Sopenharmony_ci } 520bf215546Sopenharmony_ci else { 521bf215546Sopenharmony_ci return lpr->data; 522bf215546Sopenharmony_ci } 523bf215546Sopenharmony_ci} 524bf215546Sopenharmony_ci 525bf215546Sopenharmony_ci 526bf215546Sopenharmony_ci/** 527bf215546Sopenharmony_ci * Unmap a resource. 528bf215546Sopenharmony_ci */ 529bf215546Sopenharmony_civoid 530bf215546Sopenharmony_cillvmpipe_resource_unmap(struct pipe_resource *resource, 531bf215546Sopenharmony_ci unsigned level, 532bf215546Sopenharmony_ci unsigned layer) 533bf215546Sopenharmony_ci{ 534bf215546Sopenharmony_ci struct llvmpipe_resource *lpr = llvmpipe_resource(resource); 535bf215546Sopenharmony_ci 536bf215546Sopenharmony_ci if (lpr->dt) { 537bf215546Sopenharmony_ci /* display target */ 538bf215546Sopenharmony_ci struct llvmpipe_screen *lp_screen = lpr->screen; 539bf215546Sopenharmony_ci struct sw_winsys *winsys = lp_screen->winsys; 540bf215546Sopenharmony_ci 541bf215546Sopenharmony_ci assert(level == 0); 542bf215546Sopenharmony_ci assert(layer == 0); 543bf215546Sopenharmony_ci 544bf215546Sopenharmony_ci winsys->displaytarget_unmap(winsys, lpr->dt); 545bf215546Sopenharmony_ci } 546bf215546Sopenharmony_ci} 547bf215546Sopenharmony_ci 548bf215546Sopenharmony_ci 549bf215546Sopenharmony_civoid * 550bf215546Sopenharmony_cillvmpipe_resource_data(struct pipe_resource *resource) 551bf215546Sopenharmony_ci{ 552bf215546Sopenharmony_ci struct llvmpipe_resource *lpr = llvmpipe_resource(resource); 553bf215546Sopenharmony_ci 554bf215546Sopenharmony_ci assert(!llvmpipe_resource_is_texture(resource)); 555bf215546Sopenharmony_ci 556bf215546Sopenharmony_ci return lpr->data; 557bf215546Sopenharmony_ci} 558bf215546Sopenharmony_ci 559bf215546Sopenharmony_ci 560bf215546Sopenharmony_cistatic struct pipe_resource * 561bf215546Sopenharmony_cillvmpipe_resource_from_handle(struct pipe_screen *_screen, 562bf215546Sopenharmony_ci const struct pipe_resource *template, 563bf215546Sopenharmony_ci struct winsys_handle *whandle, 564bf215546Sopenharmony_ci unsigned usage) 565bf215546Sopenharmony_ci{ 566bf215546Sopenharmony_ci struct llvmpipe_screen *screen = llvmpipe_screen(_screen); 567bf215546Sopenharmony_ci struct sw_winsys *winsys = screen->winsys; 568bf215546Sopenharmony_ci struct llvmpipe_resource *lpr; 569bf215546Sopenharmony_ci 570bf215546Sopenharmony_ci /* XXX Seems like from_handled depth textures doesn't work that well */ 571bf215546Sopenharmony_ci 572bf215546Sopenharmony_ci lpr = CALLOC_STRUCT(llvmpipe_resource); 573bf215546Sopenharmony_ci if (!lpr) { 574bf215546Sopenharmony_ci goto no_lpr; 575bf215546Sopenharmony_ci } 576bf215546Sopenharmony_ci 577bf215546Sopenharmony_ci lpr->base = *template; 578bf215546Sopenharmony_ci lpr->screen = screen; 579bf215546Sopenharmony_ci pipe_reference_init(&lpr->base.reference, 1); 580bf215546Sopenharmony_ci lpr->base.screen = _screen; 581bf215546Sopenharmony_ci 582bf215546Sopenharmony_ci /* 583bf215546Sopenharmony_ci * Looks like unaligned displaytargets work just fine, 584bf215546Sopenharmony_ci * at least sampler/render ones. 585bf215546Sopenharmony_ci */ 586bf215546Sopenharmony_ci#if 0 587bf215546Sopenharmony_ci assert(lpr->base.width0 == width); 588bf215546Sopenharmony_ci assert(lpr->base.height0 == height); 589bf215546Sopenharmony_ci#endif 590bf215546Sopenharmony_ci 591bf215546Sopenharmony_ci lpr->dt = winsys->displaytarget_from_handle(winsys, 592bf215546Sopenharmony_ci template, 593bf215546Sopenharmony_ci whandle, 594bf215546Sopenharmony_ci &lpr->row_stride[0]); 595bf215546Sopenharmony_ci if (!lpr->dt) { 596bf215546Sopenharmony_ci goto no_dt; 597bf215546Sopenharmony_ci } 598bf215546Sopenharmony_ci 599bf215546Sopenharmony_ci lpr->id = id_counter++; 600bf215546Sopenharmony_ci 601bf215546Sopenharmony_ci#ifdef DEBUG 602bf215546Sopenharmony_ci mtx_lock(&resource_list_mutex); 603bf215546Sopenharmony_ci list_addtail(&lpr->list, &resource_list.list); 604bf215546Sopenharmony_ci mtx_unlock(&resource_list_mutex); 605bf215546Sopenharmony_ci#endif 606bf215546Sopenharmony_ci 607bf215546Sopenharmony_ci return &lpr->base; 608bf215546Sopenharmony_ci 609bf215546Sopenharmony_cino_dt: 610bf215546Sopenharmony_ci FREE(lpr); 611bf215546Sopenharmony_cino_lpr: 612bf215546Sopenharmony_ci return NULL; 613bf215546Sopenharmony_ci} 614bf215546Sopenharmony_ci 615bf215546Sopenharmony_ci 616bf215546Sopenharmony_cistatic bool 617bf215546Sopenharmony_cillvmpipe_resource_get_handle(struct pipe_screen *screen, 618bf215546Sopenharmony_ci struct pipe_context *ctx, 619bf215546Sopenharmony_ci struct pipe_resource *pt, 620bf215546Sopenharmony_ci struct winsys_handle *whandle, 621bf215546Sopenharmony_ci unsigned usage) 622bf215546Sopenharmony_ci{ 623bf215546Sopenharmony_ci struct sw_winsys *winsys = llvmpipe_screen(screen)->winsys; 624bf215546Sopenharmony_ci struct llvmpipe_resource *lpr = llvmpipe_resource(pt); 625bf215546Sopenharmony_ci 626bf215546Sopenharmony_ci assert(lpr->dt); 627bf215546Sopenharmony_ci if (!lpr->dt) 628bf215546Sopenharmony_ci return false; 629bf215546Sopenharmony_ci 630bf215546Sopenharmony_ci return winsys->displaytarget_get_handle(winsys, lpr->dt, whandle); 631bf215546Sopenharmony_ci} 632bf215546Sopenharmony_ci 633bf215546Sopenharmony_cistatic struct pipe_resource * 634bf215546Sopenharmony_cillvmpipe_resource_from_user_memory(struct pipe_screen *_screen, 635bf215546Sopenharmony_ci const struct pipe_resource *resource, 636bf215546Sopenharmony_ci void *user_memory) 637bf215546Sopenharmony_ci{ 638bf215546Sopenharmony_ci struct llvmpipe_screen *screen = llvmpipe_screen(_screen); 639bf215546Sopenharmony_ci struct llvmpipe_resource *lpr; 640bf215546Sopenharmony_ci 641bf215546Sopenharmony_ci lpr = CALLOC_STRUCT(llvmpipe_resource); 642bf215546Sopenharmony_ci if (!lpr) { 643bf215546Sopenharmony_ci return NULL; 644bf215546Sopenharmony_ci } 645bf215546Sopenharmony_ci 646bf215546Sopenharmony_ci lpr->base = *resource; 647bf215546Sopenharmony_ci lpr->screen = screen; 648bf215546Sopenharmony_ci pipe_reference_init(&lpr->base.reference, 1); 649bf215546Sopenharmony_ci lpr->base.screen = _screen; 650bf215546Sopenharmony_ci 651bf215546Sopenharmony_ci if (llvmpipe_resource_is_texture(&lpr->base)) { 652bf215546Sopenharmony_ci if (!llvmpipe_texture_layout(screen, lpr, false)) 653bf215546Sopenharmony_ci goto fail; 654bf215546Sopenharmony_ci 655bf215546Sopenharmony_ci lpr->tex_data = user_memory; 656bf215546Sopenharmony_ci } else 657bf215546Sopenharmony_ci lpr->data = user_memory; 658bf215546Sopenharmony_ci lpr->user_ptr = true; 659bf215546Sopenharmony_ci#ifdef DEBUG 660bf215546Sopenharmony_ci mtx_lock(&resource_list_mutex); 661bf215546Sopenharmony_ci list_addtail(&lpr->list, &resource_list.list); 662bf215546Sopenharmony_ci mtx_unlock(&resource_list_mutex); 663bf215546Sopenharmony_ci#endif 664bf215546Sopenharmony_ci return &lpr->base; 665bf215546Sopenharmony_cifail: 666bf215546Sopenharmony_ci FREE(lpr); 667bf215546Sopenharmony_ci return NULL; 668bf215546Sopenharmony_ci} 669bf215546Sopenharmony_ci 670bf215546Sopenharmony_civoid * 671bf215546Sopenharmony_cillvmpipe_transfer_map_ms( struct pipe_context *pipe, 672bf215546Sopenharmony_ci struct pipe_resource *resource, 673bf215546Sopenharmony_ci unsigned level, 674bf215546Sopenharmony_ci unsigned usage, 675bf215546Sopenharmony_ci unsigned sample, 676bf215546Sopenharmony_ci const struct pipe_box *box, 677bf215546Sopenharmony_ci struct pipe_transfer **transfer ) 678bf215546Sopenharmony_ci{ 679bf215546Sopenharmony_ci struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); 680bf215546Sopenharmony_ci struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen); 681bf215546Sopenharmony_ci struct llvmpipe_resource *lpr = llvmpipe_resource(resource); 682bf215546Sopenharmony_ci struct llvmpipe_transfer *lpt; 683bf215546Sopenharmony_ci struct pipe_transfer *pt; 684bf215546Sopenharmony_ci ubyte *map; 685bf215546Sopenharmony_ci enum pipe_format format; 686bf215546Sopenharmony_ci enum lp_texture_usage tex_usage; 687bf215546Sopenharmony_ci const char *mode; 688bf215546Sopenharmony_ci 689bf215546Sopenharmony_ci assert(resource); 690bf215546Sopenharmony_ci assert(level <= resource->last_level); 691bf215546Sopenharmony_ci 692bf215546Sopenharmony_ci /* 693bf215546Sopenharmony_ci * Transfers, like other pipe operations, must happen in order, so flush the 694bf215546Sopenharmony_ci * context if necessary. 695bf215546Sopenharmony_ci */ 696bf215546Sopenharmony_ci if (!(usage & PIPE_MAP_UNSYNCHRONIZED)) { 697bf215546Sopenharmony_ci boolean read_only = !(usage & PIPE_MAP_WRITE); 698bf215546Sopenharmony_ci boolean do_not_block = !!(usage & PIPE_MAP_DONTBLOCK); 699bf215546Sopenharmony_ci if (!llvmpipe_flush_resource(pipe, resource, 700bf215546Sopenharmony_ci level, 701bf215546Sopenharmony_ci read_only, 702bf215546Sopenharmony_ci TRUE, /* cpu_access */ 703bf215546Sopenharmony_ci do_not_block, 704bf215546Sopenharmony_ci __FUNCTION__)) { 705bf215546Sopenharmony_ci /* 706bf215546Sopenharmony_ci * It would have blocked, but gallium frontend requested no to. 707bf215546Sopenharmony_ci */ 708bf215546Sopenharmony_ci assert(do_not_block); 709bf215546Sopenharmony_ci return NULL; 710bf215546Sopenharmony_ci } 711bf215546Sopenharmony_ci } 712bf215546Sopenharmony_ci 713bf215546Sopenharmony_ci /* Check if we're mapping a current constant buffer */ 714bf215546Sopenharmony_ci if ((usage & PIPE_MAP_WRITE) && 715bf215546Sopenharmony_ci (resource->bind & PIPE_BIND_CONSTANT_BUFFER)) { 716bf215546Sopenharmony_ci unsigned i; 717bf215546Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(llvmpipe->constants[PIPE_SHADER_FRAGMENT]); ++i) { 718bf215546Sopenharmony_ci if (resource == llvmpipe->constants[PIPE_SHADER_FRAGMENT][i].buffer) { 719bf215546Sopenharmony_ci /* constants may have changed */ 720bf215546Sopenharmony_ci llvmpipe->dirty |= LP_NEW_FS_CONSTANTS; 721bf215546Sopenharmony_ci break; 722bf215546Sopenharmony_ci } 723bf215546Sopenharmony_ci } 724bf215546Sopenharmony_ci } 725bf215546Sopenharmony_ci 726bf215546Sopenharmony_ci lpt = CALLOC_STRUCT(llvmpipe_transfer); 727bf215546Sopenharmony_ci if (!lpt) 728bf215546Sopenharmony_ci return NULL; 729bf215546Sopenharmony_ci pt = &lpt->base; 730bf215546Sopenharmony_ci pipe_resource_reference(&pt->resource, resource); 731bf215546Sopenharmony_ci pt->box = *box; 732bf215546Sopenharmony_ci pt->level = level; 733bf215546Sopenharmony_ci pt->stride = lpr->row_stride[level]; 734bf215546Sopenharmony_ci pt->layer_stride = lpr->img_stride[level]; 735bf215546Sopenharmony_ci pt->usage = usage; 736bf215546Sopenharmony_ci *transfer = pt; 737bf215546Sopenharmony_ci 738bf215546Sopenharmony_ci assert(level < LP_MAX_TEXTURE_LEVELS); 739bf215546Sopenharmony_ci 740bf215546Sopenharmony_ci /* 741bf215546Sopenharmony_ci printf("tex_transfer_map(%d, %d %d x %d of %d x %d, usage %d )\n", 742bf215546Sopenharmony_ci transfer->x, transfer->y, transfer->width, transfer->height, 743bf215546Sopenharmony_ci transfer->texture->width0, 744bf215546Sopenharmony_ci transfer->texture->height0, 745bf215546Sopenharmony_ci transfer->usage); 746bf215546Sopenharmony_ci */ 747bf215546Sopenharmony_ci 748bf215546Sopenharmony_ci if (usage == PIPE_MAP_READ) { 749bf215546Sopenharmony_ci tex_usage = LP_TEX_USAGE_READ; 750bf215546Sopenharmony_ci mode = "read"; 751bf215546Sopenharmony_ci } 752bf215546Sopenharmony_ci else { 753bf215546Sopenharmony_ci tex_usage = LP_TEX_USAGE_READ_WRITE; 754bf215546Sopenharmony_ci mode = "read/write"; 755bf215546Sopenharmony_ci } 756bf215546Sopenharmony_ci 757bf215546Sopenharmony_ci if (0) { 758bf215546Sopenharmony_ci printf("transfer map tex %u mode %s\n", lpr->id, mode); 759bf215546Sopenharmony_ci } 760bf215546Sopenharmony_ci 761bf215546Sopenharmony_ci format = lpr->base.format; 762bf215546Sopenharmony_ci 763bf215546Sopenharmony_ci map = llvmpipe_resource_map(resource, 764bf215546Sopenharmony_ci level, 765bf215546Sopenharmony_ci box->z, 766bf215546Sopenharmony_ci tex_usage); 767bf215546Sopenharmony_ci 768bf215546Sopenharmony_ci 769bf215546Sopenharmony_ci /* May want to do different things here depending on read/write nature 770bf215546Sopenharmony_ci * of the map: 771bf215546Sopenharmony_ci */ 772bf215546Sopenharmony_ci if (usage & PIPE_MAP_WRITE) { 773bf215546Sopenharmony_ci /* Do something to notify sharing contexts of a texture change. 774bf215546Sopenharmony_ci */ 775bf215546Sopenharmony_ci screen->timestamp++; 776bf215546Sopenharmony_ci } 777bf215546Sopenharmony_ci 778bf215546Sopenharmony_ci map += 779bf215546Sopenharmony_ci box->y / util_format_get_blockheight(format) * pt->stride + 780bf215546Sopenharmony_ci box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); 781bf215546Sopenharmony_ci 782bf215546Sopenharmony_ci map += sample * lpr->sample_stride; 783bf215546Sopenharmony_ci return map; 784bf215546Sopenharmony_ci} 785bf215546Sopenharmony_ci 786bf215546Sopenharmony_cistatic void * 787bf215546Sopenharmony_cillvmpipe_transfer_map( struct pipe_context *pipe, 788bf215546Sopenharmony_ci struct pipe_resource *resource, 789bf215546Sopenharmony_ci unsigned level, 790bf215546Sopenharmony_ci unsigned usage, 791bf215546Sopenharmony_ci const struct pipe_box *box, 792bf215546Sopenharmony_ci struct pipe_transfer **transfer ) 793bf215546Sopenharmony_ci{ 794bf215546Sopenharmony_ci return llvmpipe_transfer_map_ms(pipe, resource, level, usage, 0, box, transfer); 795bf215546Sopenharmony_ci} 796bf215546Sopenharmony_ci 797bf215546Sopenharmony_cistatic void 798bf215546Sopenharmony_cillvmpipe_transfer_unmap(struct pipe_context *pipe, 799bf215546Sopenharmony_ci struct pipe_transfer *transfer) 800bf215546Sopenharmony_ci{ 801bf215546Sopenharmony_ci assert(transfer->resource); 802bf215546Sopenharmony_ci 803bf215546Sopenharmony_ci llvmpipe_resource_unmap(transfer->resource, 804bf215546Sopenharmony_ci transfer->level, 805bf215546Sopenharmony_ci transfer->box.z); 806bf215546Sopenharmony_ci 807bf215546Sopenharmony_ci /* Effectively do the texture_update work here - if texture images 808bf215546Sopenharmony_ci * needed post-processing to put them into hardware layout, this is 809bf215546Sopenharmony_ci * where it would happen. For llvmpipe, nothing to do. 810bf215546Sopenharmony_ci */ 811bf215546Sopenharmony_ci assert (transfer->resource); 812bf215546Sopenharmony_ci pipe_resource_reference(&transfer->resource, NULL); 813bf215546Sopenharmony_ci FREE(transfer); 814bf215546Sopenharmony_ci} 815bf215546Sopenharmony_ci 816bf215546Sopenharmony_ciunsigned int 817bf215546Sopenharmony_cillvmpipe_is_resource_referenced( struct pipe_context *pipe, 818bf215546Sopenharmony_ci struct pipe_resource *presource, 819bf215546Sopenharmony_ci unsigned level) 820bf215546Sopenharmony_ci{ 821bf215546Sopenharmony_ci struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe ); 822bf215546Sopenharmony_ci if (!(presource->bind & (PIPE_BIND_DEPTH_STENCIL | 823bf215546Sopenharmony_ci PIPE_BIND_RENDER_TARGET | 824bf215546Sopenharmony_ci PIPE_BIND_SAMPLER_VIEW | 825bf215546Sopenharmony_ci PIPE_BIND_SHADER_BUFFER | 826bf215546Sopenharmony_ci PIPE_BIND_SHADER_IMAGE))) 827bf215546Sopenharmony_ci return LP_UNREFERENCED; 828bf215546Sopenharmony_ci 829bf215546Sopenharmony_ci return lp_setup_is_resource_referenced(llvmpipe->setup, presource); 830bf215546Sopenharmony_ci} 831bf215546Sopenharmony_ci 832bf215546Sopenharmony_ci 833bf215546Sopenharmony_ci/** 834bf215546Sopenharmony_ci * Returns the largest possible alignment for a format in llvmpipe 835bf215546Sopenharmony_ci */ 836bf215546Sopenharmony_ciunsigned 837bf215546Sopenharmony_cillvmpipe_get_format_alignment( enum pipe_format format ) 838bf215546Sopenharmony_ci{ 839bf215546Sopenharmony_ci const struct util_format_description *desc = util_format_description(format); 840bf215546Sopenharmony_ci unsigned size = 0; 841bf215546Sopenharmony_ci unsigned bytes; 842bf215546Sopenharmony_ci unsigned i; 843bf215546Sopenharmony_ci 844bf215546Sopenharmony_ci for (i = 0; i < desc->nr_channels; ++i) { 845bf215546Sopenharmony_ci size += desc->channel[i].size; 846bf215546Sopenharmony_ci } 847bf215546Sopenharmony_ci 848bf215546Sopenharmony_ci bytes = size / 8; 849bf215546Sopenharmony_ci 850bf215546Sopenharmony_ci if (!util_is_power_of_two_or_zero(bytes)) { 851bf215546Sopenharmony_ci bytes /= desc->nr_channels; 852bf215546Sopenharmony_ci } 853bf215546Sopenharmony_ci 854bf215546Sopenharmony_ci if (bytes % 2 || bytes < 1) { 855bf215546Sopenharmony_ci return 1; 856bf215546Sopenharmony_ci } else { 857bf215546Sopenharmony_ci return bytes; 858bf215546Sopenharmony_ci } 859bf215546Sopenharmony_ci} 860bf215546Sopenharmony_ci 861bf215546Sopenharmony_ci 862bf215546Sopenharmony_ci/** 863bf215546Sopenharmony_ci * Create buffer which wraps user-space data. 864bf215546Sopenharmony_ci * XXX unreachable. 865bf215546Sopenharmony_ci */ 866bf215546Sopenharmony_cistruct pipe_resource * 867bf215546Sopenharmony_cillvmpipe_user_buffer_create(struct pipe_screen *screen, 868bf215546Sopenharmony_ci void *ptr, 869bf215546Sopenharmony_ci unsigned bytes, 870bf215546Sopenharmony_ci unsigned bind_flags) 871bf215546Sopenharmony_ci{ 872bf215546Sopenharmony_ci struct llvmpipe_resource *buffer; 873bf215546Sopenharmony_ci 874bf215546Sopenharmony_ci buffer = CALLOC_STRUCT(llvmpipe_resource); 875bf215546Sopenharmony_ci if (!buffer) 876bf215546Sopenharmony_ci return NULL; 877bf215546Sopenharmony_ci 878bf215546Sopenharmony_ci buffer->screen = llvmpipe_screen(screen); 879bf215546Sopenharmony_ci pipe_reference_init(&buffer->base.reference, 1); 880bf215546Sopenharmony_ci buffer->base.screen = screen; 881bf215546Sopenharmony_ci buffer->base.format = PIPE_FORMAT_R8_UNORM; /* ?? */ 882bf215546Sopenharmony_ci buffer->base.bind = bind_flags; 883bf215546Sopenharmony_ci buffer->base.usage = PIPE_USAGE_IMMUTABLE; 884bf215546Sopenharmony_ci buffer->base.flags = 0; 885bf215546Sopenharmony_ci buffer->base.width0 = bytes; 886bf215546Sopenharmony_ci buffer->base.height0 = 1; 887bf215546Sopenharmony_ci buffer->base.depth0 = 1; 888bf215546Sopenharmony_ci buffer->base.array_size = 1; 889bf215546Sopenharmony_ci buffer->user_ptr = true; 890bf215546Sopenharmony_ci buffer->data = ptr; 891bf215546Sopenharmony_ci 892bf215546Sopenharmony_ci return &buffer->base; 893bf215546Sopenharmony_ci} 894bf215546Sopenharmony_ci 895bf215546Sopenharmony_ci 896bf215546Sopenharmony_ci/** 897bf215546Sopenharmony_ci * Compute size (in bytes) need to store a texture image / mipmap level, 898bf215546Sopenharmony_ci * for just one cube face, one array layer or one 3D texture slice 899bf215546Sopenharmony_ci */ 900bf215546Sopenharmony_cistatic unsigned 901bf215546Sopenharmony_citex_image_face_size(const struct llvmpipe_resource *lpr, unsigned level) 902bf215546Sopenharmony_ci{ 903bf215546Sopenharmony_ci return lpr->img_stride[level]; 904bf215546Sopenharmony_ci} 905bf215546Sopenharmony_ci 906bf215546Sopenharmony_ci 907bf215546Sopenharmony_ci/** 908bf215546Sopenharmony_ci * Return pointer to a 2D texture image/face/slice. 909bf215546Sopenharmony_ci * No tiled/linear conversion is done. 910bf215546Sopenharmony_ci */ 911bf215546Sopenharmony_ciubyte * 912bf215546Sopenharmony_cillvmpipe_get_texture_image_address(struct llvmpipe_resource *lpr, 913bf215546Sopenharmony_ci unsigned face_slice, unsigned level) 914bf215546Sopenharmony_ci{ 915bf215546Sopenharmony_ci unsigned offset; 916bf215546Sopenharmony_ci 917bf215546Sopenharmony_ci assert(llvmpipe_resource_is_texture(&lpr->base)); 918bf215546Sopenharmony_ci 919bf215546Sopenharmony_ci offset = lpr->mip_offsets[level]; 920bf215546Sopenharmony_ci 921bf215546Sopenharmony_ci if (face_slice > 0) 922bf215546Sopenharmony_ci offset += face_slice * tex_image_face_size(lpr, level); 923bf215546Sopenharmony_ci 924bf215546Sopenharmony_ci return (ubyte *) lpr->tex_data + offset; 925bf215546Sopenharmony_ci} 926bf215546Sopenharmony_ci 927bf215546Sopenharmony_ci 928bf215546Sopenharmony_ci/** 929bf215546Sopenharmony_ci * Return size of resource in bytes 930bf215546Sopenharmony_ci */ 931bf215546Sopenharmony_ciunsigned 932bf215546Sopenharmony_cillvmpipe_resource_size(const struct pipe_resource *resource) 933bf215546Sopenharmony_ci{ 934bf215546Sopenharmony_ci const struct llvmpipe_resource *lpr = llvmpipe_resource_const(resource); 935bf215546Sopenharmony_ci unsigned size = 0; 936bf215546Sopenharmony_ci 937bf215546Sopenharmony_ci if (llvmpipe_resource_is_texture(resource)) { 938bf215546Sopenharmony_ci /* Note this will always return 0 for displaytarget resources */ 939bf215546Sopenharmony_ci size = lpr->total_alloc_size; 940bf215546Sopenharmony_ci } 941bf215546Sopenharmony_ci else { 942bf215546Sopenharmony_ci size = resource->width0; 943bf215546Sopenharmony_ci } 944bf215546Sopenharmony_ci return size; 945bf215546Sopenharmony_ci} 946bf215546Sopenharmony_ci 947bf215546Sopenharmony_cistatic void 948bf215546Sopenharmony_cillvmpipe_memory_barrier(struct pipe_context *pipe, 949bf215546Sopenharmony_ci unsigned flags) 950bf215546Sopenharmony_ci{ 951bf215546Sopenharmony_ci /* this may be an overly large hammer for this nut. */ 952bf215546Sopenharmony_ci llvmpipe_finish(pipe, "barrier"); 953bf215546Sopenharmony_ci} 954bf215546Sopenharmony_ci 955bf215546Sopenharmony_cistatic struct pipe_memory_allocation *llvmpipe_allocate_memory(struct pipe_screen *screen, uint64_t size) 956bf215546Sopenharmony_ci{ 957bf215546Sopenharmony_ci uint64_t alignment; 958bf215546Sopenharmony_ci if (!os_get_page_size(&alignment)) 959bf215546Sopenharmony_ci alignment = 256; 960bf215546Sopenharmony_ci return os_malloc_aligned(size, alignment); 961bf215546Sopenharmony_ci} 962bf215546Sopenharmony_ci 963bf215546Sopenharmony_cistatic void llvmpipe_free_memory(struct pipe_screen *screen, 964bf215546Sopenharmony_ci struct pipe_memory_allocation *pmem) 965bf215546Sopenharmony_ci{ 966bf215546Sopenharmony_ci os_free_aligned(pmem); 967bf215546Sopenharmony_ci} 968bf215546Sopenharmony_ci 969bf215546Sopenharmony_ci#ifdef PIPE_MEMORY_FD 970bf215546Sopenharmony_ci 971bf215546Sopenharmony_cistatic const char *driver_id = "llvmpipe" MESA_GIT_SHA1; 972bf215546Sopenharmony_ci 973bf215546Sopenharmony_cistatic struct pipe_memory_allocation *llvmpipe_allocate_memory_fd(struct pipe_screen *screen, uint64_t size, int *fd) 974bf215546Sopenharmony_ci{ 975bf215546Sopenharmony_ci uint64_t alignment; 976bf215546Sopenharmony_ci if (!os_get_page_size(&alignment)) 977bf215546Sopenharmony_ci alignment = 256; 978bf215546Sopenharmony_ci return os_malloc_aligned_fd(size, alignment, fd, "llvmpipe memory fd", driver_id); 979bf215546Sopenharmony_ci} 980bf215546Sopenharmony_ci 981bf215546Sopenharmony_cistatic bool llvmpipe_import_memory_fd(struct pipe_screen *screen, int fd, struct pipe_memory_allocation **ptr, uint64_t *size) 982bf215546Sopenharmony_ci{ 983bf215546Sopenharmony_ci return os_import_memory_fd(fd, (void**)ptr, size, driver_id); 984bf215546Sopenharmony_ci} 985bf215546Sopenharmony_ci 986bf215546Sopenharmony_cistatic void llvmpipe_free_memory_fd(struct pipe_screen *screen, 987bf215546Sopenharmony_ci struct pipe_memory_allocation *pmem) 988bf215546Sopenharmony_ci{ 989bf215546Sopenharmony_ci os_free_fd(pmem); 990bf215546Sopenharmony_ci} 991bf215546Sopenharmony_ci 992bf215546Sopenharmony_ci#endif 993bf215546Sopenharmony_ci 994bf215546Sopenharmony_cistatic bool llvmpipe_resource_bind_backing(struct pipe_screen *screen, 995bf215546Sopenharmony_ci struct pipe_resource *pt, 996bf215546Sopenharmony_ci struct pipe_memory_allocation *pmem, 997bf215546Sopenharmony_ci uint64_t offset) 998bf215546Sopenharmony_ci{ 999bf215546Sopenharmony_ci struct llvmpipe_resource *lpr = llvmpipe_resource(pt); 1000bf215546Sopenharmony_ci 1001bf215546Sopenharmony_ci if (!lpr->backable) 1002bf215546Sopenharmony_ci return FALSE; 1003bf215546Sopenharmony_ci 1004bf215546Sopenharmony_ci if (llvmpipe_resource_is_texture(&lpr->base)) { 1005bf215546Sopenharmony_ci if (lpr->size_required > LP_MAX_TEXTURE_SIZE) 1006bf215546Sopenharmony_ci return FALSE; 1007bf215546Sopenharmony_ci 1008bf215546Sopenharmony_ci lpr->tex_data = (char *)pmem + offset; 1009bf215546Sopenharmony_ci } else 1010bf215546Sopenharmony_ci lpr->data = (char *)pmem + offset; 1011bf215546Sopenharmony_ci lpr->backing_offset = offset; 1012bf215546Sopenharmony_ci 1013bf215546Sopenharmony_ci return TRUE; 1014bf215546Sopenharmony_ci} 1015bf215546Sopenharmony_ci 1016bf215546Sopenharmony_cistatic void *llvmpipe_map_memory(struct pipe_screen *screen, 1017bf215546Sopenharmony_ci struct pipe_memory_allocation *pmem) 1018bf215546Sopenharmony_ci{ 1019bf215546Sopenharmony_ci return pmem; 1020bf215546Sopenharmony_ci} 1021bf215546Sopenharmony_ci 1022bf215546Sopenharmony_cistatic void llvmpipe_unmap_memory(struct pipe_screen *screen, 1023bf215546Sopenharmony_ci struct pipe_memory_allocation *pmem) 1024bf215546Sopenharmony_ci{ 1025bf215546Sopenharmony_ci} 1026bf215546Sopenharmony_ci 1027bf215546Sopenharmony_ci#ifdef DEBUG 1028bf215546Sopenharmony_civoid 1029bf215546Sopenharmony_cillvmpipe_print_resources(void) 1030bf215546Sopenharmony_ci{ 1031bf215546Sopenharmony_ci struct llvmpipe_resource *lpr; 1032bf215546Sopenharmony_ci unsigned n = 0, total = 0; 1033bf215546Sopenharmony_ci 1034bf215546Sopenharmony_ci debug_printf("LLVMPIPE: current resources:\n"); 1035bf215546Sopenharmony_ci mtx_lock(&resource_list_mutex); 1036bf215546Sopenharmony_ci LIST_FOR_EACH_ENTRY(lpr, &resource_list.list, list) { 1037bf215546Sopenharmony_ci unsigned size = llvmpipe_resource_size(&lpr->base); 1038bf215546Sopenharmony_ci debug_printf("resource %u at %p, size %ux%ux%u: %u bytes, refcount %u\n", 1039bf215546Sopenharmony_ci lpr->id, (void *) lpr, 1040bf215546Sopenharmony_ci lpr->base.width0, lpr->base.height0, lpr->base.depth0, 1041bf215546Sopenharmony_ci size, lpr->base.reference.count); 1042bf215546Sopenharmony_ci total += size; 1043bf215546Sopenharmony_ci n++; 1044bf215546Sopenharmony_ci } 1045bf215546Sopenharmony_ci mtx_unlock(&resource_list_mutex); 1046bf215546Sopenharmony_ci debug_printf("LLVMPIPE: total size of %u resources: %u\n", n, total); 1047bf215546Sopenharmony_ci} 1048bf215546Sopenharmony_ci#endif 1049bf215546Sopenharmony_ci 1050bf215546Sopenharmony_cistatic void 1051bf215546Sopenharmony_cillvmpipe_get_resource_info(struct pipe_screen *screen, 1052bf215546Sopenharmony_ci struct pipe_resource *resource, 1053bf215546Sopenharmony_ci unsigned *stride, 1054bf215546Sopenharmony_ci unsigned *offset) 1055bf215546Sopenharmony_ci{ 1056bf215546Sopenharmony_ci struct llvmpipe_resource *lpr = llvmpipe_resource(resource); 1057bf215546Sopenharmony_ci 1058bf215546Sopenharmony_ci *stride = lpr->row_stride[0]; 1059bf215546Sopenharmony_ci *offset = 0; 1060bf215546Sopenharmony_ci} 1061bf215546Sopenharmony_ci 1062bf215546Sopenharmony_cistatic bool 1063bf215546Sopenharmony_cillvmpipe_resource_get_param(struct pipe_screen *screen, 1064bf215546Sopenharmony_ci struct pipe_context *context, 1065bf215546Sopenharmony_ci struct pipe_resource *resource, 1066bf215546Sopenharmony_ci unsigned plane, 1067bf215546Sopenharmony_ci unsigned layer, 1068bf215546Sopenharmony_ci unsigned level, 1069bf215546Sopenharmony_ci enum pipe_resource_param param, 1070bf215546Sopenharmony_ci unsigned handle_usage, 1071bf215546Sopenharmony_ci uint64_t *value) 1072bf215546Sopenharmony_ci{ 1073bf215546Sopenharmony_ci struct llvmpipe_resource *lpr = llvmpipe_resource(resource); 1074bf215546Sopenharmony_ci struct winsys_handle whandle; 1075bf215546Sopenharmony_ci 1076bf215546Sopenharmony_ci switch (param) { 1077bf215546Sopenharmony_ci case PIPE_RESOURCE_PARAM_NPLANES: 1078bf215546Sopenharmony_ci *value = 1; 1079bf215546Sopenharmony_ci return true; 1080bf215546Sopenharmony_ci case PIPE_RESOURCE_PARAM_STRIDE: 1081bf215546Sopenharmony_ci *value = lpr->row_stride[level]; 1082bf215546Sopenharmony_ci return true; 1083bf215546Sopenharmony_ci case PIPE_RESOURCE_PARAM_OFFSET: 1084bf215546Sopenharmony_ci *value = lpr->mip_offsets[level] + (lpr->img_stride[level] * layer); 1085bf215546Sopenharmony_ci return true; 1086bf215546Sopenharmony_ci case PIPE_RESOURCE_PARAM_LAYER_STRIDE: 1087bf215546Sopenharmony_ci *value = lpr->img_stride[level]; 1088bf215546Sopenharmony_ci return true; 1089bf215546Sopenharmony_ci#ifndef _WIN32 1090bf215546Sopenharmony_ci case PIPE_RESOURCE_PARAM_MODIFIER: 1091bf215546Sopenharmony_ci *value = DRM_FORMAT_MOD_INVALID; 1092bf215546Sopenharmony_ci return true; 1093bf215546Sopenharmony_ci#endif 1094bf215546Sopenharmony_ci case PIPE_RESOURCE_PARAM_HANDLE_TYPE_SHARED: 1095bf215546Sopenharmony_ci case PIPE_RESOURCE_PARAM_HANDLE_TYPE_KMS: 1096bf215546Sopenharmony_ci case PIPE_RESOURCE_PARAM_HANDLE_TYPE_FD: 1097bf215546Sopenharmony_ci if (!lpr->dt) 1098bf215546Sopenharmony_ci return false; 1099bf215546Sopenharmony_ci 1100bf215546Sopenharmony_ci memset(&whandle, 0, sizeof(whandle)); 1101bf215546Sopenharmony_ci if (param == PIPE_RESOURCE_PARAM_HANDLE_TYPE_SHARED) 1102bf215546Sopenharmony_ci whandle.type = WINSYS_HANDLE_TYPE_SHARED; 1103bf215546Sopenharmony_ci else if (param == PIPE_RESOURCE_PARAM_HANDLE_TYPE_KMS) 1104bf215546Sopenharmony_ci whandle.type = WINSYS_HANDLE_TYPE_KMS; 1105bf215546Sopenharmony_ci else if (param == PIPE_RESOURCE_PARAM_HANDLE_TYPE_FD) 1106bf215546Sopenharmony_ci whandle.type = WINSYS_HANDLE_TYPE_FD; 1107bf215546Sopenharmony_ci 1108bf215546Sopenharmony_ci if (!llvmpipe_resource_get_handle(screen, context, resource, &whandle, handle_usage)) 1109bf215546Sopenharmony_ci return false; 1110bf215546Sopenharmony_ci *value = (uint64_t)(uintptr_t)whandle.handle; 1111bf215546Sopenharmony_ci return true; 1112bf215546Sopenharmony_ci default: 1113bf215546Sopenharmony_ci break; 1114bf215546Sopenharmony_ci } 1115bf215546Sopenharmony_ci assert(0); 1116bf215546Sopenharmony_ci *value = 0; 1117bf215546Sopenharmony_ci return false; 1118bf215546Sopenharmony_ci} 1119bf215546Sopenharmony_ci 1120bf215546Sopenharmony_civoid 1121bf215546Sopenharmony_cillvmpipe_init_screen_resource_funcs(struct pipe_screen *screen) 1122bf215546Sopenharmony_ci{ 1123bf215546Sopenharmony_ci#ifdef DEBUG 1124bf215546Sopenharmony_ci /* init linked list for tracking resources */ 1125bf215546Sopenharmony_ci { 1126bf215546Sopenharmony_ci static boolean first_call = TRUE; 1127bf215546Sopenharmony_ci if (first_call) { 1128bf215546Sopenharmony_ci memset(&resource_list, 0, sizeof(resource_list)); 1129bf215546Sopenharmony_ci list_inithead(&resource_list.list); 1130bf215546Sopenharmony_ci first_call = FALSE; 1131bf215546Sopenharmony_ci } 1132bf215546Sopenharmony_ci } 1133bf215546Sopenharmony_ci#endif 1134bf215546Sopenharmony_ci 1135bf215546Sopenharmony_ci screen->resource_create = llvmpipe_resource_create; 1136bf215546Sopenharmony_ci/* screen->resource_create_front = llvmpipe_resource_create_front; */ 1137bf215546Sopenharmony_ci screen->resource_destroy = llvmpipe_resource_destroy; 1138bf215546Sopenharmony_ci screen->resource_from_handle = llvmpipe_resource_from_handle; 1139bf215546Sopenharmony_ci screen->resource_from_memobj = llvmpipe_resource_from_memobj; 1140bf215546Sopenharmony_ci screen->resource_get_handle = llvmpipe_resource_get_handle; 1141bf215546Sopenharmony_ci screen->can_create_resource = llvmpipe_can_create_resource; 1142bf215546Sopenharmony_ci 1143bf215546Sopenharmony_ci screen->resource_create_unbacked = llvmpipe_resource_create_unbacked; 1144bf215546Sopenharmony_ci 1145bf215546Sopenharmony_ci screen->memobj_create_from_handle = llvmpipe_memobj_create_from_handle; 1146bf215546Sopenharmony_ci screen->memobj_destroy = llvmpipe_memobj_destroy; 1147bf215546Sopenharmony_ci 1148bf215546Sopenharmony_ci screen->resource_get_info = llvmpipe_get_resource_info; 1149bf215546Sopenharmony_ci screen->resource_get_param = llvmpipe_resource_get_param; 1150bf215546Sopenharmony_ci screen->resource_from_user_memory = llvmpipe_resource_from_user_memory; 1151bf215546Sopenharmony_ci screen->allocate_memory = llvmpipe_allocate_memory; 1152bf215546Sopenharmony_ci screen->free_memory = llvmpipe_free_memory; 1153bf215546Sopenharmony_ci#ifdef PIPE_MEMORY_FD 1154bf215546Sopenharmony_ci screen->allocate_memory_fd = llvmpipe_allocate_memory_fd; 1155bf215546Sopenharmony_ci screen->import_memory_fd = llvmpipe_import_memory_fd; 1156bf215546Sopenharmony_ci screen->free_memory_fd = llvmpipe_free_memory_fd; 1157bf215546Sopenharmony_ci#endif 1158bf215546Sopenharmony_ci screen->map_memory = llvmpipe_map_memory; 1159bf215546Sopenharmony_ci screen->unmap_memory = llvmpipe_unmap_memory; 1160bf215546Sopenharmony_ci 1161bf215546Sopenharmony_ci screen->resource_bind_backing = llvmpipe_resource_bind_backing; 1162bf215546Sopenharmony_ci} 1163bf215546Sopenharmony_ci 1164bf215546Sopenharmony_ci 1165bf215546Sopenharmony_civoid 1166bf215546Sopenharmony_cillvmpipe_init_context_resource_funcs(struct pipe_context *pipe) 1167bf215546Sopenharmony_ci{ 1168bf215546Sopenharmony_ci pipe->buffer_map = llvmpipe_transfer_map; 1169bf215546Sopenharmony_ci pipe->buffer_unmap = llvmpipe_transfer_unmap; 1170bf215546Sopenharmony_ci pipe->texture_map = llvmpipe_transfer_map; 1171bf215546Sopenharmony_ci pipe->texture_unmap = llvmpipe_transfer_unmap; 1172bf215546Sopenharmony_ci 1173bf215546Sopenharmony_ci pipe->transfer_flush_region = u_default_transfer_flush_region; 1174bf215546Sopenharmony_ci pipe->buffer_subdata = u_default_buffer_subdata; 1175bf215546Sopenharmony_ci pipe->texture_subdata = u_default_texture_subdata; 1176bf215546Sopenharmony_ci 1177bf215546Sopenharmony_ci pipe->memory_barrier = llvmpipe_memory_barrier; 1178bf215546Sopenharmony_ci} 1179