1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/********************************************************** 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2008-2009 VMware, Inc. All rights reserved. 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * obtaining a copy of this software and associated documentation 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * files (the "Software"), to deal in the Software without 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * restriction, including without limitation the rights to use, copy, 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * modify, merge, publish, distribute, sublicense, and/or sell copies 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software, and to permit persons to whom the Software is 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * furnished to do so, subject to the following conditions: 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice shall be 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * included in all copies or substantial portions of the Software. 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE. 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **********************************************************/ 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_math.h" 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_memory.h" 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_hash.h" 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "svga_debug.h" 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "svga_format.h" 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "svga_winsys.h" 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "svga_screen.h" 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "svga_screen_cache.h" 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SVGA_SURFACE_CACHE_ENABLED 1 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return the size of the surface described by the key (in bytes). 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsurface_size(const struct svga_host_surface_cache_key *key) 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned bw, bh, bpb, total_size, i; 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(key->numMipLevels > 0); 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(key->numFaces > 0); 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (key->format == SVGA3D_BUFFER) { 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Special case: we don't want to count vertex/index buffers 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * against the cache size limit, so view them as zero-sized. 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svga_format_size(key->format, &bw, &bh, &bpb); 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org total_size = 0; 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < key->numMipLevels; i++) { 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned w = u_minify(key->size.width, i); 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned h = u_minify(key->size.height, i); 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned d = u_minify(key->size.depth, i); 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned img_size = ((w + bw - 1) / bw) * ((h + bh - 1) / bh) * d * bpb; 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org total_size += img_size; 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org total_size *= key->numFaces; 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return total_size; 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Compute the bucket for this key. 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE unsigned 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsvga_screen_cache_bucket(const struct svga_host_surface_cache_key *key) 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return util_hash_crc32(key, sizeof *key) % SVGA_HOST_SURFACE_CACHE_BUCKETS; 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Search the cache for a surface that matches the key. If a match is 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * found, remove it from the cache and return the surface pointer. 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Return NULL otherwise. 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE struct svga_winsys_surface * 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsvga_screen_cache_lookup(struct svga_screen *svgascreen, 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct svga_host_surface_cache_key *key) 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct svga_host_surface_cache *cache = &svgascreen->cache; 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct svga_winsys_screen *sws = svgascreen->sws; 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct svga_host_surface_cache_entry *entry; 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct svga_winsys_surface *handle = NULL; 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct list_head *curr, *next; 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned bucket; 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned tries = 0; 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(key->cachable); 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bucket = svga_screen_cache_bucket(key); 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_mutex_lock(cache->mutex); 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org curr = cache->bucket[bucket].next; 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org next = curr->next; 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (curr != &cache->bucket[bucket]) { 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ++tries; 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry = LIST_ENTRY(struct svga_host_surface_cache_entry, curr, bucket_head); 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(entry->handle); 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (memcmp(&entry->key, key, sizeof *key) == 0 && 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sws->fence_signalled(sws, entry->fence, 0) == 0) { 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned surf_size; 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(sws->surface_is_flushed(sws, entry->handle)); 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org handle = entry->handle; /* Reference is transfered here. */ 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry->handle = NULL; 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LIST_DEL(&entry->bucket_head); 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LIST_DEL(&entry->head); 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LIST_ADD(&entry->head, &cache->empty); 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* update the cache size */ 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org surf_size = surface_size(&entry->key); 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(surf_size <= cache->total_size); 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (surf_size > cache->total_size) 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cache->total_size = 0; /* should never happen, but be safe */ 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cache->total_size -= surf_size; 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org curr = next; 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org next = curr->next; 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_mutex_unlock(cache->mutex); 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (SVGA_DEBUG & DEBUG_DMA) 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("%s: cache %s after %u tries (bucket %d)\n", __FUNCTION__, 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org handle ? "hit" : "miss", tries, bucket); 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return handle; 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Free the least recently used entries in the surface cache until the 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * cache size is <= the target size OR there are no unused entries left 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to discard. We don't do any flushing to try to free up additional 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * surfaces. 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsvga_screen_cache_shrink(struct svga_screen *svgascreen, 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned target_size) 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct svga_host_surface_cache *cache = &svgascreen->cache; 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct svga_winsys_screen *sws = svgascreen->sws; 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct svga_host_surface_cache_entry *entry = NULL, *next_entry; 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Walk over the list of unused buffers in reverse order: from oldest 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to newest. 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LIST_FOR_EACH_ENTRY_SAFE_REV(entry, next_entry, &cache->unused, head) { 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (entry->key.format != SVGA3D_BUFFER) { 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* we don't want to discard vertex/index buffers */ 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cache->total_size -= surface_size(&entry->key); 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(entry->handle); 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sws->surface_reference(sws, &entry->handle, NULL); 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LIST_DEL(&entry->bucket_head); 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LIST_DEL(&entry->head); 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LIST_ADD(&entry->head, &cache->empty); 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cache->total_size <= target_size) { 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* all done */ 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Transfers a handle reference. 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE void 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsvga_screen_cache_add(struct svga_screen *svgascreen, 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct svga_host_surface_cache_key *key, 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct svga_winsys_surface **p_handle) 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct svga_host_surface_cache *cache = &svgascreen->cache; 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct svga_winsys_screen *sws = svgascreen->sws; 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct svga_host_surface_cache_entry *entry = NULL; 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct svga_winsys_surface *handle = *p_handle; 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned surf_size; 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(key->cachable); 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(handle); 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!handle) 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org surf_size = surface_size(key); 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *p_handle = NULL; 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_mutex_lock(cache->mutex); 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (surf_size >= SVGA_HOST_SURFACE_CACHE_BYTES) { 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* this surface is too large to cache, just free it */ 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sws->surface_reference(sws, &handle, NULL); 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_mutex_unlock(cache->mutex); 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cache->total_size + surf_size > SVGA_HOST_SURFACE_CACHE_BYTES) { 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Adding this surface would exceed the cache size. 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Try to discard least recently used entries until we hit the 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * new target cache size. 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned target_size = SVGA_HOST_SURFACE_CACHE_BYTES - surf_size; 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svga_screen_cache_shrink(svgascreen, target_size); 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cache->total_size > target_size) { 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* we weren't able to shrink the cache as much as we wanted so 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * just discard this surface. 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sws->surface_reference(sws, &handle, NULL); 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_mutex_unlock(cache->mutex); 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!LIST_IS_EMPTY(&cache->empty)) { 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* use the first empty entry */ 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry = LIST_ENTRY(struct svga_host_surface_cache_entry, 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cache->empty.next, head); 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LIST_DEL(&entry->head); 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (!LIST_IS_EMPTY(&cache->unused)) { 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* free the last used buffer and reuse its entry */ 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry = LIST_ENTRY(struct svga_host_surface_cache_entry, 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cache->unused.prev, head); 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SVGA_DBG(DEBUG_CACHE|DEBUG_DMA, 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "unref sid %p (make space)\n", entry->handle); 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cache->total_size -= surface_size(&entry->key); 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sws->surface_reference(sws, &entry->handle, NULL); 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LIST_DEL(&entry->bucket_head); 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LIST_DEL(&entry->head); 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (entry) { 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry->handle = handle; 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(&entry->key, key, sizeof entry->key); 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SVGA_DBG(DEBUG_CACHE|DEBUG_DMA, 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "cache sid %p\n", entry->handle); 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LIST_ADD(&entry->head, &cache->validated); 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cache->total_size += surf_size; 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Couldn't cache the buffer -- this really shouldn't happen */ 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SVGA_DBG(DEBUG_CACHE|DEBUG_DMA, 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "unref sid %p (couldn't find space)\n", handle); 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sws->surface_reference(sws, &handle, NULL); 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_mutex_unlock(cache->mutex); 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Called during the screen flush to move all buffers not in a validate list 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * into the unused list. 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsvga_screen_cache_flush(struct svga_screen *svgascreen, 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct pipe_fence_handle *fence) 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct svga_host_surface_cache *cache = &svgascreen->cache; 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct svga_winsys_screen *sws = svgascreen->sws; 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct svga_host_surface_cache_entry *entry; 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct list_head *curr, *next; 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned bucket; 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_mutex_lock(cache->mutex); 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org curr = cache->validated.next; 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org next = curr->next; 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (curr != &cache->validated) { 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry = LIST_ENTRY(struct svga_host_surface_cache_entry, curr, head); 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(entry->handle); 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (sws->surface_is_flushed(sws, entry->handle)) { 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LIST_DEL(&entry->head); 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svgascreen->sws->fence_reference(svgascreen->sws, &entry->fence, fence); 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LIST_ADD(&entry->head, &cache->unused); 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bucket = svga_screen_cache_bucket(&entry->key); 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LIST_ADD(&entry->bucket_head, &cache->bucket[bucket]); 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org curr = next; 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org next = curr->next; 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_mutex_unlock(cache->mutex); 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Free all the surfaces in the cache. 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Called when destroying the svga screen object. 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsvga_screen_cache_cleanup(struct svga_screen *svgascreen) 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct svga_host_surface_cache *cache = &svgascreen->cache; 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct svga_winsys_screen *sws = svgascreen->sws; 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned i; 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < SVGA_HOST_SURFACE_CACHE_SIZE; ++i) { 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cache->entries[i].handle) { 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SVGA_DBG(DEBUG_CACHE|DEBUG_DMA, 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "unref sid %p (shutdown)\n", cache->entries[i].handle); 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sws->surface_reference(sws, &cache->entries[i].handle, NULL); 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cache->total_size -= surface_size(&cache->entries[i].key); 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cache->entries[i].fence) 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svgascreen->sws->fence_reference(svgascreen->sws, 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &cache->entries[i].fence, NULL); 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_mutex_destroy(cache->mutex); 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgenum pipe_error 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsvga_screen_cache_init(struct svga_screen *svgascreen) 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct svga_host_surface_cache *cache = &svgascreen->cache; 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned i; 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(cache->total_size == 0); 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_mutex_init(cache->mutex); 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < SVGA_HOST_SURFACE_CACHE_BUCKETS; ++i) 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LIST_INITHEAD(&cache->bucket[i]); 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LIST_INITHEAD(&cache->unused); 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LIST_INITHEAD(&cache->validated); 379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LIST_INITHEAD(&cache->empty); 381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < SVGA_HOST_SURFACE_CACHE_SIZE; ++i) 382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LIST_ADDTAIL(&cache->entries[i].head, &cache->empty); 383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return PIPE_OK; 385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Allocate a new host-side surface. If the surface is marked as cachable, 390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * first try re-using a surface in the cache of freed surfaces. Otherwise, 391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * allocate a new surface. 392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct svga_winsys_surface * 394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsvga_screen_surface_create(struct svga_screen *svgascreen, 395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct svga_host_surface_cache_key *key) 396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct svga_winsys_screen *sws = svgascreen->sws; 398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct svga_winsys_surface *handle = NULL; 399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org boolean cachable = SVGA_SURFACE_CACHE_ENABLED && key->cachable; 400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SVGA_DBG(DEBUG_CACHE|DEBUG_DMA, 402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "%s sz %dx%dx%d mips %d faces %d cachable %d\n", 403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org __FUNCTION__, 404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key->size.width, 405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key->size.height, 406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key->size.depth, 407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key->numMipLevels, 408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key->numFaces, 409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key->cachable); 410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cachable) { 412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (key->format == SVGA3D_BUFFER) { 413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* For buffers, round the buffer size up to the nearest power 414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of two to increase the probability of cache hits. Keep 415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * texture surface dimensions unchanged. 416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org uint32_t size = 1; 418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org while (size < key->size.width) 419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org size <<= 1; 420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key->size.width = size; 421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Since we're reusing buffers we're effectively transforming all 422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of them into dynamic buffers. 423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * It would be nice to not cache long lived static buffers. But there 425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * is no way to detect the long lived from short lived ones yet. A 426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * good heuristic would be buffer size. 427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key->flags &= ~SVGA3D_SURFACE_HINT_STATIC; 429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key->flags |= SVGA3D_SURFACE_HINT_DYNAMIC; 430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org handle = svga_screen_cache_lookup(svgascreen, key); 433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (handle) { 434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (key->format == SVGA3D_BUFFER) 435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SVGA_DBG(DEBUG_CACHE|DEBUG_DMA, 436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "reuse sid %p sz %d (buffer)\n", handle, 437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key->size.width); 438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SVGA_DBG(DEBUG_CACHE|DEBUG_DMA, 440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "reuse sid %p sz %dx%dx%d mips %d faces %d\n", handle, 441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key->size.width, 442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key->size.height, 443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key->size.depth, 444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key->numMipLevels, 445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key->numFaces); 446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!handle) { 450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org handle = sws->surface_create(sws, 451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key->flags, 452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key->format, 453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key->size, 454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key->numFaces, 455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key->numMipLevels); 456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (handle) 457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SVGA_DBG(DEBUG_CACHE|DEBUG_DMA, 458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org " CREATE sid %p sz %dx%dx%d\n", 459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org handle, 460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key->size.width, 461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key->size.height, 462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org key->size.depth); 463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return handle; 466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Release a surface. We don't actually free the surface- we put 471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * it into the cache of freed surfaces (if it's cachable). 472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsvga_screen_surface_destroy(struct svga_screen *svgascreen, 475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct svga_host_surface_cache_key *key, 476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct svga_winsys_surface **p_handle) 477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct svga_winsys_screen *sws = svgascreen->sws; 479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* We only set the cachable flag for surfaces of which we are the 481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * exclusive owner. So just hold onto our existing reference in 482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * that case. 483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (SVGA_SURFACE_CACHE_ENABLED && key->cachable) { 485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org svga_screen_cache_add(svgascreen, key, p_handle); 486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SVGA_DBG(DEBUG_DMA, 489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "unref sid %p (uncachable)\n", *p_handle); 490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sws->surface_reference(sws, p_handle, NULL); 491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 493