1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright (c) 2012-2015 Etnaviv Project 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sub license, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the 12bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 13bf215546Sopenharmony_ci * of the Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 22bf215546Sopenharmony_ci * 23bf215546Sopenharmony_ci * Authors: 24bf215546Sopenharmony_ci * Wladimir J. van der Laan <laanwj@gmail.com> 25bf215546Sopenharmony_ci */ 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ci#include "etnaviv_resource.h" 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ci#include "hw/common.xml.h" 30bf215546Sopenharmony_ci 31bf215546Sopenharmony_ci#include "etnaviv_context.h" 32bf215546Sopenharmony_ci#include "etnaviv_debug.h" 33bf215546Sopenharmony_ci#include "etnaviv_screen.h" 34bf215546Sopenharmony_ci#include "etnaviv_translate.h" 35bf215546Sopenharmony_ci 36bf215546Sopenharmony_ci#include "util/hash_table.h" 37bf215546Sopenharmony_ci#include "util/u_inlines.h" 38bf215546Sopenharmony_ci#include "util/u_memory.h" 39bf215546Sopenharmony_ci 40bf215546Sopenharmony_ci#include "drm-uapi/drm_fourcc.h" 41bf215546Sopenharmony_ci 42bf215546Sopenharmony_cistatic enum etna_surface_layout modifier_to_layout(uint64_t modifier) 43bf215546Sopenharmony_ci{ 44bf215546Sopenharmony_ci switch (modifier) { 45bf215546Sopenharmony_ci case DRM_FORMAT_MOD_VIVANTE_TILED: 46bf215546Sopenharmony_ci return ETNA_LAYOUT_TILED; 47bf215546Sopenharmony_ci case DRM_FORMAT_MOD_VIVANTE_SUPER_TILED: 48bf215546Sopenharmony_ci return ETNA_LAYOUT_SUPER_TILED; 49bf215546Sopenharmony_ci case DRM_FORMAT_MOD_VIVANTE_SPLIT_TILED: 50bf215546Sopenharmony_ci return ETNA_LAYOUT_MULTI_TILED; 51bf215546Sopenharmony_ci case DRM_FORMAT_MOD_VIVANTE_SPLIT_SUPER_TILED: 52bf215546Sopenharmony_ci return ETNA_LAYOUT_MULTI_SUPERTILED; 53bf215546Sopenharmony_ci case DRM_FORMAT_MOD_LINEAR: 54bf215546Sopenharmony_ci default: 55bf215546Sopenharmony_ci return ETNA_LAYOUT_LINEAR; 56bf215546Sopenharmony_ci } 57bf215546Sopenharmony_ci} 58bf215546Sopenharmony_ci 59bf215546Sopenharmony_cistatic uint64_t layout_to_modifier(enum etna_surface_layout layout) 60bf215546Sopenharmony_ci{ 61bf215546Sopenharmony_ci switch (layout) { 62bf215546Sopenharmony_ci case ETNA_LAYOUT_TILED: 63bf215546Sopenharmony_ci return DRM_FORMAT_MOD_VIVANTE_TILED; 64bf215546Sopenharmony_ci case ETNA_LAYOUT_SUPER_TILED: 65bf215546Sopenharmony_ci return DRM_FORMAT_MOD_VIVANTE_SUPER_TILED; 66bf215546Sopenharmony_ci case ETNA_LAYOUT_MULTI_TILED: 67bf215546Sopenharmony_ci return DRM_FORMAT_MOD_VIVANTE_SPLIT_TILED; 68bf215546Sopenharmony_ci case ETNA_LAYOUT_MULTI_SUPERTILED: 69bf215546Sopenharmony_ci return DRM_FORMAT_MOD_VIVANTE_SPLIT_SUPER_TILED; 70bf215546Sopenharmony_ci case ETNA_LAYOUT_LINEAR: 71bf215546Sopenharmony_ci return DRM_FORMAT_MOD_LINEAR; 72bf215546Sopenharmony_ci default: 73bf215546Sopenharmony_ci return DRM_FORMAT_MOD_INVALID; 74bf215546Sopenharmony_ci } 75bf215546Sopenharmony_ci} 76bf215546Sopenharmony_ci 77bf215546Sopenharmony_ci/* A tile is 4x4 pixels, having 'screen->specs.bits_per_tile' of tile status. 78bf215546Sopenharmony_ci * So, in a buffer of N pixels, there are N / (4 * 4) tiles. 79bf215546Sopenharmony_ci * We need N * screen->specs.bits_per_tile / (4 * 4) bits of tile status, or 80bf215546Sopenharmony_ci * N * screen->specs.bits_per_tile / (4 * 4 * 8) bytes. 81bf215546Sopenharmony_ci */ 82bf215546Sopenharmony_cibool 83bf215546Sopenharmony_cietna_screen_resource_alloc_ts(struct pipe_screen *pscreen, 84bf215546Sopenharmony_ci struct etna_resource *rsc) 85bf215546Sopenharmony_ci{ 86bf215546Sopenharmony_ci struct etna_screen *screen = etna_screen(pscreen); 87bf215546Sopenharmony_ci size_t rt_ts_size, ts_layer_stride; 88bf215546Sopenharmony_ci uint8_t ts_mode = TS_MODE_128B; 89bf215546Sopenharmony_ci int8_t ts_compress_fmt; 90bf215546Sopenharmony_ci 91bf215546Sopenharmony_ci assert(!rsc->ts_bo); 92bf215546Sopenharmony_ci 93bf215546Sopenharmony_ci /* pre-v4 compression is largely useless, so disable it when not wanted for MSAA 94bf215546Sopenharmony_ci * v4 compression can be enabled everywhere without any known drawback, 95bf215546Sopenharmony_ci * except that in-place resolve must go through a slower path 96bf215546Sopenharmony_ci */ 97bf215546Sopenharmony_ci ts_compress_fmt = (screen->specs.v4_compression || rsc->base.nr_samples > 1) ? 98bf215546Sopenharmony_ci translate_ts_format(rsc->base.format) : -1; 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_ci /* enable 256B ts mode with compression, as it improves performance 101bf215546Sopenharmony_ci * the size of the resource might also determine if we want to use it or not 102bf215546Sopenharmony_ci */ 103bf215546Sopenharmony_ci if (VIV_FEATURE(screen, chipMinorFeatures6, CACHE128B256BPERLINE) && 104bf215546Sopenharmony_ci ts_compress_fmt >= 0 && 105bf215546Sopenharmony_ci (rsc->layout != ETNA_LAYOUT_LINEAR || 106bf215546Sopenharmony_ci rsc->levels[0].stride % 256 == 0) ) 107bf215546Sopenharmony_ci ts_mode = TS_MODE_256B; 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_ci ts_layer_stride = align(DIV_ROUND_UP(rsc->levels[0].layer_stride, 110bf215546Sopenharmony_ci etna_screen_get_tile_size(screen, ts_mode) * 111bf215546Sopenharmony_ci 8 / screen->specs.bits_per_tile), 112bf215546Sopenharmony_ci 0x100 * screen->specs.pixel_pipes); 113bf215546Sopenharmony_ci rt_ts_size = ts_layer_stride * rsc->base.array_size; 114bf215546Sopenharmony_ci if (rt_ts_size == 0) 115bf215546Sopenharmony_ci return true; 116bf215546Sopenharmony_ci 117bf215546Sopenharmony_ci DBG_F(ETNA_DBG_RESOURCE_MSGS, "%p: Allocating tile status of size %zu", 118bf215546Sopenharmony_ci rsc, rt_ts_size); 119bf215546Sopenharmony_ci 120bf215546Sopenharmony_ci struct etna_bo *rt_ts; 121bf215546Sopenharmony_ci rt_ts = etna_bo_new(screen->dev, rt_ts_size, DRM_ETNA_GEM_CACHE_WC); 122bf215546Sopenharmony_ci 123bf215546Sopenharmony_ci if (unlikely(!rt_ts)) { 124bf215546Sopenharmony_ci BUG("Problem allocating tile status for resource"); 125bf215546Sopenharmony_ci return false; 126bf215546Sopenharmony_ci } 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_ci rsc->ts_bo = rt_ts; 129bf215546Sopenharmony_ci rsc->levels[0].ts_offset = 0; 130bf215546Sopenharmony_ci rsc->levels[0].ts_layer_stride = ts_layer_stride; 131bf215546Sopenharmony_ci rsc->levels[0].ts_size = rt_ts_size; 132bf215546Sopenharmony_ci rsc->levels[0].ts_mode = ts_mode; 133bf215546Sopenharmony_ci rsc->levels[0].ts_compress_fmt = ts_compress_fmt; 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci return true; 136bf215546Sopenharmony_ci} 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_cistatic bool 139bf215546Sopenharmony_cietna_screen_can_create_resource(struct pipe_screen *pscreen, 140bf215546Sopenharmony_ci const struct pipe_resource *templat) 141bf215546Sopenharmony_ci{ 142bf215546Sopenharmony_ci struct etna_screen *screen = etna_screen(pscreen); 143bf215546Sopenharmony_ci if (!translate_samples_to_xyscale(templat->nr_samples, NULL, NULL)) 144bf215546Sopenharmony_ci return false; 145bf215546Sopenharmony_ci 146bf215546Sopenharmony_ci /* templat->bind is not set here, so we must use the minimum sizes */ 147bf215546Sopenharmony_ci uint max_size = 148bf215546Sopenharmony_ci MIN2(screen->specs.max_rendertarget_size, screen->specs.max_texture_size); 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_ci if (templat->width0 > max_size || templat->height0 > max_size) 151bf215546Sopenharmony_ci return false; 152bf215546Sopenharmony_ci 153bf215546Sopenharmony_ci return true; 154bf215546Sopenharmony_ci} 155bf215546Sopenharmony_ci 156bf215546Sopenharmony_cistatic unsigned 157bf215546Sopenharmony_cisetup_miptree(struct etna_resource *rsc, unsigned paddingX, unsigned paddingY, 158bf215546Sopenharmony_ci unsigned msaa_xscale, unsigned msaa_yscale) 159bf215546Sopenharmony_ci{ 160bf215546Sopenharmony_ci struct pipe_resource *prsc = &rsc->base; 161bf215546Sopenharmony_ci unsigned level, size = 0; 162bf215546Sopenharmony_ci unsigned width = prsc->width0; 163bf215546Sopenharmony_ci unsigned height = prsc->height0; 164bf215546Sopenharmony_ci unsigned depth = prsc->depth0; 165bf215546Sopenharmony_ci 166bf215546Sopenharmony_ci for (level = 0; level <= prsc->last_level; level++) { 167bf215546Sopenharmony_ci struct etna_resource_level *mip = &rsc->levels[level]; 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_ci mip->width = width; 170bf215546Sopenharmony_ci mip->height = height; 171bf215546Sopenharmony_ci mip->depth = depth; 172bf215546Sopenharmony_ci mip->padded_width = align(width * msaa_xscale, paddingX); 173bf215546Sopenharmony_ci mip->padded_height = align(height * msaa_yscale, paddingY); 174bf215546Sopenharmony_ci mip->stride = util_format_get_stride(prsc->format, mip->padded_width); 175bf215546Sopenharmony_ci mip->offset = size; 176bf215546Sopenharmony_ci mip->layer_stride = mip->stride * util_format_get_nblocksy(prsc->format, mip->padded_height); 177bf215546Sopenharmony_ci mip->size = prsc->array_size * mip->layer_stride; 178bf215546Sopenharmony_ci 179bf215546Sopenharmony_ci /* align levels to 64 bytes to be able to render to them */ 180bf215546Sopenharmony_ci size += align(mip->size, ETNA_PE_ALIGNMENT) * depth; 181bf215546Sopenharmony_ci 182bf215546Sopenharmony_ci width = u_minify(width, 1); 183bf215546Sopenharmony_ci height = u_minify(height, 1); 184bf215546Sopenharmony_ci depth = u_minify(depth, 1); 185bf215546Sopenharmony_ci } 186bf215546Sopenharmony_ci 187bf215546Sopenharmony_ci return size; 188bf215546Sopenharmony_ci} 189bf215546Sopenharmony_ci 190bf215546Sopenharmony_ci/* Is rs alignment needed? */ 191bf215546Sopenharmony_cistatic bool is_rs_align(struct etna_screen *screen, 192bf215546Sopenharmony_ci const struct pipe_resource *tmpl) 193bf215546Sopenharmony_ci{ 194bf215546Sopenharmony_ci return screen->specs.use_blt ? false : ( 195bf215546Sopenharmony_ci VIV_FEATURE(screen, chipMinorFeatures1, TEXTURE_HALIGN) || 196bf215546Sopenharmony_ci !etna_resource_sampler_only(tmpl)); 197bf215546Sopenharmony_ci} 198bf215546Sopenharmony_ci 199bf215546Sopenharmony_ci/* Create a new resource object, using the given template info */ 200bf215546Sopenharmony_cistruct pipe_resource * 201bf215546Sopenharmony_cietna_resource_alloc(struct pipe_screen *pscreen, unsigned layout, 202bf215546Sopenharmony_ci uint64_t modifier, const struct pipe_resource *templat) 203bf215546Sopenharmony_ci{ 204bf215546Sopenharmony_ci struct etna_screen *screen = etna_screen(pscreen); 205bf215546Sopenharmony_ci struct etna_resource *rsc; 206bf215546Sopenharmony_ci unsigned size; 207bf215546Sopenharmony_ci 208bf215546Sopenharmony_ci DBG_F(ETNA_DBG_RESOURCE_MSGS, 209bf215546Sopenharmony_ci "target=%d, format=%s, %ux%ux%u, array_size=%u, " 210bf215546Sopenharmony_ci "last_level=%u, nr_samples=%u, usage=%u, bind=%x, flags=%x", 211bf215546Sopenharmony_ci templat->target, util_format_name(templat->format), templat->width0, 212bf215546Sopenharmony_ci templat->height0, templat->depth0, templat->array_size, 213bf215546Sopenharmony_ci templat->last_level, templat->nr_samples, templat->usage, 214bf215546Sopenharmony_ci templat->bind, templat->flags); 215bf215546Sopenharmony_ci 216bf215546Sopenharmony_ci /* Determine scaling for antialiasing, allow override using debug flag */ 217bf215546Sopenharmony_ci int nr_samples = templat->nr_samples; 218bf215546Sopenharmony_ci if ((templat->bind & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_DEPTH_STENCIL)) && 219bf215546Sopenharmony_ci !(templat->bind & PIPE_BIND_SAMPLER_VIEW)) { 220bf215546Sopenharmony_ci if (DBG_ENABLED(ETNA_DBG_MSAA_2X)) 221bf215546Sopenharmony_ci nr_samples = 2; 222bf215546Sopenharmony_ci if (DBG_ENABLED(ETNA_DBG_MSAA_4X)) 223bf215546Sopenharmony_ci nr_samples = 4; 224bf215546Sopenharmony_ci } 225bf215546Sopenharmony_ci 226bf215546Sopenharmony_ci int msaa_xscale = 1, msaa_yscale = 1; 227bf215546Sopenharmony_ci if (!translate_samples_to_xyscale(nr_samples, &msaa_xscale, &msaa_yscale)) { 228bf215546Sopenharmony_ci /* Number of samples not supported */ 229bf215546Sopenharmony_ci return NULL; 230bf215546Sopenharmony_ci } 231bf215546Sopenharmony_ci 232bf215546Sopenharmony_ci /* Determine needed padding (alignment of height/width) */ 233bf215546Sopenharmony_ci unsigned paddingX = 0, paddingY = 0; 234bf215546Sopenharmony_ci unsigned halign = TEXTURE_HALIGN_FOUR; 235bf215546Sopenharmony_ci if (!util_format_is_compressed(templat->format)) { 236bf215546Sopenharmony_ci /* If we have the TEXTURE_HALIGN feature, we can always align to the 237bf215546Sopenharmony_ci * resolve engine's width. If not, we must not align resources used 238bf215546Sopenharmony_ci * only for textures. If this GPU uses the BLT engine, never do RS align. 239bf215546Sopenharmony_ci */ 240bf215546Sopenharmony_ci etna_layout_multiple(layout, screen->specs.pixel_pipes, 241bf215546Sopenharmony_ci is_rs_align (screen, templat), 242bf215546Sopenharmony_ci &paddingX, &paddingY, &halign); 243bf215546Sopenharmony_ci assert(paddingX && paddingY); 244bf215546Sopenharmony_ci } else { 245bf215546Sopenharmony_ci /* Compressed textures are padded to their block size, but we don't have 246bf215546Sopenharmony_ci * to do anything special for that. */ 247bf215546Sopenharmony_ci paddingX = 1; 248bf215546Sopenharmony_ci paddingY = 1; 249bf215546Sopenharmony_ci } 250bf215546Sopenharmony_ci 251bf215546Sopenharmony_ci if (!screen->specs.use_blt && templat->target != PIPE_BUFFER && layout == ETNA_LAYOUT_LINEAR) 252bf215546Sopenharmony_ci paddingY = align(paddingY, ETNA_RS_HEIGHT_MASK + 1); 253bf215546Sopenharmony_ci 254bf215546Sopenharmony_ci rsc = CALLOC_STRUCT(etna_resource); 255bf215546Sopenharmony_ci if (!rsc) 256bf215546Sopenharmony_ci return NULL; 257bf215546Sopenharmony_ci 258bf215546Sopenharmony_ci rsc->base = *templat; 259bf215546Sopenharmony_ci rsc->base.screen = pscreen; 260bf215546Sopenharmony_ci rsc->base.nr_samples = nr_samples; 261bf215546Sopenharmony_ci rsc->layout = layout; 262bf215546Sopenharmony_ci rsc->halign = halign; 263bf215546Sopenharmony_ci rsc->explicit_flush = true; 264bf215546Sopenharmony_ci 265bf215546Sopenharmony_ci pipe_reference_init(&rsc->base.reference, 1); 266bf215546Sopenharmony_ci util_range_init(&rsc->valid_buffer_range); 267bf215546Sopenharmony_ci 268bf215546Sopenharmony_ci size = setup_miptree(rsc, paddingX, paddingY, msaa_xscale, msaa_yscale); 269bf215546Sopenharmony_ci 270bf215546Sopenharmony_ci if (unlikely(templat->bind & PIPE_BIND_SCANOUT) && screen->ro) { 271bf215546Sopenharmony_ci struct pipe_resource scanout_templat = *templat; 272bf215546Sopenharmony_ci struct winsys_handle handle; 273bf215546Sopenharmony_ci 274bf215546Sopenharmony_ci scanout_templat.width0 = align(scanout_templat.width0, paddingX); 275bf215546Sopenharmony_ci scanout_templat.height0 = align(scanout_templat.height0, paddingY); 276bf215546Sopenharmony_ci 277bf215546Sopenharmony_ci rsc->scanout = renderonly_scanout_for_resource(&scanout_templat, 278bf215546Sopenharmony_ci screen->ro, &handle); 279bf215546Sopenharmony_ci if (!rsc->scanout) { 280bf215546Sopenharmony_ci BUG("Problem allocating kms memory for resource"); 281bf215546Sopenharmony_ci goto free_rsc; 282bf215546Sopenharmony_ci } 283bf215546Sopenharmony_ci 284bf215546Sopenharmony_ci assert(handle.type == WINSYS_HANDLE_TYPE_FD); 285bf215546Sopenharmony_ci rsc->levels[0].stride = handle.stride; 286bf215546Sopenharmony_ci rsc->bo = etna_screen_bo_from_handle(pscreen, &handle); 287bf215546Sopenharmony_ci close(handle.handle); 288bf215546Sopenharmony_ci if (unlikely(!rsc->bo)) 289bf215546Sopenharmony_ci goto free_rsc; 290bf215546Sopenharmony_ci } else { 291bf215546Sopenharmony_ci uint32_t flags = DRM_ETNA_GEM_CACHE_WC; 292bf215546Sopenharmony_ci 293bf215546Sopenharmony_ci if (templat->bind & PIPE_BIND_VERTEX_BUFFER) 294bf215546Sopenharmony_ci flags |= DRM_ETNA_GEM_FORCE_MMU; 295bf215546Sopenharmony_ci 296bf215546Sopenharmony_ci rsc->bo = etna_bo_new(screen->dev, size, flags); 297bf215546Sopenharmony_ci if (unlikely(!rsc->bo)) { 298bf215546Sopenharmony_ci BUG("Problem allocating video memory for resource"); 299bf215546Sopenharmony_ci goto free_rsc; 300bf215546Sopenharmony_ci } 301bf215546Sopenharmony_ci } 302bf215546Sopenharmony_ci 303bf215546Sopenharmony_ci if (DBG_ENABLED(ETNA_DBG_ZERO)) { 304bf215546Sopenharmony_ci void *map = etna_bo_map(rsc->bo); 305bf215546Sopenharmony_ci etna_bo_cpu_prep(rsc->bo, DRM_ETNA_PREP_WRITE); 306bf215546Sopenharmony_ci memset(map, 0, size); 307bf215546Sopenharmony_ci etna_bo_cpu_fini(rsc->bo); 308bf215546Sopenharmony_ci } 309bf215546Sopenharmony_ci 310bf215546Sopenharmony_ci return &rsc->base; 311bf215546Sopenharmony_ci 312bf215546Sopenharmony_cifree_rsc: 313bf215546Sopenharmony_ci FREE(rsc); 314bf215546Sopenharmony_ci return NULL; 315bf215546Sopenharmony_ci} 316bf215546Sopenharmony_ci 317bf215546Sopenharmony_cistatic struct pipe_resource * 318bf215546Sopenharmony_cietna_resource_create(struct pipe_screen *pscreen, 319bf215546Sopenharmony_ci const struct pipe_resource *templat) 320bf215546Sopenharmony_ci{ 321bf215546Sopenharmony_ci struct etna_screen *screen = etna_screen(pscreen); 322bf215546Sopenharmony_ci unsigned layout = ETNA_LAYOUT_TILED; 323bf215546Sopenharmony_ci 324bf215546Sopenharmony_ci /* At this point we don't know if the resource will be used as a texture, 325bf215546Sopenharmony_ci * render target, or both, because gallium sets the bits whenever possible 326bf215546Sopenharmony_ci * This matters because on some GPUs (GC2000) there is no tiling that is 327bf215546Sopenharmony_ci * compatible with both TE and PE. 328bf215546Sopenharmony_ci * 329bf215546Sopenharmony_ci * We expect that depth/stencil buffers will always be used by PE (rendering), 330bf215546Sopenharmony_ci * and any other non-scanout resource will be used as a texture at some point, 331bf215546Sopenharmony_ci * So allocate a render-compatible base buffer for scanout/depthstencil buffers, 332bf215546Sopenharmony_ci * and a texture-compatible base buffer in other cases 333bf215546Sopenharmony_ci * 334bf215546Sopenharmony_ci */ 335bf215546Sopenharmony_ci if (templat->bind & PIPE_BIND_DEPTH_STENCIL) { 336bf215546Sopenharmony_ci if (screen->specs.pixel_pipes > 1 && !screen->specs.single_buffer) 337bf215546Sopenharmony_ci layout |= ETNA_LAYOUT_BIT_MULTI; 338bf215546Sopenharmony_ci if (screen->specs.can_supertile) 339bf215546Sopenharmony_ci layout |= ETNA_LAYOUT_BIT_SUPER; 340bf215546Sopenharmony_ci } else if (screen->specs.can_supertile && 341bf215546Sopenharmony_ci VIV_FEATURE(screen, chipMinorFeatures2, SUPERTILED_TEXTURE) && 342bf215546Sopenharmony_ci etna_resource_hw_tileable(screen->specs.use_blt, templat)) { 343bf215546Sopenharmony_ci layout |= ETNA_LAYOUT_BIT_SUPER; 344bf215546Sopenharmony_ci } 345bf215546Sopenharmony_ci 346bf215546Sopenharmony_ci if (/* linear base or scanout without modifier requested */ 347bf215546Sopenharmony_ci (templat->bind & (PIPE_BIND_LINEAR | PIPE_BIND_SCANOUT)) || 348bf215546Sopenharmony_ci templat->target == PIPE_BUFFER || /* buffer always linear */ 349bf215546Sopenharmony_ci /* compressed textures don't use tiling, they have their own "tiles" */ 350bf215546Sopenharmony_ci util_format_is_compressed(templat->format)) { 351bf215546Sopenharmony_ci layout = ETNA_LAYOUT_LINEAR; 352bf215546Sopenharmony_ci } 353bf215546Sopenharmony_ci 354bf215546Sopenharmony_ci /* modifier is only used for scanout surfaces, so safe to use LINEAR here */ 355bf215546Sopenharmony_ci return etna_resource_alloc(pscreen, layout, DRM_FORMAT_MOD_LINEAR, templat); 356bf215546Sopenharmony_ci} 357bf215546Sopenharmony_ci 358bf215546Sopenharmony_cienum modifier_priority { 359bf215546Sopenharmony_ci MODIFIER_PRIORITY_INVALID = 0, 360bf215546Sopenharmony_ci MODIFIER_PRIORITY_LINEAR, 361bf215546Sopenharmony_ci MODIFIER_PRIORITY_SPLIT_TILED, 362bf215546Sopenharmony_ci MODIFIER_PRIORITY_SPLIT_SUPER_TILED, 363bf215546Sopenharmony_ci MODIFIER_PRIORITY_TILED, 364bf215546Sopenharmony_ci MODIFIER_PRIORITY_SUPER_TILED, 365bf215546Sopenharmony_ci}; 366bf215546Sopenharmony_ci 367bf215546Sopenharmony_cistatic const uint64_t priority_to_modifier[] = { 368bf215546Sopenharmony_ci [MODIFIER_PRIORITY_INVALID] = DRM_FORMAT_MOD_INVALID, 369bf215546Sopenharmony_ci [MODIFIER_PRIORITY_LINEAR] = DRM_FORMAT_MOD_LINEAR, 370bf215546Sopenharmony_ci [MODIFIER_PRIORITY_SPLIT_TILED] = DRM_FORMAT_MOD_VIVANTE_SPLIT_TILED, 371bf215546Sopenharmony_ci [MODIFIER_PRIORITY_SPLIT_SUPER_TILED] = DRM_FORMAT_MOD_VIVANTE_SPLIT_SUPER_TILED, 372bf215546Sopenharmony_ci [MODIFIER_PRIORITY_TILED] = DRM_FORMAT_MOD_VIVANTE_TILED, 373bf215546Sopenharmony_ci [MODIFIER_PRIORITY_SUPER_TILED] = DRM_FORMAT_MOD_VIVANTE_SUPER_TILED, 374bf215546Sopenharmony_ci}; 375bf215546Sopenharmony_ci 376bf215546Sopenharmony_cistatic uint64_t 377bf215546Sopenharmony_ciselect_best_modifier(const struct etna_screen * screen, 378bf215546Sopenharmony_ci const uint64_t *modifiers, const unsigned count) 379bf215546Sopenharmony_ci{ 380bf215546Sopenharmony_ci enum modifier_priority prio = MODIFIER_PRIORITY_INVALID; 381bf215546Sopenharmony_ci 382bf215546Sopenharmony_ci for (int i = 0; i < count; i++) { 383bf215546Sopenharmony_ci switch (modifiers[i]) { 384bf215546Sopenharmony_ci case DRM_FORMAT_MOD_VIVANTE_SUPER_TILED: 385bf215546Sopenharmony_ci if ((screen->specs.pixel_pipes > 1 && !screen->specs.single_buffer) || 386bf215546Sopenharmony_ci !screen->specs.can_supertile) 387bf215546Sopenharmony_ci break; 388bf215546Sopenharmony_ci prio = MAX2(prio, MODIFIER_PRIORITY_SUPER_TILED); 389bf215546Sopenharmony_ci break; 390bf215546Sopenharmony_ci case DRM_FORMAT_MOD_VIVANTE_TILED: 391bf215546Sopenharmony_ci if (screen->specs.pixel_pipes > 1 && !screen->specs.single_buffer) 392bf215546Sopenharmony_ci break; 393bf215546Sopenharmony_ci prio = MAX2(prio, MODIFIER_PRIORITY_TILED); 394bf215546Sopenharmony_ci break; 395bf215546Sopenharmony_ci case DRM_FORMAT_MOD_VIVANTE_SPLIT_SUPER_TILED: 396bf215546Sopenharmony_ci if ((screen->specs.pixel_pipes < 2) || !screen->specs.can_supertile) 397bf215546Sopenharmony_ci break; 398bf215546Sopenharmony_ci prio = MAX2(prio, MODIFIER_PRIORITY_SPLIT_SUPER_TILED); 399bf215546Sopenharmony_ci break; 400bf215546Sopenharmony_ci case DRM_FORMAT_MOD_VIVANTE_SPLIT_TILED: 401bf215546Sopenharmony_ci if (screen->specs.pixel_pipes < 2) 402bf215546Sopenharmony_ci break; 403bf215546Sopenharmony_ci prio = MAX2(prio, MODIFIER_PRIORITY_SPLIT_TILED); 404bf215546Sopenharmony_ci break; 405bf215546Sopenharmony_ci case DRM_FORMAT_MOD_LINEAR: 406bf215546Sopenharmony_ci prio = MAX2(prio, MODIFIER_PRIORITY_LINEAR); 407bf215546Sopenharmony_ci break; 408bf215546Sopenharmony_ci case DRM_FORMAT_MOD_INVALID: 409bf215546Sopenharmony_ci default: 410bf215546Sopenharmony_ci break; 411bf215546Sopenharmony_ci } 412bf215546Sopenharmony_ci } 413bf215546Sopenharmony_ci 414bf215546Sopenharmony_ci return priority_to_modifier[prio]; 415bf215546Sopenharmony_ci} 416bf215546Sopenharmony_ci 417bf215546Sopenharmony_cistatic struct pipe_resource * 418bf215546Sopenharmony_cietna_resource_create_modifiers(struct pipe_screen *pscreen, 419bf215546Sopenharmony_ci const struct pipe_resource *templat, 420bf215546Sopenharmony_ci const uint64_t *modifiers, int count) 421bf215546Sopenharmony_ci{ 422bf215546Sopenharmony_ci struct etna_screen *screen = etna_screen(pscreen); 423bf215546Sopenharmony_ci struct pipe_resource tmpl = *templat; 424bf215546Sopenharmony_ci uint64_t modifier = select_best_modifier(screen, modifiers, count); 425bf215546Sopenharmony_ci 426bf215546Sopenharmony_ci if (modifier == DRM_FORMAT_MOD_INVALID) 427bf215546Sopenharmony_ci return NULL; 428bf215546Sopenharmony_ci 429bf215546Sopenharmony_ci return etna_resource_alloc(pscreen, modifier_to_layout(modifier), modifier, &tmpl); 430bf215546Sopenharmony_ci} 431bf215546Sopenharmony_ci 432bf215546Sopenharmony_cistatic void 433bf215546Sopenharmony_cietna_resource_changed(struct pipe_screen *pscreen, struct pipe_resource *prsc) 434bf215546Sopenharmony_ci{ 435bf215546Sopenharmony_ci etna_resource(prsc)->seqno++; 436bf215546Sopenharmony_ci} 437bf215546Sopenharmony_ci 438bf215546Sopenharmony_cistatic void 439bf215546Sopenharmony_cietna_resource_destroy(struct pipe_screen *pscreen, struct pipe_resource *prsc) 440bf215546Sopenharmony_ci{ 441bf215546Sopenharmony_ci struct etna_resource *rsc = etna_resource(prsc); 442bf215546Sopenharmony_ci 443bf215546Sopenharmony_ci if (rsc->bo) 444bf215546Sopenharmony_ci etna_bo_del(rsc->bo); 445bf215546Sopenharmony_ci 446bf215546Sopenharmony_ci if (rsc->ts_bo) 447bf215546Sopenharmony_ci etna_bo_del(rsc->ts_bo); 448bf215546Sopenharmony_ci 449bf215546Sopenharmony_ci if (rsc->scanout) 450bf215546Sopenharmony_ci renderonly_scanout_destroy(rsc->scanout, etna_screen(pscreen)->ro); 451bf215546Sopenharmony_ci 452bf215546Sopenharmony_ci util_range_destroy(&rsc->valid_buffer_range); 453bf215546Sopenharmony_ci 454bf215546Sopenharmony_ci pipe_resource_reference(&rsc->texture, NULL); 455bf215546Sopenharmony_ci pipe_resource_reference(&rsc->render, NULL); 456bf215546Sopenharmony_ci 457bf215546Sopenharmony_ci for (unsigned i = 0; i < ETNA_NUM_LOD; i++) 458bf215546Sopenharmony_ci FREE(rsc->levels[i].patch_offsets); 459bf215546Sopenharmony_ci 460bf215546Sopenharmony_ci FREE(rsc); 461bf215546Sopenharmony_ci} 462bf215546Sopenharmony_ci 463bf215546Sopenharmony_cistatic struct pipe_resource * 464bf215546Sopenharmony_cietna_resource_from_handle(struct pipe_screen *pscreen, 465bf215546Sopenharmony_ci const struct pipe_resource *tmpl, 466bf215546Sopenharmony_ci struct winsys_handle *handle, unsigned usage) 467bf215546Sopenharmony_ci{ 468bf215546Sopenharmony_ci struct etna_screen *screen = etna_screen(pscreen); 469bf215546Sopenharmony_ci struct etna_resource *rsc; 470bf215546Sopenharmony_ci struct etna_resource_level *level; 471bf215546Sopenharmony_ci struct pipe_resource *prsc; 472bf215546Sopenharmony_ci 473bf215546Sopenharmony_ci DBG("target=%d, format=%s, %ux%ux%u, array_size=%u, last_level=%u, " 474bf215546Sopenharmony_ci "nr_samples=%u, usage=%u, bind=%x, flags=%x", 475bf215546Sopenharmony_ci tmpl->target, util_format_name(tmpl->format), tmpl->width0, 476bf215546Sopenharmony_ci tmpl->height0, tmpl->depth0, tmpl->array_size, tmpl->last_level, 477bf215546Sopenharmony_ci tmpl->nr_samples, tmpl->usage, tmpl->bind, tmpl->flags); 478bf215546Sopenharmony_ci 479bf215546Sopenharmony_ci rsc = CALLOC_STRUCT(etna_resource); 480bf215546Sopenharmony_ci if (!rsc) 481bf215546Sopenharmony_ci return NULL; 482bf215546Sopenharmony_ci 483bf215546Sopenharmony_ci level = &rsc->levels[0]; 484bf215546Sopenharmony_ci prsc = &rsc->base; 485bf215546Sopenharmony_ci 486bf215546Sopenharmony_ci *prsc = *tmpl; 487bf215546Sopenharmony_ci 488bf215546Sopenharmony_ci pipe_reference_init(&prsc->reference, 1); 489bf215546Sopenharmony_ci util_range_init(&rsc->valid_buffer_range); 490bf215546Sopenharmony_ci prsc->screen = pscreen; 491bf215546Sopenharmony_ci 492bf215546Sopenharmony_ci rsc->bo = etna_screen_bo_from_handle(pscreen, handle); 493bf215546Sopenharmony_ci if (!rsc->bo) 494bf215546Sopenharmony_ci goto fail; 495bf215546Sopenharmony_ci 496bf215546Sopenharmony_ci rsc->seqno = 1; 497bf215546Sopenharmony_ci rsc->layout = modifier_to_layout(handle->modifier); 498bf215546Sopenharmony_ci rsc->halign = TEXTURE_HALIGN_FOUR; 499bf215546Sopenharmony_ci 500bf215546Sopenharmony_ci if (usage & PIPE_HANDLE_USAGE_EXPLICIT_FLUSH) 501bf215546Sopenharmony_ci rsc->explicit_flush = true; 502bf215546Sopenharmony_ci 503bf215546Sopenharmony_ci level->width = tmpl->width0; 504bf215546Sopenharmony_ci level->height = tmpl->height0; 505bf215546Sopenharmony_ci level->depth = tmpl->depth0; 506bf215546Sopenharmony_ci level->stride = handle->stride; 507bf215546Sopenharmony_ci level->offset = handle->offset; 508bf215546Sopenharmony_ci 509bf215546Sopenharmony_ci /* Determine padding of the imported resource. */ 510bf215546Sopenharmony_ci unsigned paddingX = 0, paddingY = 0; 511bf215546Sopenharmony_ci etna_layout_multiple(rsc->layout, screen->specs.pixel_pipes, 512bf215546Sopenharmony_ci is_rs_align(screen, tmpl), 513bf215546Sopenharmony_ci &paddingX, &paddingY, &rsc->halign); 514bf215546Sopenharmony_ci 515bf215546Sopenharmony_ci if (!screen->specs.use_blt && rsc->layout == ETNA_LAYOUT_LINEAR) 516bf215546Sopenharmony_ci paddingY = align(paddingY, ETNA_RS_HEIGHT_MASK + 1); 517bf215546Sopenharmony_ci level->padded_width = align(level->width, paddingX); 518bf215546Sopenharmony_ci level->padded_height = align(level->height, paddingY); 519bf215546Sopenharmony_ci 520bf215546Sopenharmony_ci level->layer_stride = level->stride * util_format_get_nblocksy(prsc->format, 521bf215546Sopenharmony_ci level->padded_height); 522bf215546Sopenharmony_ci level->size = level->layer_stride; 523bf215546Sopenharmony_ci 524bf215546Sopenharmony_ci /* The DDX must give us a BO which conforms to our padding size. 525bf215546Sopenharmony_ci * The stride of the BO must be greater or equal to our padded 526bf215546Sopenharmony_ci * stride. The size of the BO must accomodate the padded height. */ 527bf215546Sopenharmony_ci if (level->stride < util_format_get_stride(tmpl->format, level->padded_width)) { 528bf215546Sopenharmony_ci BUG("BO stride %u is too small for RS engine width padding (%zu, format %s)", 529bf215546Sopenharmony_ci level->stride, util_format_get_stride(tmpl->format, level->padded_width), 530bf215546Sopenharmony_ci util_format_name(tmpl->format)); 531bf215546Sopenharmony_ci goto fail; 532bf215546Sopenharmony_ci } 533bf215546Sopenharmony_ci if (etna_bo_size(rsc->bo) < level->stride * level->padded_height) { 534bf215546Sopenharmony_ci BUG("BO size %u is too small for RS engine height padding (%u, format %s)", 535bf215546Sopenharmony_ci etna_bo_size(rsc->bo), level->stride * level->padded_height, 536bf215546Sopenharmony_ci util_format_name(tmpl->format)); 537bf215546Sopenharmony_ci goto fail; 538bf215546Sopenharmony_ci } 539bf215546Sopenharmony_ci 540bf215546Sopenharmony_ci if (screen->ro) { 541bf215546Sopenharmony_ci struct pipe_resource *imp_prsc = prsc; 542bf215546Sopenharmony_ci do { 543bf215546Sopenharmony_ci etna_resource(imp_prsc)->scanout = 544bf215546Sopenharmony_ci renderonly_create_gpu_import_for_resource(imp_prsc, screen->ro, 545bf215546Sopenharmony_ci NULL); 546bf215546Sopenharmony_ci /* failure is expected for scanout incompatible buffers */ 547bf215546Sopenharmony_ci } while ((imp_prsc = imp_prsc->next)); 548bf215546Sopenharmony_ci } 549bf215546Sopenharmony_ci 550bf215546Sopenharmony_ci return prsc; 551bf215546Sopenharmony_ci 552bf215546Sopenharmony_cifail: 553bf215546Sopenharmony_ci etna_resource_destroy(pscreen, prsc); 554bf215546Sopenharmony_ci 555bf215546Sopenharmony_ci return NULL; 556bf215546Sopenharmony_ci} 557bf215546Sopenharmony_ci 558bf215546Sopenharmony_cistatic bool 559bf215546Sopenharmony_cietna_resource_get_handle(struct pipe_screen *pscreen, 560bf215546Sopenharmony_ci struct pipe_context *pctx, 561bf215546Sopenharmony_ci struct pipe_resource *prsc, 562bf215546Sopenharmony_ci struct winsys_handle *handle, unsigned usage) 563bf215546Sopenharmony_ci{ 564bf215546Sopenharmony_ci struct etna_screen *screen = etna_screen(pscreen); 565bf215546Sopenharmony_ci struct etna_resource *rsc = etna_resource(prsc); 566bf215546Sopenharmony_ci struct renderonly_scanout *scanout; 567bf215546Sopenharmony_ci 568bf215546Sopenharmony_ci if (handle->plane) { 569bf215546Sopenharmony_ci struct pipe_resource *cur = prsc; 570bf215546Sopenharmony_ci 571bf215546Sopenharmony_ci for (int i = 0; i < handle->plane; i++) { 572bf215546Sopenharmony_ci cur = cur->next; 573bf215546Sopenharmony_ci if (!cur) 574bf215546Sopenharmony_ci return false; 575bf215546Sopenharmony_ci } 576bf215546Sopenharmony_ci rsc = etna_resource(cur); 577bf215546Sopenharmony_ci } 578bf215546Sopenharmony_ci 579bf215546Sopenharmony_ci /* Scanout is always attached to the base resource */ 580bf215546Sopenharmony_ci scanout = rsc->scanout; 581bf215546Sopenharmony_ci 582bf215546Sopenharmony_ci handle->stride = rsc->levels[0].stride; 583bf215546Sopenharmony_ci handle->offset = rsc->levels[0].offset; 584bf215546Sopenharmony_ci handle->modifier = layout_to_modifier(rsc->layout); 585bf215546Sopenharmony_ci 586bf215546Sopenharmony_ci if (!(usage & PIPE_HANDLE_USAGE_EXPLICIT_FLUSH)) 587bf215546Sopenharmony_ci rsc->explicit_flush = false; 588bf215546Sopenharmony_ci 589bf215546Sopenharmony_ci if (handle->type == WINSYS_HANDLE_TYPE_SHARED) { 590bf215546Sopenharmony_ci return etna_bo_get_name(rsc->bo, &handle->handle) == 0; 591bf215546Sopenharmony_ci } else if (handle->type == WINSYS_HANDLE_TYPE_KMS) { 592bf215546Sopenharmony_ci if (screen->ro) { 593bf215546Sopenharmony_ci return renderonly_get_handle(scanout, handle); 594bf215546Sopenharmony_ci } else { 595bf215546Sopenharmony_ci handle->handle = etna_bo_handle(rsc->bo); 596bf215546Sopenharmony_ci return true; 597bf215546Sopenharmony_ci } 598bf215546Sopenharmony_ci } else if (handle->type == WINSYS_HANDLE_TYPE_FD) { 599bf215546Sopenharmony_ci handle->handle = etna_bo_dmabuf(rsc->bo); 600bf215546Sopenharmony_ci return true; 601bf215546Sopenharmony_ci } else { 602bf215546Sopenharmony_ci return false; 603bf215546Sopenharmony_ci } 604bf215546Sopenharmony_ci} 605bf215546Sopenharmony_ci 606bf215546Sopenharmony_cistatic bool 607bf215546Sopenharmony_cietna_resource_get_param(struct pipe_screen *pscreen, 608bf215546Sopenharmony_ci struct pipe_context *pctx, struct pipe_resource *prsc, 609bf215546Sopenharmony_ci unsigned plane, unsigned layer, unsigned level, 610bf215546Sopenharmony_ci enum pipe_resource_param param, 611bf215546Sopenharmony_ci unsigned usage, uint64_t *value) 612bf215546Sopenharmony_ci{ 613bf215546Sopenharmony_ci if (param == PIPE_RESOURCE_PARAM_NPLANES) { 614bf215546Sopenharmony_ci unsigned count = 0; 615bf215546Sopenharmony_ci 616bf215546Sopenharmony_ci for (struct pipe_resource *cur = prsc; cur; cur = cur->next) 617bf215546Sopenharmony_ci count++; 618bf215546Sopenharmony_ci *value = count; 619bf215546Sopenharmony_ci return true; 620bf215546Sopenharmony_ci } 621bf215546Sopenharmony_ci 622bf215546Sopenharmony_ci struct pipe_resource *cur = prsc; 623bf215546Sopenharmony_ci for (int i = 0; i < plane; i++) { 624bf215546Sopenharmony_ci cur = cur->next; 625bf215546Sopenharmony_ci if (!cur) 626bf215546Sopenharmony_ci return false; 627bf215546Sopenharmony_ci } 628bf215546Sopenharmony_ci struct etna_resource *rsc = etna_resource(cur); 629bf215546Sopenharmony_ci 630bf215546Sopenharmony_ci switch (param) { 631bf215546Sopenharmony_ci case PIPE_RESOURCE_PARAM_STRIDE: 632bf215546Sopenharmony_ci *value = rsc->levels[level].stride; 633bf215546Sopenharmony_ci return true; 634bf215546Sopenharmony_ci case PIPE_RESOURCE_PARAM_OFFSET: 635bf215546Sopenharmony_ci *value = rsc->levels[level].offset; 636bf215546Sopenharmony_ci return true; 637bf215546Sopenharmony_ci case PIPE_RESOURCE_PARAM_MODIFIER: 638bf215546Sopenharmony_ci *value = layout_to_modifier(rsc->layout); 639bf215546Sopenharmony_ci return true; 640bf215546Sopenharmony_ci default: 641bf215546Sopenharmony_ci return false; 642bf215546Sopenharmony_ci } 643bf215546Sopenharmony_ci} 644bf215546Sopenharmony_ci 645bf215546Sopenharmony_civoid 646bf215546Sopenharmony_cietna_resource_used(struct etna_context *ctx, struct pipe_resource *prsc, 647bf215546Sopenharmony_ci enum etna_resource_status status) 648bf215546Sopenharmony_ci{ 649bf215546Sopenharmony_ci struct etna_resource *rsc; 650bf215546Sopenharmony_ci struct hash_entry *entry; 651bf215546Sopenharmony_ci uint32_t hash; 652bf215546Sopenharmony_ci 653bf215546Sopenharmony_ci if (!prsc) 654bf215546Sopenharmony_ci return; 655bf215546Sopenharmony_ci 656bf215546Sopenharmony_ci rsc = etna_resource(prsc); 657bf215546Sopenharmony_ci hash = _mesa_hash_pointer(rsc); 658bf215546Sopenharmony_ci entry = _mesa_hash_table_search_pre_hashed(ctx->pending_resources, 659bf215546Sopenharmony_ci hash, rsc); 660bf215546Sopenharmony_ci 661bf215546Sopenharmony_ci if (entry) { 662bf215546Sopenharmony_ci enum etna_resource_status tmp = (uintptr_t)entry->data; 663bf215546Sopenharmony_ci tmp |= status; 664bf215546Sopenharmony_ci entry->data = (void *)(uintptr_t)tmp; 665bf215546Sopenharmony_ci } else { 666bf215546Sopenharmony_ci _mesa_hash_table_insert_pre_hashed(ctx->pending_resources, hash, rsc, 667bf215546Sopenharmony_ci (void *)(uintptr_t)status); 668bf215546Sopenharmony_ci } 669bf215546Sopenharmony_ci} 670bf215546Sopenharmony_ci 671bf215546Sopenharmony_cienum etna_resource_status 672bf215546Sopenharmony_cietna_resource_status(struct etna_context *ctx, struct etna_resource *res) 673bf215546Sopenharmony_ci{ 674bf215546Sopenharmony_ci struct hash_entry *entry = _mesa_hash_table_search(ctx->pending_resources, res); 675bf215546Sopenharmony_ci 676bf215546Sopenharmony_ci if (entry) 677bf215546Sopenharmony_ci return (enum etna_resource_status)(uintptr_t)entry->data; 678bf215546Sopenharmony_ci else 679bf215546Sopenharmony_ci return 0; 680bf215546Sopenharmony_ci} 681bf215546Sopenharmony_ci 682bf215546Sopenharmony_cibool 683bf215546Sopenharmony_cietna_resource_has_valid_ts(struct etna_resource *rsc) 684bf215546Sopenharmony_ci{ 685bf215546Sopenharmony_ci if (!rsc->ts_bo) 686bf215546Sopenharmony_ci return false; 687bf215546Sopenharmony_ci 688bf215546Sopenharmony_ci for (int level = 0; level <= rsc->base.last_level; level++) 689bf215546Sopenharmony_ci if (rsc->levels[level].ts_valid) 690bf215546Sopenharmony_ci return true; 691bf215546Sopenharmony_ci 692bf215546Sopenharmony_ci return false; 693bf215546Sopenharmony_ci} 694bf215546Sopenharmony_ci 695bf215546Sopenharmony_civoid 696bf215546Sopenharmony_cietna_resource_screen_init(struct pipe_screen *pscreen) 697bf215546Sopenharmony_ci{ 698bf215546Sopenharmony_ci pscreen->can_create_resource = etna_screen_can_create_resource; 699bf215546Sopenharmony_ci pscreen->resource_create = etna_resource_create; 700bf215546Sopenharmony_ci pscreen->resource_create_with_modifiers = etna_resource_create_modifiers; 701bf215546Sopenharmony_ci pscreen->resource_from_handle = etna_resource_from_handle; 702bf215546Sopenharmony_ci pscreen->resource_get_handle = etna_resource_get_handle; 703bf215546Sopenharmony_ci pscreen->resource_get_param = etna_resource_get_param; 704bf215546Sopenharmony_ci pscreen->resource_changed = etna_resource_changed; 705bf215546Sopenharmony_ci pscreen->resource_destroy = etna_resource_destroy; 706bf215546Sopenharmony_ci} 707