summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/svga/svga_screen_cache.c37
-rw-r--r--src/gallium/drivers/svga/svga_screen_cache.h14
-rw-r--r--src/gallium/drivers/svga/svga_winsys.h8
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen_svga.c13
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;