diff options
-rw-r--r-- | src/gallium/drivers/svga/svga_resource_buffer.h | 18 | ||||
-rw-r--r-- | src/gallium/drivers/svga/svga_resource_texture.c | 18 | ||||
-rw-r--r-- | src/gallium/drivers/svga/svga_winsys.h | 7 | ||||
-rw-r--r-- | src/gallium/winsys/svga/drm/vmw_surface.c | 10 | ||||
-rw-r--r-- | src/gallium/winsys/svga/drm/vmw_surface.h | 5 |
5 files changed, 50 insertions, 8 deletions
diff --git a/src/gallium/drivers/svga/svga_resource_buffer.h b/src/gallium/drivers/svga/svga_resource_buffer.h index 35ed35d61dd..b3559446fa9 100644 --- a/src/gallium/drivers/svga/svga_resource_buffer.h +++ b/src/gallium/drivers/svga/svga_resource_buffer.h @@ -285,7 +285,23 @@ svga_buffer_hw_storage_map(struct svga_context *svga, svga->hud.num_buffers_mapped++; if (sws->have_gb_objects) { - return svga->swc->surface_map(svga->swc, sbuf->handle, flags, retry); + struct svga_winsys_context *swc = svga->swc; + boolean rebind; + void *map; + + map = swc->surface_map(swc, sbuf->handle, flags, retry, &rebind); + if (map && rebind) { + enum pipe_error ret; + + ret = SVGA3D_BindGBSurface(swc, sbuf->handle); + if (ret != PIPE_OK) { + svga_context_flush(svga, NULL); + ret = SVGA3D_BindGBSurface(swc, sbuf->handle); + assert(ret == PIPE_OK); + } + svga_context_flush(svga, NULL); + } + return map; } else { *retry = FALSE; return sws->buffer_map(sws, sbuf->hwbuf, flags); diff --git a/src/gallium/drivers/svga/svga_resource_texture.c b/src/gallium/drivers/svga/svga_resource_texture.c index 4cc58e001c0..58b2f64d0b7 100644 --- a/src/gallium/drivers/svga/svga_resource_texture.c +++ b/src/gallium/drivers/svga/svga_resource_texture.c @@ -458,10 +458,11 @@ svga_texture_transfer_map_direct(struct svga_context *svga, { SVGA3dSize baseLevelSize; uint8_t *map; - boolean retry; + boolean retry, rebind; unsigned offset, mip_width, mip_height; + struct svga_winsys_context *swc = svga->swc; - map = svga->swc->surface_map(svga->swc, surf, usage, &retry); + map = swc->surface_map(swc, surf, usage, &retry, &rebind); if (map == NULL && retry) { /* * At this point, the svga_surfaces_flush() should already have @@ -469,7 +470,18 @@ svga_texture_transfer_map_direct(struct svga_context *svga, */ svga->hud.surface_write_flushes++; svga_context_flush(svga, NULL); - map = svga->swc->surface_map(svga->swc, surf, usage, &retry); + map = swc->surface_map(swc, surf, usage, &retry, &rebind); + } + if (map && rebind) { + enum pipe_error ret; + + ret = SVGA3D_BindGBSurface(swc, surf); + if (ret != PIPE_OK) { + svga_context_flush(svga, NULL); + ret = SVGA3D_BindGBSurface(swc, surf); + assert(ret == PIPE_OK); + } + svga_context_flush(svga, NULL); } /* diff --git a/src/gallium/drivers/svga/svga_winsys.h b/src/gallium/drivers/svga/svga_winsys.h index 30d3f8776d9..20096c036c9 100644 --- a/src/gallium/drivers/svga/svga_winsys.h +++ b/src/gallium/drivers/svga/svga_winsys.h @@ -390,7 +390,11 @@ struct svga_winsys_context /** * Map a guest-backed surface. + * \param swc The winsys context + * \param surface The surface to map * \param flags bitmaks of PIPE_TRANSFER_x flags + * \param retry Whether to flush and retry the map + * \param rebind Whether to issue an immediate rebind and flush. * * The surface_map() member is allowed to fail due to a * shortage of command buffer space, if the @@ -401,7 +405,8 @@ struct svga_winsys_context void * (*surface_map)(struct svga_winsys_context *swc, struct svga_winsys_surface *surface, - unsigned flags, boolean *retry); + unsigned flags, boolean *retry, + boolean *rebind); /** * Unmap a guest-backed surface. diff --git a/src/gallium/winsys/svga/drm/vmw_surface.c b/src/gallium/winsys/svga/drm/vmw_surface.c index 6aa09e11b76..698cd11a28e 100644 --- a/src/gallium/winsys/svga/drm/vmw_surface.c +++ b/src/gallium/winsys/svga/drm/vmw_surface.c @@ -38,7 +38,8 @@ void * vmw_svga_winsys_surface_map(struct svga_winsys_context *swc, struct svga_winsys_surface *srf, - unsigned flags, boolean *retry) + unsigned flags, boolean *retry, + boolean *rebind) { struct vmw_svga_winsys_surface *vsrf = vmw_svga_winsys_surface(srf); void *data = NULL; @@ -47,6 +48,7 @@ vmw_svga_winsys_surface_map(struct svga_winsys_context *swc, struct vmw_winsys_screen *vws = vsrf->screen; *retry = FALSE; + *rebind = FALSE; assert((flags & (PIPE_TRANSFER_READ | PIPE_TRANSFER_WRITE)) != 0); mtx_lock(&vsrf->mutex); @@ -121,6 +123,12 @@ vmw_svga_winsys_surface_map(struct svga_winsys_context *swc, if (vsrf->buf) vmw_svga_winsys_buffer_destroy(&vws->base, vsrf->buf); vsrf->buf = vbuf; + + /* Rebind persistent maps immediately */ + if (flags & PIPE_TRANSFER_PERSISTENT) { + *rebind = TRUE; + vsrf->rebind = FALSE; + } goto out_mapped; } else vmw_svga_winsys_buffer_destroy(&vws->base, vbuf); diff --git a/src/gallium/winsys/svga/drm/vmw_surface.h b/src/gallium/winsys/svga/drm/vmw_surface.h index b1a1ce746b3..ab75fed5f97 100644 --- a/src/gallium/winsys/svga/drm/vmw_surface.h +++ b/src/gallium/winsys/svga/drm/vmw_surface.h @@ -88,8 +88,9 @@ vmw_svga_winsys_surface_reference(struct vmw_svga_winsys_surface **pdst, struct vmw_svga_winsys_surface *src); void * vmw_svga_winsys_surface_map(struct svga_winsys_context *swc, - struct svga_winsys_surface *srf, - unsigned flags, boolean *retry); + struct svga_winsys_surface *srf, + unsigned flags, boolean *retry, + boolean *rebind); void vmw_svga_winsys_surface_unmap(struct svga_winsys_context *swc, struct svga_winsys_surface *srf, |