mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 07:08:04 +02:00
svga: cache textures as well as buffers
This commit is contained in:
parent
4509f3cbad
commit
f1ce37f74a
5 changed files with 167 additions and 117 deletions
|
|
@ -71,7 +71,10 @@ svga_buffer_create_host_surface(struct svga_screen *ss,
|
|||
|
||||
sbuf->key.numFaces = 1;
|
||||
sbuf->key.numMipLevels = 1;
|
||||
sbuf->key.cachable = 1;
|
||||
|
||||
SVGA_DBG(DEBUG_DMA, "surface_create for buffer sz %d\n", sbuf->base.size);
|
||||
|
||||
sbuf->handle = svga_screen_surface_create(ss, &sbuf->key);
|
||||
if(!sbuf->handle)
|
||||
return PIPE_ERROR_OUT_OF_MEMORY;
|
||||
|
|
@ -82,7 +85,7 @@ svga_buffer_create_host_surface(struct svga_screen *ss,
|
|||
*/
|
||||
sbuf->hw.flags.discard = TRUE;
|
||||
|
||||
SVGA_DBG(DEBUG_DMA, " grab sid %p sz %d\n", sbuf->handle, sbuf->base.size);
|
||||
SVGA_DBG(DEBUG_DMA, " --> got sid %p sz %d (buffer)\n", sbuf->handle, sbuf->base.size);
|
||||
}
|
||||
|
||||
return PIPE_OK;
|
||||
|
|
@ -776,12 +779,11 @@ svga_screen_buffer_wrap_surface(struct pipe_screen *screen,
|
|||
|
||||
/*
|
||||
* We are not the creator of this surface and therefore we must not
|
||||
* cache it for reuse. The caching code only caches SVGA3D_BUFFER surfaces
|
||||
* so make sure this isn't one of those.
|
||||
* cache it for reuse. Set the cacheable flag to zero in the key to
|
||||
* prevent this.
|
||||
*/
|
||||
|
||||
assert(format != SVGA3D_BUFFER);
|
||||
sbuf->key.format = format;
|
||||
sbuf->key.cachable = 0;
|
||||
sws->surface_reference(sws, &sbuf->handle, srf);
|
||||
|
||||
return buf;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
**********************************************************/
|
||||
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_hash.h"
|
||||
|
||||
#include "svga_debug.h"
|
||||
#include "svga_winsys.h"
|
||||
|
|
@ -36,24 +37,11 @@
|
|||
|
||||
/**
|
||||
* Compute the bucket for this key.
|
||||
*
|
||||
* We simply compute log2(width) for now, but
|
||||
*/
|
||||
static INLINE unsigned
|
||||
svga_screen_cache_bucket(const struct svga_host_surface_cache_key *key)
|
||||
{
|
||||
unsigned bucket = 0;
|
||||
unsigned size = key->size.width;
|
||||
|
||||
while ((size >>= 1))
|
||||
++bucket;
|
||||
|
||||
if(key->flags & SVGA3D_SURFACE_HINT_INDEXBUFFER)
|
||||
bucket += 32;
|
||||
|
||||
assert(bucket < SVGA_HOST_SURFACE_CACHE_BUCKETS);
|
||||
|
||||
return bucket;
|
||||
return util_hash_crc32( key, sizeof key ) % SVGA_HOST_SURFACE_CACHE_BUCKETS;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -69,6 +57,8 @@ svga_screen_cache_lookup(struct svga_screen *svgascreen,
|
|||
unsigned bucket;
|
||||
unsigned tries = 0;
|
||||
|
||||
assert(key->cachable);
|
||||
|
||||
bucket = svga_screen_cache_bucket(key);
|
||||
|
||||
pipe_mutex_lock(cache->mutex);
|
||||
|
|
@ -104,11 +94,9 @@ svga_screen_cache_lookup(struct svga_screen *svgascreen,
|
|||
|
||||
pipe_mutex_unlock(cache->mutex);
|
||||
|
||||
#if 0
|
||||
_debug_printf("%s: cache %s after %u tries\n", __FUNCTION__, handle ? "hit" : "miss", tries);
|
||||
#else
|
||||
(void)tries;
|
||||
#endif
|
||||
if (SVGA_DEBUG & DEBUG_DMA)
|
||||
debug_printf("%s: cache %s after %u tries\n", __FUNCTION__,
|
||||
handle ? "hit" : "miss", tries);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
|
@ -128,6 +116,7 @@ svga_screen_cache_add(struct svga_screen *svgascreen,
|
|||
struct svga_host_surface_cache_entry *entry = NULL;
|
||||
struct svga_winsys_surface *handle = *p_handle;
|
||||
|
||||
assert(key->cachable);
|
||||
|
||||
assert(handle);
|
||||
if(!handle)
|
||||
|
|
@ -137,15 +126,15 @@ svga_screen_cache_add(struct svga_screen *svgascreen,
|
|||
pipe_mutex_lock(cache->mutex);
|
||||
|
||||
if(!LIST_IS_EMPTY(&cache->empty)) {
|
||||
/* use the first empty entry */
|
||||
entry = LIST_ENTRY(struct svga_host_surface_cache_entry, cache->empty.next, head);
|
||||
/* use the first empty entry */
|
||||
entry = LIST_ENTRY(struct svga_host_surface_cache_entry, cache->empty.next, head);
|
||||
|
||||
LIST_DEL(&entry->head);
|
||||
}
|
||||
LIST_DEL(&entry->head);
|
||||
}
|
||||
else if(!LIST_IS_EMPTY(&cache->unused)) {
|
||||
/* free the last used buffer and reuse its entry */
|
||||
entry = LIST_ENTRY(struct svga_host_surface_cache_entry, cache->unused.prev, head);
|
||||
SVGA_DBG(DEBUG_DMA, "unref sid %p\n", entry->handle);
|
||||
SVGA_DBG(DEBUG_DMA, "unref sid %p (make space)\n", entry->handle);
|
||||
sws->surface_reference(sws, &entry->handle, NULL);
|
||||
|
||||
LIST_DEL(&entry->bucket_head);
|
||||
|
|
@ -161,7 +150,7 @@ svga_screen_cache_add(struct svga_screen *svgascreen,
|
|||
}
|
||||
else {
|
||||
/* Couldn't cache the buffer -- this really shouldn't happen */
|
||||
SVGA_DBG(DEBUG_DMA, "unref sid %p\n", handle);
|
||||
SVGA_DBG(DEBUG_DMA, "unref sid %p (couldn't find space)\n", handle);
|
||||
sws->surface_reference(sws, &handle, NULL);
|
||||
}
|
||||
|
||||
|
|
@ -220,7 +209,7 @@ svga_screen_cache_cleanup(struct svga_screen *svgascreen)
|
|||
|
||||
for(i = 0; i < SVGA_HOST_SURFACE_CACHE_SIZE; ++i) {
|
||||
if(cache->entries[i].handle) {
|
||||
SVGA_DBG(DEBUG_DMA, "unref sid %p\n", cache->entries[i].handle);
|
||||
SVGA_DBG(DEBUG_DMA, "unref sid %p (shutdown)\n", cache->entries[i].handle);
|
||||
sws->surface_reference(sws, &cache->entries[i].handle, NULL);
|
||||
}
|
||||
|
||||
|
|
@ -261,18 +250,42 @@ svga_screen_surface_create(struct svga_screen *svgascreen,
|
|||
{
|
||||
struct svga_winsys_screen *sws = svgascreen->sws;
|
||||
struct svga_winsys_surface *handle = NULL;
|
||||
boolean cachable = SVGA_SURFACE_CACHE_ENABLED && key->cachable;
|
||||
|
||||
SVGA_DBG(DEBUG_DMA, "%s sz %dx%dx%d mips %d faces %d cachable %d\n",
|
||||
__FUNCTION__,
|
||||
key->size.width,
|
||||
key->size.height,
|
||||
key->size.depth,
|
||||
key->numMipLevels,
|
||||
key->numFaces,
|
||||
key->cachable);
|
||||
|
||||
if (cachable) {
|
||||
if (key->format == SVGA3D_BUFFER) {
|
||||
/* For buffers, round the buffer size up to the nearest power
|
||||
* of two to increase the probability of cache hits. Keep
|
||||
* texture surface dimensions unchanged.
|
||||
*/
|
||||
uint32_t size = 1;
|
||||
while(size < key->size.width)
|
||||
size <<= 1;
|
||||
key->size.width = size;
|
||||
}
|
||||
|
||||
if (SVGA_SURFACE_CACHE_ENABLED && key->format == SVGA3D_BUFFER) {
|
||||
/* round the buffer size up to the nearest power of two to increase the
|
||||
* probability of cache hits */
|
||||
uint32_t size = 1;
|
||||
while(size < key->size.width)
|
||||
size <<= 1;
|
||||
key->size.width = size;
|
||||
|
||||
handle = svga_screen_cache_lookup(svgascreen, key);
|
||||
if (handle)
|
||||
SVGA_DBG(DEBUG_DMA, " reuse sid %p sz %d\n", handle, size);
|
||||
if (handle) {
|
||||
if (key->format == SVGA3D_BUFFER)
|
||||
SVGA_DBG(DEBUG_DMA, " reuse sid %p sz %d (buffer)\n", handle,
|
||||
key->size.width);
|
||||
else
|
||||
SVGA_DBG(DEBUG_DMA, " reuse sid %p sz %dx%dx%d mips %d faces %d\n", handle,
|
||||
key->size.width,
|
||||
key->size.height,
|
||||
key->size.depth,
|
||||
key->numMipLevels,
|
||||
key->numFaces);
|
||||
}
|
||||
}
|
||||
|
||||
if (!handle) {
|
||||
|
|
@ -297,11 +310,15 @@ svga_screen_surface_destroy(struct svga_screen *svgascreen,
|
|||
{
|
||||
struct svga_winsys_screen *sws = svgascreen->sws;
|
||||
|
||||
if(SVGA_SURFACE_CACHE_ENABLED && key->format == SVGA3D_BUFFER) {
|
||||
/* We only set the cachable flag for surfaces of which we are the
|
||||
* exclusive owner. So just hold onto our existing reference in
|
||||
* that case.
|
||||
*/
|
||||
if(SVGA_SURFACE_CACHE_ENABLED && key->cachable) {
|
||||
svga_screen_cache_add(svgascreen, key, p_handle);
|
||||
}
|
||||
else {
|
||||
SVGA_DBG(DEBUG_DMA, "unref sid %p\n", *p_handle);
|
||||
SVGA_DBG(DEBUG_DMA, "unref sid %p (uncachable)\n", *p_handle);
|
||||
sws->surface_reference(sws, p_handle, NULL);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,10 +36,18 @@
|
|||
#include "util/u_double_list.h"
|
||||
|
||||
|
||||
/* TODO: Reduce this once we don't allocate an index buffer per draw call */
|
||||
/* Guess the storage size of cached surfaces and try and keep it under
|
||||
* this amount:
|
||||
*/
|
||||
#define SVGA_HOST_SURFACE_CACHE_BYTES 16*1024*1024
|
||||
|
||||
/* Maximum number of discrete surfaces in the cache:
|
||||
*/
|
||||
#define SVGA_HOST_SURFACE_CACHE_SIZE 1024
|
||||
|
||||
#define SVGA_HOST_SURFACE_CACHE_BUCKETS 64
|
||||
/* Number of hash buckets:
|
||||
*/
|
||||
#define SVGA_HOST_SURFACE_CACHE_BUCKETS 256
|
||||
|
||||
|
||||
struct svga_winsys_surface;
|
||||
|
|
@ -50,11 +58,12 @@ struct svga_screen;
|
|||
*/
|
||||
struct svga_host_surface_cache_key
|
||||
{
|
||||
SVGA3dSurfaceFlags flags;
|
||||
SVGA3dSurfaceFormat format;
|
||||
SVGA3dSize size;
|
||||
uint32_t numFaces;
|
||||
uint32_t numMipLevels;
|
||||
uint32_t flags:8;
|
||||
uint32_t format:8;
|
||||
uint32_t numFaces:8;
|
||||
uint32_t numMipLevels:7;
|
||||
uint32_t cachable:1; /* False if this is a shared surface */
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -266,14 +266,8 @@ svga_texture_create(struct pipe_screen *screen,
|
|||
const struct pipe_texture *templat)
|
||||
{
|
||||
struct svga_screen *svgascreen = svga_screen(screen);
|
||||
struct svga_winsys_screen *sws = svgascreen->sws;
|
||||
struct svga_texture *tex = CALLOC_STRUCT(svga_texture);
|
||||
unsigned width, height, depth;
|
||||
SVGA3dSurfaceFlags flags = 0;
|
||||
SVGA3dSurfaceFormat format;
|
||||
SVGA3dSize size;
|
||||
uint32 numFaces;
|
||||
uint32 numMipLevels;
|
||||
unsigned level;
|
||||
|
||||
if (!tex)
|
||||
|
|
@ -301,23 +295,24 @@ svga_texture_create(struct pipe_screen *screen,
|
|||
depth = minify(depth);
|
||||
}
|
||||
|
||||
size.width = templat->width[0];
|
||||
size.height = templat->height[0];
|
||||
size.depth = templat->depth[0];
|
||||
tex->key.flags = 0;
|
||||
tex->key.size.width = templat->width[0];
|
||||
tex->key.size.height = templat->height[0];
|
||||
tex->key.size.depth = templat->depth[0];
|
||||
|
||||
if(templat->target == PIPE_TEXTURE_CUBE) {
|
||||
flags |= SVGA3D_SURFACE_CUBEMAP;
|
||||
numFaces = 6;
|
||||
tex->key.flags |= SVGA3D_SURFACE_CUBEMAP;
|
||||
tex->key.numFaces = 6;
|
||||
}
|
||||
else {
|
||||
numFaces = 1;
|
||||
tex->key.numFaces = 1;
|
||||
}
|
||||
|
||||
if(templat->tex_usage & PIPE_TEXTURE_USAGE_SAMPLER)
|
||||
flags |= SVGA3D_SURFACE_HINT_TEXTURE;
|
||||
tex->key.flags |= SVGA3D_SURFACE_HINT_TEXTURE;
|
||||
|
||||
if(templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY)
|
||||
flags |= SVGA3D_SURFACE_HINT_SCANOUT;
|
||||
tex->key.flags |= SVGA3D_SURFACE_HINT_SCANOUT;
|
||||
|
||||
/*
|
||||
* XXX: Never pass the SVGA3D_SURFACE_HINT_RENDERTARGET hint. Mesa cannot
|
||||
|
|
@ -328,21 +323,24 @@ svga_texture_create(struct pipe_screen *screen,
|
|||
#if 0
|
||||
if((templat->tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) &&
|
||||
!pf_is_compressed(templat->format))
|
||||
flags |= SVGA3D_SURFACE_HINT_RENDERTARGET;
|
||||
tex->key.flags |= SVGA3D_SURFACE_HINT_RENDERTARGET;
|
||||
#endif
|
||||
|
||||
if(templat->tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL)
|
||||
flags |= SVGA3D_SURFACE_HINT_DEPTHSTENCIL;
|
||||
tex->key.flags |= SVGA3D_SURFACE_HINT_DEPTHSTENCIL;
|
||||
|
||||
numMipLevels = templat->last_level + 1;
|
||||
tex->key.numMipLevels = templat->last_level + 1;
|
||||
|
||||
format = svga_translate_format(templat->format);
|
||||
if(format == SVGA3D_FORMAT_INVALID)
|
||||
tex->key.format = svga_translate_format(templat->format);
|
||||
if(tex->key.format == SVGA3D_FORMAT_INVALID)
|
||||
goto error2;
|
||||
|
||||
tex->key.cachable = 1;
|
||||
|
||||
tex->handle = sws->surface_create(sws, flags, format, size, numFaces, numMipLevels);
|
||||
SVGA_DBG(DEBUG_DMA, "surface_create for texture\n", tex->handle);
|
||||
tex->handle = svga_screen_surface_create(svgascreen, &tex->key);
|
||||
if (tex->handle)
|
||||
SVGA_DBG(DEBUG_DMA, "create sid %p (texture)\n", tex->handle);
|
||||
SVGA_DBG(DEBUG_DMA, " --> got sid %p (texture)\n", tex->handle);
|
||||
|
||||
return &tex->base;
|
||||
|
||||
|
|
@ -398,6 +396,10 @@ svga_texture_blanket(struct pipe_screen * screen,
|
|||
return NULL;
|
||||
|
||||
tex->base = *base;
|
||||
|
||||
/* We don't own this storage, so don't try to cache it.
|
||||
*/
|
||||
tex->key.cachable = 0;
|
||||
|
||||
if (sbuf->key.format == 1)
|
||||
tex->base.format = PIPE_FORMAT_X8R8G8B8_UNORM;
|
||||
|
|
@ -407,6 +409,7 @@ svga_texture_blanket(struct pipe_screen * screen,
|
|||
pipe_reference_init(&tex->base.reference, 1);
|
||||
tex->base.screen = screen;
|
||||
|
||||
SVGA_DBG(DEBUG_DMA, "blanket sid %p\n", sbuf->handle);
|
||||
sws->surface_reference(sws, &tex->handle, sbuf->handle);
|
||||
|
||||
return &tex->base;
|
||||
|
|
@ -427,7 +430,7 @@ svga_texture_destroy(struct pipe_texture *pt)
|
|||
DBG("%s deleting %p\n", __FUNCTION__, (void *) tex);
|
||||
*/
|
||||
SVGA_DBG(DEBUG_DMA, "unref sid %p (texture)\n", tex->handle);
|
||||
ss->sws->surface_reference(ss->sws, &tex->handle, NULL);
|
||||
svga_screen_surface_destroy(ss, &tex->key, &tex->handle);
|
||||
|
||||
FREE(tex);
|
||||
}
|
||||
|
|
@ -518,43 +521,43 @@ svga_texture_view_surface(struct pipe_context *pipe,
|
|||
unsigned start_mip,
|
||||
unsigned num_mip,
|
||||
int face_pick,
|
||||
int zslice_pick)
|
||||
int zslice_pick,
|
||||
struct svga_host_surface_cache_key *key) /* OUT */
|
||||
{
|
||||
struct svga_screen *ss = svga_screen(tex->base.screen);
|
||||
struct svga_winsys_screen *sws = ss->sws;
|
||||
struct svga_winsys_surface *handle;
|
||||
int i, j;
|
||||
SVGA3dSurfaceFlags flags = 0;
|
||||
SVGA3dSize size;
|
||||
uint32 numFaces;
|
||||
uint32 numMipLevels = num_mip;
|
||||
unsigned z_offset = 0;
|
||||
|
||||
SVGA_DBG(DEBUG_PERF,
|
||||
"svga: Create surface view: face %d zslice %d mips %d..%d\n",
|
||||
face_pick, zslice_pick, start_mip, start_mip+num_mip-1);
|
||||
|
||||
size.width = tex->base.width[start_mip];
|
||||
size.height = tex->base.height[start_mip];
|
||||
size.depth = zslice_pick < 0 ? tex->base.depth[start_mip] : 1;
|
||||
assert(size.depth == 1);
|
||||
key->flags = 0;
|
||||
key->format = format;
|
||||
key->numMipLevels = num_mip;
|
||||
key->size.width = tex->base.width[start_mip];
|
||||
key->size.height = tex->base.height[start_mip];
|
||||
key->size.depth = zslice_pick < 0 ? tex->base.depth[start_mip] : 1;
|
||||
key->cachable = 1;
|
||||
assert(key->size.depth == 1);
|
||||
|
||||
if(tex->base.target == PIPE_TEXTURE_CUBE && face_pick < 0) {
|
||||
flags |= SVGA3D_SURFACE_CUBEMAP;
|
||||
numFaces = 6;
|
||||
key->flags |= SVGA3D_SURFACE_CUBEMAP;
|
||||
key->numFaces = 6;
|
||||
} else {
|
||||
numFaces = 1;
|
||||
key->numFaces = 1;
|
||||
}
|
||||
|
||||
if(format == SVGA3D_FORMAT_INVALID)
|
||||
if(key->format == SVGA3D_FORMAT_INVALID)
|
||||
return NULL;
|
||||
|
||||
handle = sws->surface_create(sws, flags, format, size, numFaces, numMipLevels);
|
||||
|
||||
SVGA_DBG(DEBUG_DMA, "surface_create for texture view\n", handle);
|
||||
handle = svga_screen_surface_create(ss, key);
|
||||
if (!handle)
|
||||
return NULL;
|
||||
|
||||
SVGA_DBG(DEBUG_DMA, "create sid %p (texture view)\n", handle);
|
||||
SVGA_DBG(DEBUG_DMA, " --> got sid %p (texture view)\n", handle);
|
||||
|
||||
if (face_pick < 0)
|
||||
face_pick = 0;
|
||||
|
|
@ -562,14 +565,20 @@ svga_texture_view_surface(struct pipe_context *pipe,
|
|||
if (zslice_pick >= 0)
|
||||
z_offset = zslice_pick;
|
||||
|
||||
for (i = 0; i < num_mip; i++) {
|
||||
for (j = 0; j < numFaces; j++) {
|
||||
for (i = 0; i < key->numMipLevels; i++) {
|
||||
for (j = 0; j < key->numFaces; j++) {
|
||||
if(tex->defined[j + face_pick][i + start_mip]) {
|
||||
unsigned depth = zslice_pick < 0 ? tex->base.depth[i + start_mip] : 1;
|
||||
svga_texture_copy_handle(svga_context(pipe), ss,
|
||||
tex->handle, 0, 0, z_offset, i + start_mip, j + face_pick,
|
||||
svga_texture_copy_handle(svga_context(pipe),
|
||||
ss,
|
||||
tex->handle,
|
||||
0, 0, z_offset,
|
||||
i + start_mip,
|
||||
j + face_pick,
|
||||
handle, 0, 0, 0, i, j,
|
||||
tex->base.width[i + start_mip], tex->base.height[i + start_mip], depth);
|
||||
tex->base.width[i + start_mip],
|
||||
tex->base.height[i + start_mip],
|
||||
depth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -586,25 +595,23 @@ svga_get_tex_surface(struct pipe_screen *screen,
|
|||
{
|
||||
struct svga_texture *tex = svga_texture(pt);
|
||||
struct svga_surface *s;
|
||||
struct pipe_surface *ps;
|
||||
boolean render = flags & PIPE_BUFFER_USAGE_GPU_WRITE ? TRUE : FALSE;
|
||||
boolean view = FALSE;
|
||||
SVGA3dSurfaceFormat format;
|
||||
|
||||
s = CALLOC_STRUCT(svga_surface);
|
||||
ps = &s->base;
|
||||
if (!ps)
|
||||
if (!s)
|
||||
return NULL;
|
||||
|
||||
pipe_reference_init(&ps->reference, 1);
|
||||
pipe_texture_reference(&ps->texture, pt);
|
||||
ps->format = pt->format;
|
||||
ps->width = pt->width[level];
|
||||
ps->height = pt->height[level];
|
||||
ps->usage = flags;
|
||||
ps->level = level;
|
||||
ps->face = face;
|
||||
ps->zslice = zslice;
|
||||
pipe_reference_init(&s->base.reference, 1);
|
||||
pipe_texture_reference(&s->base.texture, pt);
|
||||
s->base.format = pt->format;
|
||||
s->base.width = pt->width[level];
|
||||
s->base.height = pt->height[level];
|
||||
s->base.usage = flags;
|
||||
s->base.level = level;
|
||||
s->base.face = face;
|
||||
s->base.zslice = zslice;
|
||||
|
||||
if (!render)
|
||||
format = svga_translate_format(pt->format);
|
||||
|
|
@ -619,11 +626,13 @@ svga_get_tex_surface(struct pipe_screen *screen,
|
|||
view = TRUE;
|
||||
|
||||
/* Currently only used for compressed textures */
|
||||
if (render && (format != svga_translate_format(pt->format))) {
|
||||
if (render &&
|
||||
format != svga_translate_format(pt->format)) {
|
||||
view = TRUE;
|
||||
}
|
||||
|
||||
if (level != 0 && svga_screen(screen)->debug.force_level_surface_view)
|
||||
if (level != 0 &&
|
||||
svga_screen(screen)->debug.force_level_surface_view)
|
||||
view = TRUE;
|
||||
|
||||
if (pt->target == PIPE_TEXTURE_3D)
|
||||
|
|
@ -634,9 +643,10 @@ svga_get_tex_surface(struct pipe_screen *screen,
|
|||
|
||||
if (view) {
|
||||
SVGA_DBG(DEBUG_VIEWS, "svga: Surface view: yes %p, level %u face %u z %u, %p\n",
|
||||
pt, level, face, zslice, ps);
|
||||
pt, level, face, zslice, s);
|
||||
|
||||
s->handle = svga_texture_view_surface(NULL, tex, format, level, 1, face, zslice);
|
||||
s->handle = svga_texture_view_surface(NULL, tex, format, level, 1, face, zslice,
|
||||
&s->key);
|
||||
s->real_face = 0;
|
||||
s->real_level = 0;
|
||||
s->real_zslice = 0;
|
||||
|
|
@ -644,15 +654,16 @@ svga_get_tex_surface(struct pipe_screen *screen,
|
|||
struct svga_winsys_screen *sws = svga_winsys_screen(screen);
|
||||
|
||||
SVGA_DBG(DEBUG_VIEWS, "svga: Surface view: no %p, level %u, face %u, z %u, %p\n",
|
||||
pt, level, face, zslice, ps);
|
||||
pt, level, face, zslice, s);
|
||||
|
||||
sws->surface_reference(sws, &s->handle, tex->handle);
|
||||
s->real_face = face;
|
||||
s->real_level = level;
|
||||
s->real_zslice = zslice;
|
||||
memset(&s->key, 0, sizeof s->key);
|
||||
}
|
||||
|
||||
return ps;
|
||||
return &s->base;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -663,7 +674,7 @@ svga_tex_surface_destroy(struct pipe_surface *surf)
|
|||
struct svga_screen *ss = svga_screen(surf->texture->screen);
|
||||
|
||||
SVGA_DBG(DEBUG_DMA, "unref sid %p (tex surface)\n", s->handle);
|
||||
ss->sws->surface_reference(ss->sws, &s->handle, NULL);
|
||||
svga_screen_surface_destroy(ss, &s->key, &s->handle);
|
||||
pipe_texture_reference(&surf->texture, NULL);
|
||||
FREE(surf);
|
||||
}
|
||||
|
|
@ -974,7 +985,8 @@ svga_get_tex_sampler_view(struct pipe_context *pipe, struct pipe_texture *pt,
|
|||
sv->handle = svga_texture_view_surface(pipe, tex, format,
|
||||
min_lod,
|
||||
max_lod - min_lod + 1,
|
||||
-1, -1);
|
||||
-1, -1,
|
||||
&sv->key);
|
||||
|
||||
if (!sv->handle) {
|
||||
assert(0);
|
||||
|
|
@ -1030,7 +1042,7 @@ svga_destroy_sampler_view_priv(struct svga_sampler_view *v)
|
|||
struct svga_screen *ss = svga_screen(v->texture->base.screen);
|
||||
|
||||
SVGA_DBG(DEBUG_DMA, "unref sid %p (sampler view)\n", v->handle);
|
||||
ss->sws->surface_reference(ss->sws, &v->handle, NULL);
|
||||
svga_screen_surface_destroy(ss, &v->key, &v->handle);
|
||||
|
||||
FREE(v);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
#include "pipe/p_compiler.h"
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
#include "svga_screen_cache.h"
|
||||
|
||||
struct pipe_context;
|
||||
struct pipe_screen;
|
||||
|
|
@ -68,6 +68,7 @@ struct svga_sampler_view
|
|||
|
||||
unsigned age;
|
||||
|
||||
struct svga_host_surface_cache_key key;
|
||||
struct svga_winsys_surface *handle;
|
||||
};
|
||||
|
||||
|
|
@ -76,8 +77,6 @@ struct svga_texture
|
|||
{
|
||||
struct pipe_texture base;
|
||||
|
||||
struct svga_winsys_surface *handle;
|
||||
|
||||
boolean defined[6][PIPE_MAX_TEXTURE_LEVELS];
|
||||
|
||||
struct svga_sampler_view *cached_view;
|
||||
|
|
@ -86,6 +85,16 @@ struct svga_texture
|
|||
unsigned age;
|
||||
|
||||
boolean views_modified;
|
||||
|
||||
/**
|
||||
* Creation key for the host surface handle.
|
||||
*
|
||||
* This structure describes all the host surface characteristics so that it
|
||||
* can be looked up in cache, since creating a host surface is often a slow
|
||||
* operation.
|
||||
*/
|
||||
struct svga_host_surface_cache_key key;
|
||||
struct svga_winsys_surface *handle;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -93,6 +102,7 @@ struct svga_surface
|
|||
{
|
||||
struct pipe_surface base;
|
||||
|
||||
struct svga_host_surface_cache_key key;
|
||||
struct svga_winsys_surface *handle;
|
||||
|
||||
unsigned real_face;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue