X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fwinsys%2Fsvga%2Fdrm%2Fvmw_surface.c;h=25c6d320c7408447ce687afe5265aa071098079f;hb=f41848a9df3c6eb81059edfd63347584790e0a3a;hp=9fadbf95a02e3836352a90cefe9042590c9ae999;hpb=be188289e1bf0e259c91a751c405d54bb99bc5d4;p=mesa.git diff --git a/src/gallium/winsys/svga/drm/vmw_surface.c b/src/gallium/winsys/svga/drm/vmw_surface.c index 9fadbf95a02..25c6d320c74 100644 --- a/src/gallium/winsys/svga/drm/vmw_surface.c +++ b/src/gallium/winsys/svga/drm/vmw_surface.c @@ -34,32 +34,91 @@ #include "vmw_context.h" #include "pipebuffer/pb_bufmgr.h" +void +vmw_svga_winsys_surface_init(struct svga_winsys_screen *sws, + struct svga_winsys_surface *srf, + unsigned surf_size, SVGA3dSurfaceAllFlags flags) +{ + struct vmw_svga_winsys_surface *vsrf = vmw_svga_winsys_surface(srf); + void *data = NULL; + struct pb_buffer *pb_buf; + uint32_t pb_flags; + struct vmw_winsys_screen *vws = vsrf->screen; + pb_flags = PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE; + + struct pb_manager *provider; + struct pb_desc desc; + + mtx_lock(&vsrf->mutex); + data = vmw_svga_winsys_buffer_map(&vws->base, vsrf->buf, pb_flags); + if (data) + goto out_mapped; + + provider = vws->pools.mob_fenced; + memset(&desc, 0, sizeof(desc)); + desc.alignment = 4096; + pb_buf = provider->create_buffer(provider, vsrf->size, &desc); + if (pb_buf != NULL) { + struct svga_winsys_buffer *vbuf = + vmw_svga_winsys_buffer_wrap(pb_buf); + + data = vmw_svga_winsys_buffer_map(&vws->base, vbuf, pb_flags); + if (data) { + vsrf->rebind = TRUE; + if (vsrf->buf) + vmw_svga_winsys_buffer_destroy(&vws->base, vsrf->buf); + vsrf->buf = vbuf; + goto out_mapped; + } else { + vmw_svga_winsys_buffer_destroy(&vws->base, vbuf); + goto out_unlock; + } + } + else { + /* Cannot create a buffer, just unlock */ + goto out_unlock; + } + +out_mapped: + mtx_unlock(&vsrf->mutex); + if (data) { + if (flags & SVGA3D_SURFACE_BIND_STREAM_OUTPUT) { + memset(data, 0, surf_size + sizeof(SVGA3dDXSOState)); + } + else { + memset(data, 0, surf_size); + } + } + + mtx_lock(&vsrf->mutex); + vmw_svga_winsys_buffer_unmap(&vsrf->screen->base, vsrf->buf); +out_unlock: + mtx_unlock(&vsrf->mutex); +} + + + 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; struct pb_buffer *pb_buf; uint32_t pb_flags; struct vmw_winsys_screen *vws = vsrf->screen; - + *retry = FALSE; + *rebind = FALSE; assert((flags & (PIPE_TRANSFER_READ | PIPE_TRANSFER_WRITE)) != 0); - pipe_mutex_lock(vsrf->mutex); + mtx_lock(&vsrf->mutex); if (vsrf->mapcount) { - /* - * Only allow multiple readers to map. - */ - if ((flags & PIPE_TRANSFER_WRITE) || - (vsrf->map_mode & PIPE_TRANSFER_WRITE)) - goto out_unlock; - - data = vsrf->data; - goto out_mapped; + /* Other mappers will get confused if we discard. */ + flags &= ~PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE; } vsrf->rebind = FALSE; @@ -89,7 +148,8 @@ vmw_svga_winsys_surface_map(struct svga_winsys_context *swc, goto out_unlock; } - pb_flags = flags & (PIPE_TRANSFER_READ_WRITE | PIPE_TRANSFER_UNSYNCHRONIZED); + pb_flags = flags & (PIPE_TRANSFER_READ_WRITE | PIPE_TRANSFER_UNSYNCHRONIZED | + PIPE_TRANSFER_PERSISTENT); if (flags & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) { struct pb_manager *provider; @@ -127,6 +187,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); @@ -154,7 +220,7 @@ out_mapped: vsrf->data = data; vsrf->map_mode = flags & (PIPE_TRANSFER_READ | PIPE_TRANSFER_WRITE); out_unlock: - pipe_mutex_unlock(vsrf->mutex); + mtx_unlock(&vsrf->mutex); return data; } @@ -165,15 +231,15 @@ vmw_svga_winsys_surface_unmap(struct svga_winsys_context *swc, boolean *rebind) { struct vmw_svga_winsys_surface *vsrf = vmw_svga_winsys_surface(srf); - pipe_mutex_lock(vsrf->mutex); + mtx_lock(&vsrf->mutex); if (--vsrf->mapcount == 0) { *rebind = vsrf->rebind; vsrf->rebind = FALSE; - vmw_svga_winsys_buffer_unmap(&vsrf->screen->base, vsrf->buf); } else { *rebind = FALSE; } - pipe_mutex_unlock(vsrf->mutex); + vmw_svga_winsys_buffer_unmap(&vsrf->screen->base, vsrf->buf); + mtx_unlock(&vsrf->mutex); } void