summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gallium/winsys/svga/drm/vmw_buffer.c17
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen.c3
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen.h1
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen_ioctl.c13
4 files changed, 22 insertions, 12 deletions
diff --git a/src/gallium/winsys/svga/drm/vmw_buffer.c b/src/gallium/winsys/svga/drm/vmw_buffer.c
index e2ddf78ed2e..03db92a6481 100644
--- a/src/gallium/winsys/svga/drm/vmw_buffer.c
+++ b/src/gallium/winsys/svga/drm/vmw_buffer.c
@@ -63,6 +63,7 @@ struct vmw_gmr_buffer
struct vmw_region *region;
void *map;
unsigned map_flags;
+ unsigned map_count;
};
@@ -104,8 +105,12 @@ vmw_gmr_buffer_destroy(struct pb_buffer *_buf)
{
struct vmw_gmr_buffer *buf = vmw_gmr_buffer(_buf);
- vmw_ioctl_region_unmap(buf->region);
-
+ assert(buf->map_count == 0);
+ if (buf->map) {
+ assert(buf->mgr->vws->cache_maps);
+ vmw_ioctl_region_unmap(buf->region);
+ }
+
vmw_ioctl_region_destroy(buf->region);
FREE(buf);
@@ -126,7 +131,6 @@ vmw_gmr_buffer_map(struct pb_buffer *_buf,
if (!buf->map)
return NULL;
-
if ((_buf->usage & VMW_BUFFER_USAGE_SYNC) &&
!(flags & PB_USAGE_UNSYNCHRONIZED)) {
ret = vmw_ioctl_syncforcpu(buf->region,
@@ -137,6 +141,7 @@ vmw_gmr_buffer_map(struct pb_buffer *_buf,
return NULL;
}
+ buf->map_count++;
return buf->map;
}
@@ -153,6 +158,12 @@ vmw_gmr_buffer_unmap(struct pb_buffer *_buf)
!(flags & PB_USAGE_CPU_WRITE),
FALSE);
}
+
+ assert(buf->map_count > 0);
+ if (!--buf->map_count && !buf->mgr->vws->cache_maps) {
+ vmw_ioctl_region_unmap(buf->region);
+ buf->map = NULL;
+ }
}
diff --git a/src/gallium/winsys/svga/drm/vmw_screen.c b/src/gallium/winsys/svga/drm/vmw_screen.c
index 8b4b89981b2..2f70212de61 100644
--- a/src/gallium/winsys/svga/drm/vmw_screen.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen.c
@@ -67,6 +67,7 @@ vmw_winsys_create( int fd )
{
struct vmw_winsys_screen *vws;
struct stat stat_buf;
+ const char *getenv_val;
if (dev_hash == NULL) {
dev_hash = _mesa_hash_table_create(NULL, vmw_dev_hash, vmw_dev_compare);
@@ -97,6 +98,8 @@ vmw_winsys_create( int fd )
vws->base.have_gb_dma = !vws->force_coherent;
vws->base.need_to_rebind_resources = FALSE;
vws->base.have_transfer_from_buffer_cmd = vws->base.have_vgpu10;
+ getenv_val = getenv("SVGA_FORCE_KERNEL_UNMAPS");
+ vws->cache_maps = !getenv_val || strcmp(getenv_val, "0") == 0;
vws->fence_ops = vmw_fence_ops_create(vws);
if (!vws->fence_ops)
goto out_no_fence_ops;
diff --git a/src/gallium/winsys/svga/drm/vmw_screen.h b/src/gallium/winsys/svga/drm/vmw_screen.h
index c55de4a2b6f..4cf6b3fd895 100644
--- a/src/gallium/winsys/svga/drm/vmw_screen.h
+++ b/src/gallium/winsys/svga/drm/vmw_screen.h
@@ -108,6 +108,7 @@ struct vmw_winsys_screen
mtx_t cs_mutex;
boolean force_coherent;
+ boolean cache_maps;
};
diff --git a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
index 9696f884e4f..bb3a1adedc1 100644
--- a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
@@ -64,7 +64,6 @@ struct vmw_region
uint32_t handle;
uint64_t map_handle;
void *data;
- uint32_t map_count;
int drm_fd;
uint32_t size;
};
@@ -637,7 +636,6 @@ vmw_ioctl_region_create(struct vmw_winsys_screen *vws, uint32_t size)
region->data = NULL;
region->handle = rep->handle;
region->map_handle = rep->map_handle;
- region->map_count = 0;
region->size = size;
region->drm_fd = vws->ioctl.drm_fd;
@@ -659,10 +657,7 @@ vmw_ioctl_region_destroy(struct vmw_region *region)
vmw_printf("%s: gmrId = %u, offset = %u\n", __FUNCTION__,
region->ptr.gmrId, region->ptr.offset);
- if (region->data) {
- os_munmap(region->data, region->size);
- region->data = NULL;
- }
+ assert(region->data == NULL);
memset(&arg, 0, sizeof(arg));
arg.handle = region->handle;
@@ -701,8 +696,6 @@ vmw_ioctl_region_map(struct vmw_region *region)
region->data = map;
}
- ++region->map_count;
-
return region->data;
}
@@ -711,7 +704,9 @@ vmw_ioctl_region_unmap(struct vmw_region *region)
{
vmw_printf("%s: gmrId = %u, offset = %u\n", __FUNCTION__,
region->ptr.gmrId, region->ptr.offset);
- --region->map_count;
+
+ os_munmap(region->data, region->size);
+ region->data = NULL;
}
/**