diff options
-rw-r--r-- | src/gallium/drivers/svga/svga_screen_cache.c | 37 | ||||
-rw-r--r-- | src/gallium/drivers/svga/svga_screen_cache.h | 14 | ||||
-rw-r--r-- | src/gallium/drivers/svga/svga_winsys.h | 8 | ||||
-rw-r--r-- | src/gallium/winsys/svga/drm/vmw_screen_svga.c | 13 |
4 files changed, 63 insertions, 9 deletions
diff --git a/src/gallium/drivers/svga/svga_screen_cache.c b/src/gallium/drivers/svga/svga_screen_cache.c index eaa589c4c26..4344a87348c 100644 --- a/src/gallium/drivers/svga/svga_screen_cache.c +++ b/src/gallium/drivers/svga/svga_screen_cache.c @@ -320,16 +320,16 @@ svga_screen_cache_flush(struct svga_screen *svgascreen, pipe_mutex_lock(cache->mutex); - /* Loop over entries in the validated list */ - curr = cache->validated.next; + /* Loop over entries in the invalidated list */ + curr = cache->invalidated.next; next = curr->next; - while (curr != &cache->validated) { + while (curr != &cache->invalidated) { entry = LIST_ENTRY(struct svga_host_surface_cache_entry, curr, head); assert(entry->handle); if (sws->surface_is_flushed(sws, entry->handle)) { - /* remove entry from LRU list */ + /* remove entry from the invalidated list */ LIST_DEL(&entry->head); svgascreen->sws->fence_reference(svgascreen->sws, &entry->fence, fence); @@ -346,6 +346,28 @@ svga_screen_cache_flush(struct svga_screen *svgascreen, next = curr->next; } + curr = cache->validated.next; + next = curr->next; + while (curr != &cache->validated) { + entry = LIST_ENTRY(struct svga_host_surface_cache_entry, curr, head); + + assert(entry->handle); + + if (sws->surface_is_flushed(sws, entry->handle)) { + /* remove entry from the validated list */ + LIST_DEL(&entry->head); + + /* it is now safe to invalidate the surface content. */ + sws->surface_invalidate(sws, entry->handle); + + /* add the entry to the invalidated list */ + LIST_ADD(&entry->head, &cache->invalidated); + } + + curr = next; + next = curr->next; + } + pipe_mutex_unlock(cache->mutex); } @@ -396,6 +418,8 @@ svga_screen_cache_init(struct svga_screen *svgascreen) LIST_INITHEAD(&cache->validated); + LIST_INITHEAD(&cache->invalidated); + LIST_INITHEAD(&cache->empty); for (i = 0; i < SVGA_HOST_SURFACE_CACHE_SIZE; ++i) LIST_ADDTAIL(&cache->entries[i].head, &cache->empty); @@ -535,6 +559,11 @@ svga_screen_surface_destroy(struct svga_screen *svgascreen, * that case. */ if (SVGA_SURFACE_CACHE_ENABLED && key->cachable) { + + /* Invalidate the surface before putting it into the recycle pool */ + if (key->format != SVGA3D_BUFFER) + sws->surface_invalidate(sws, *p_handle); + svga_screen_cache_add(svgascreen, key, p_handle); } else { diff --git a/src/gallium/drivers/svga/svga_screen_cache.h b/src/gallium/drivers/svga/svga_screen_cache.h index 05d8c56d83c..9365f751f72 100644 --- a/src/gallium/drivers/svga/svga_screen_cache.h +++ b/src/gallium/drivers/svga/svga_screen_cache.h @@ -95,12 +95,13 @@ struct svga_host_surface_cache_entry * A cache entry can be in the following stages: * 1. empty (entry->handle = NULL) * 2. holding a buffer in a validate list - * 3. holding a flushed buffer (not in any validate list) with an active fence - * 4. holding a flushed buffer with an expired fence + * 3. holding a buffer in an invalidate list + * 4. holding a flushed buffer (not in any validate list) with an active fence + * 5. holding a flushed buffer with an expired fence * - * An entry progresses from 1 -> 2 -> 3 -> 4. When we need an entry to put a + * An entry progresses from 1 -> 2 -> 3 -> 4 -> 5. When we need an entry to put a * buffer into we preferentially take from 1, or from the least recently used - * buffer from 3/4. + * buffer from 4/5. */ struct svga_host_surface_cache { @@ -113,9 +114,12 @@ struct svga_host_surface_cache * (3 and 4) */ struct list_head unused; - /* Entries with buffers still in validate lists (2) */ + /* Entries with buffers still in validate list (2) */ struct list_head validated; + /* Entries with buffers still in invalidate list (3) */ + struct list_head invalidated; + /** Empty entries (1) */ struct list_head empty; diff --git a/src/gallium/drivers/svga/svga_winsys.h b/src/gallium/drivers/svga/svga_winsys.h index b96a8e46c4d..90e4f81da8d 100644 --- a/src/gallium/drivers/svga/svga_winsys.h +++ b/src/gallium/drivers/svga/svga_winsys.h @@ -419,6 +419,14 @@ struct svga_winsys_screen uint32 numMipLevels); /** + * Invalidate the content of this surface + */ + void + (*surface_invalidate)(struct svga_winsys_screen *sws, + struct svga_winsys_surface *surface); + + + /** * Buffer management. Buffer attributes are mostly fixed over its lifetime. * * @param usage bitmask of SVGA_BUFFER_USAGE_* flags. diff --git a/src/gallium/winsys/svga/drm/vmw_screen_svga.c b/src/gallium/winsys/svga/drm/vmw_screen_svga.c index a18dd827c64..f8c9180e9bc 100644 --- a/src/gallium/winsys/svga/drm/vmw_screen_svga.c +++ b/src/gallium/winsys/svga/drm/vmw_screen_svga.c @@ -280,6 +280,18 @@ vmw_svga_winsys_surface_can_create(struct svga_winsys_screen *sws, } +static void +vmw_svga_winsys_surface_invalidate(struct svga_winsys_screen *sws, + struct svga_winsys_surface *surf) +{ + /* this is a noop since surface invalidation is not needed for DMA path. + * DMA is enabled when guest-backed surface is not enabled or + * guest-backed dma is enabled. Since guest-backed dma is enabled + * when guest-backed surface is enabled, that implies DMA is always enabled; + * hence, surface invalidation is not needed. + */ +} + static boolean vmw_svga_winsys_surface_is_flushed(struct svga_winsys_screen *sws, struct svga_winsys_surface *surface) @@ -406,6 +418,7 @@ vmw_winsys_screen_init_svga(struct vmw_winsys_screen *vws) vws->base.surface_is_flushed = vmw_svga_winsys_surface_is_flushed; vws->base.surface_reference = vmw_svga_winsys_surface_ref; vws->base.surface_can_create = vmw_svga_winsys_surface_can_create; + vws->base.surface_invalidate = vmw_svga_winsys_surface_invalidate; vws->base.buffer_create = vmw_svga_winsys_buffer_create; vws->base.buffer_map = vmw_svga_winsys_buffer_map; vws->base.buffer_unmap = vmw_svga_winsys_buffer_unmap; |