X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fwinsys%2Fsvga%2Fdrm%2Fvmw_buffer.c;h=3ac80c7caf530290893551b319996d1c9ac9d618;hb=48d743c5019076056739561f979e7101c04acf21;hp=80d5dfc3ed49f107bc07c059a02012c614b61989;hpb=b922a0ce12916a91cfc3e56714913fcf63279ff2;p=mesa.git diff --git a/src/gallium/winsys/svga/drm/vmw_buffer.c b/src/gallium/winsys/svga/drm/vmw_buffer.c index 80d5dfc3ed4..3ac80c7caf5 100644 --- a/src/gallium/winsys/svga/drm/vmw_buffer.c +++ b/src/gallium/winsys/svga/drm/vmw_buffer.c @@ -1,5 +1,5 @@ /********************************************************** - * Copyright 2009 VMware, Inc. All rights reserved. + * Copyright 2009-2015 VMware, Inc. All rights reserved. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -51,7 +51,6 @@ #include "vmw_screen.h" #include "vmw_buffer.h" - struct vmw_gmr_bufmgr; @@ -63,17 +62,14 @@ struct vmw_gmr_buffer struct vmw_region *region; void *map; - -#ifdef DEBUG - struct pipe_fence_handle *last_fence; -#endif + unsigned map_flags; }; extern const struct pb_vtbl vmw_gmr_buffer_vtbl; -static INLINE struct vmw_gmr_buffer * +static inline struct vmw_gmr_buffer * vmw_gmr_buffer(struct pb_buffer *buf) { assert(buf); @@ -90,7 +86,7 @@ struct vmw_gmr_bufmgr }; -static INLINE struct vmw_gmr_bufmgr * +static inline struct vmw_gmr_bufmgr * vmw_gmr_bufmgr(struct pb_manager *mgr) { assert(mgr); @@ -103,13 +99,6 @@ vmw_gmr_buffer_destroy(struct pb_buffer *_buf) { struct vmw_gmr_buffer *buf = vmw_gmr_buffer(_buf); -#ifdef DEBUG - if(buf->last_fence) { - struct svga_winsys_screen *sws = &buf->mgr->vws->base; - assert(sws->fence_signalled(sws, buf->last_fence, 0) == 0); - } -#endif - vmw_ioctl_region_unmap(buf->region); vmw_ioctl_region_destroy(buf->region); @@ -124,6 +113,25 @@ vmw_gmr_buffer_map(struct pb_buffer *_buf, void *flush_ctx) { struct vmw_gmr_buffer *buf = vmw_gmr_buffer(_buf); + int ret; + + if (!buf->map) + buf->map = vmw_ioctl_region_map(buf->region); + + if (!buf->map) + return NULL; + + + if ((_buf->usage & VMW_BUFFER_USAGE_SYNC) && + !(flags & PB_USAGE_UNSYNCHRONIZED)) { + ret = vmw_ioctl_syncforcpu(buf->region, + !!(flags & PB_USAGE_DONTBLOCK), + !(flags & PB_USAGE_CPU_WRITE), + FALSE); + if (ret) + return NULL; + } + return buf->map; } @@ -131,15 +139,22 @@ vmw_gmr_buffer_map(struct pb_buffer *_buf, static void vmw_gmr_buffer_unmap(struct pb_buffer *_buf) { - /* Do nothing */ - (void)_buf; + struct vmw_gmr_buffer *buf = vmw_gmr_buffer(_buf); + unsigned flags = buf->map_flags; + + if ((_buf->usage & VMW_BUFFER_USAGE_SYNC) && + !(flags & PB_USAGE_UNSYNCHRONIZED)) { + vmw_ioctl_releasefromcpu(buf->region, + !(flags & PB_USAGE_CPU_WRITE), + FALSE); + } } static void vmw_gmr_buffer_get_base_buffer(struct pb_buffer *buf, struct pb_buffer **base_buf, - unsigned *offset) + pb_size *offset) { *base_buf = buf; *offset = 0; @@ -162,11 +177,6 @@ vmw_gmr_buffer_fence( struct pb_buffer *_buf, { /* We don't need to do anything, as the pipebuffer library * will take care of delaying the destruction of fenced buffers */ -#ifdef DEBUG - struct vmw_gmr_buffer *buf = vmw_gmr_buffer(_buf); - if(fence) - buf->last_fence = fence; -#endif } @@ -183,35 +193,33 @@ const struct pb_vtbl vmw_gmr_buffer_vtbl = { static struct pb_buffer * vmw_gmr_bufmgr_create_buffer(struct pb_manager *_mgr, pb_size size, - const struct pb_desc *desc) + const struct pb_desc *pb_desc) { struct vmw_gmr_bufmgr *mgr = vmw_gmr_bufmgr(_mgr); struct vmw_winsys_screen *vws = mgr->vws; struct vmw_gmr_buffer *buf; + const struct vmw_buffer_desc *desc = + (const struct vmw_buffer_desc *) pb_desc; buf = CALLOC_STRUCT(vmw_gmr_buffer); if(!buf) goto error1; - pipe_reference_init(&buf->base.base.reference, 1); - buf->base.base.alignment = desc->alignment; - buf->base.base.usage = desc->usage; - buf->base.base.size = size; + pipe_reference_init(&buf->base.reference, 1); + buf->base.alignment = pb_desc->alignment; + buf->base.usage = pb_desc->usage & ~VMW_BUFFER_USAGE_SHARED; buf->base.vtbl = &vmw_gmr_buffer_vtbl; buf->mgr = mgr; - - buf->region = vmw_ioctl_region_create(vws, size); - if(!buf->region) - goto error2; + buf->base.size = size; + if ((pb_desc->usage & VMW_BUFFER_USAGE_SHARED) && desc->region) { + buf->region = desc->region; + } else { + buf->region = vmw_ioctl_region_create(vws, size); + if(!buf->region) + goto error2; + } - buf->map = vmw_ioctl_region_map(buf->region); - if(!buf->map) - goto error3; - return &buf->base; - -error3: - vmw_ioctl_region_destroy(buf->region); error2: FREE(buf); error1: @@ -258,7 +266,7 @@ vmw_gmr_bufmgr_region_ptr(struct pb_buffer *buf, struct SVGAGuestPtr *ptr) { struct pb_buffer *base_buf; - unsigned offset = 0; + pb_size offset = 0; struct vmw_gmr_buffer *gmr_buf; pb_get_base_buffer( buf, &base_buf, &offset ); @@ -273,3 +281,91 @@ vmw_gmr_bufmgr_region_ptr(struct pb_buffer *buf, return TRUE; } + +#ifdef DEBUG +struct svga_winsys_buffer { + struct pb_buffer *pb_buf; + struct debug_flush_buf *fbuf; +}; + +struct pb_buffer * +vmw_pb_buffer(struct svga_winsys_buffer *buffer) +{ + assert(buffer); + return buffer->pb_buf; +} + +struct svga_winsys_buffer * +vmw_svga_winsys_buffer_wrap(struct pb_buffer *buffer) +{ + struct svga_winsys_buffer *buf; + + if (!buffer) + return NULL; + + buf = CALLOC_STRUCT(svga_winsys_buffer); + if (!buf) { + pb_reference(&buffer, NULL); + return NULL; + } + + buf->pb_buf = buffer; + buf->fbuf = debug_flush_buf_create(TRUE, VMW_DEBUG_FLUSH_STACK); + return buf; +} + +struct debug_flush_buf * +vmw_debug_flush_buf(struct svga_winsys_buffer *buffer) +{ + return buffer->fbuf; +} + +#endif + +void +vmw_svga_winsys_buffer_destroy(struct svga_winsys_screen *sws, + struct svga_winsys_buffer *buf) +{ + struct pb_buffer *pbuf = vmw_pb_buffer(buf); + (void)sws; + pb_reference(&pbuf, NULL); +#ifdef DEBUG + debug_flush_buf_reference(&buf->fbuf, NULL); + FREE(buf); +#endif +} + +void * +vmw_svga_winsys_buffer_map(struct svga_winsys_screen *sws, + struct svga_winsys_buffer *buf, + unsigned flags) +{ + void *map; + + (void)sws; + if (flags & PIPE_TRANSFER_UNSYNCHRONIZED) + flags &= ~PIPE_TRANSFER_DONTBLOCK; + + map = pb_map(vmw_pb_buffer(buf), flags, NULL); + +#ifdef DEBUG + if (map != NULL) + debug_flush_map(buf->fbuf, flags); +#endif + + return map; +} + + +void +vmw_svga_winsys_buffer_unmap(struct svga_winsys_screen *sws, + struct svga_winsys_buffer *buf) +{ + (void)sws; + +#ifdef DEBUG + debug_flush_unmap(buf->fbuf); +#endif + + pb_unmap(vmw_pb_buffer(buf)); +}