With this patch, we will specify the current context when we invalidate the surface before the surface is put back to the recycled surface pool. This allows the winsys layer to use the specified context to do the invalidation rather than using the last context that referenced the surface. This prevents race condition if the last referenced context is now made current in another thread. Tested with MTT glretrace, NobelClinicianViewer. Reviewed-by: Sinclair Yeh <syeh@vmware.com>tags/17.1-branchpoint
@@ -367,7 +367,7 @@ svga_context_flush(struct svga_context *svga, | |||
svga->hud.num_flushes++; | |||
svga_screen_cache_flush(svgascreen, fence); | |||
svga_screen_cache_flush(svgascreen, svga, fence); | |||
SVGA3D_ResetLastCommand(svga->swc); | |||
@@ -32,6 +32,7 @@ | |||
#include "svga_winsys.h" | |||
#include "svga_screen.h" | |||
#include "svga_screen_cache.h" | |||
#include "svga_context.h" | |||
#define SVGA_SURFACE_CACHE_ENABLED 1 | |||
@@ -310,6 +311,7 @@ svga_screen_cache_add(struct svga_screen *svgascreen, | |||
*/ | |||
void | |||
svga_screen_cache_flush(struct svga_screen *svgascreen, | |||
struct svga_context *svga, | |||
struct pipe_fence_handle *fence) | |||
{ | |||
struct svga_host_surface_cache *cache = &svgascreen->cache; | |||
@@ -357,8 +359,10 @@ svga_screen_cache_flush(struct svga_screen *svgascreen, | |||
/* 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); | |||
/* It is now safe to invalidate the surface content. | |||
* It will be done using the current context. | |||
*/ | |||
svga->swc->surface_invalidate(svga->swc, entry->handle); | |||
/* add the entry to the invalidated list */ | |||
LIST_ADD(&entry->head, &cache->invalidated); |
@@ -53,6 +53,7 @@ | |||
struct svga_winsys_surface; | |||
struct svga_screen; | |||
struct svga_context; | |||
/** | |||
* Same as svga_winsys_screen::surface_create. | |||
@@ -136,6 +137,7 @@ svga_screen_cache_cleanup(struct svga_screen *svgascreen); | |||
void | |||
svga_screen_cache_flush(struct svga_screen *svgascreen, | |||
struct svga_context *svga, | |||
struct pipe_fence_handle *fence); | |||
enum pipe_error |
@@ -391,6 +391,13 @@ struct svga_winsys_context | |||
struct svga_winsys_surface *surface, | |||
boolean *rebind); | |||
/** | |||
* Invalidate the content of this surface | |||
*/ | |||
void | |||
(*surface_invalidate)(struct svga_winsys_context *swc, | |||
struct svga_winsys_surface *surface); | |||
/** | |||
* Create and define a DX GB shader that resides in the device COTable. | |||
* Caller of this function will issue the DXDefineShader command. | |||
@@ -555,14 +562,6 @@ struct svga_winsys_screen | |||
uint32 numLayers, | |||
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. | |||
* |
@@ -808,11 +808,12 @@ vmw_svga_winsys_context_create(struct svga_winsys_screen *sws) | |||
vswc->base.flush = vmw_swc_flush; | |||
vswc->base.surface_map = vmw_svga_winsys_surface_map; | |||
vswc->base.surface_unmap = vmw_svga_winsys_surface_unmap; | |||
vswc->base.surface_invalidate = vmw_svga_winsys_surface_invalidate; | |||
vswc->base.shader_create = vmw_svga_winsys_vgpu10_shader_create; | |||
vswc->base.shader_destroy = vmw_svga_winsys_vgpu10_shader_destroy; | |||
vswc->base.shader_create = vmw_svga_winsys_vgpu10_shader_create; | |||
vswc->base.shader_destroy = vmw_svga_winsys_vgpu10_shader_destroy; | |||
vswc->base.resource_rebind = vmw_svga_winsys_resource_rebind; | |||
vswc->base.resource_rebind = vmw_svga_winsys_resource_rebind; | |||
if (sws->have_vgpu10) | |||
vswc->base.cid = vmw_ioctl_extended_context_create(vws, sws->have_vgpu10); |
@@ -280,18 +280,6 @@ 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) | |||
@@ -434,7 +422,6 @@ 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; |
@@ -176,6 +176,18 @@ vmw_svga_winsys_surface_unmap(struct svga_winsys_context *swc, | |||
mtx_unlock(&vsrf->mutex); | |||
} | |||
void | |||
vmw_svga_winsys_surface_invalidate(struct svga_winsys_context *swc, | |||
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. | |||
*/ | |||
} | |||
void | |||
vmw_svga_winsys_surface_reference(struct vmw_svga_winsys_surface **pdst, | |||
struct vmw_svga_winsys_surface *src) |
@@ -94,5 +94,8 @@ void | |||
vmw_svga_winsys_surface_unmap(struct svga_winsys_context *swc, | |||
struct svga_winsys_surface *srf, | |||
boolean *rebind); | |||
void | |||
vmw_svga_winsys_surface_invalidate(struct svga_winsys_context *swc, | |||
struct svga_winsys_surface *srf); | |||
#endif /* VMW_SURFACE_H_ */ |