summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/svga/svga_resource_buffer.c13
-rw-r--r--src/gallium/drivers/svga/svga_resource_buffer.h9
-rw-r--r--src/gallium/drivers/svga/svga_resource_buffer_upload.c11
-rw-r--r--src/gallium/drivers/svga/svga_resource_texture.c58
-rw-r--r--src/gallium/drivers/svga/svga_winsys.h1
-rw-r--r--src/gallium/winsys/svga/drm/vmw_context.c1
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen.c6
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen.h2
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen_ioctl.c12
9 files changed, 82 insertions, 31 deletions
diff --git a/src/gallium/drivers/svga/svga_resource_buffer.c b/src/gallium/drivers/svga/svga_resource_buffer.c
index 3f37ef692fa..234d825d5a2 100644
--- a/src/gallium/drivers/svga/svga_resource_buffer.c
+++ b/src/gallium/drivers/svga/svga_resource_buffer.c
@@ -310,16 +310,18 @@ svga_buffer_transfer_flush_region(struct pipe_context *pipe,
{
struct svga_screen *ss = svga_screen(pipe->screen);
struct svga_buffer *sbuf = svga_buffer(transfer->resource);
-
+ struct svga_context *svga = svga_context(pipe);
unsigned offset = transfer->box.x + box->x;
unsigned length = box->width;
assert(transfer->usage & PIPE_TRANSFER_WRITE);
assert(transfer->usage & PIPE_TRANSFER_FLUSH_EXPLICIT);
- mtx_lock(&ss->swc_mutex);
- svga_buffer_add_range(sbuf, offset, offset + length);
- mtx_unlock(&ss->swc_mutex);
+ if (!svga->swc->force_coherent || sbuf->swbuf) {
+ mtx_lock(&ss->swc_mutex);
+ svga_buffer_add_range(sbuf, offset, offset + length);
+ mtx_unlock(&ss->swc_mutex);
+ }
}
@@ -359,7 +361,8 @@ svga_buffer_transfer_unmap(struct pipe_context *pipe,
sbuf->dma.flags.discard = TRUE;
- svga_buffer_add_range(sbuf, 0, sbuf->b.b.width0);
+ if (!svga->swc->force_coherent || sbuf->swbuf)
+ svga_buffer_add_range(sbuf, 0, sbuf->b.b.width0);
}
}
diff --git a/src/gallium/drivers/svga/svga_resource_buffer.h b/src/gallium/drivers/svga/svga_resource_buffer.h
index 464f073b34f..35ed35d61dd 100644
--- a/src/gallium/drivers/svga/svga_resource_buffer.h
+++ b/src/gallium/drivers/svga/svga_resource_buffer.h
@@ -314,6 +314,15 @@ svga_buffer_hw_storage_unmap(struct svga_context *svga,
ret = SVGA3D_BindGBSurface(swc, sbuf->handle);
assert(ret == PIPE_OK);
}
+ if (swc->force_coherent) {
+ ret = SVGA3D_UpdateGBSurface(swc, sbuf->handle);
+ if (ret != PIPE_OK) {
+ /* flush and retry */
+ svga_context_flush(svga, NULL);
+ ret = SVGA3D_UpdateGBSurface(swc, sbuf->handle);
+ assert(ret == PIPE_OK);
+ }
+ }
}
} else
sws->buffer_unmap(sws, sbuf->hwbuf);
diff --git a/src/gallium/drivers/svga/svga_resource_buffer_upload.c b/src/gallium/drivers/svga/svga_resource_buffer_upload.c
index 74c3bc4ed61..64f75231a65 100644
--- a/src/gallium/drivers/svga/svga_resource_buffer_upload.c
+++ b/src/gallium/drivers/svga/svga_resource_buffer_upload.c
@@ -448,6 +448,9 @@ svga_buffer_upload_gb_command(struct svga_context *svga,
struct pipe_resource *dummy;
unsigned i;
+ if (swc->force_coherent)
+ return PIPE_OK;
+
assert(svga_have_gb_objects(svga));
assert(numBoxes);
assert(sbuf->dma.updates == NULL);
@@ -645,7 +648,7 @@ svga_buffer_upload_flush(struct svga_context *svga, struct svga_buffer *sbuf)
unsigned i;
struct pipe_resource *dummy;
- if (!sbuf->dma.pending) {
+ if (!sbuf->dma.pending || svga->swc->force_coherent) {
//debug_printf("no dma pending on buffer\n");
return;
}
@@ -659,6 +662,7 @@ svga_buffer_upload_flush(struct svga_context *svga, struct svga_buffer *sbuf)
*/
if (svga_have_gb_objects(svga)) {
struct svga_3d_update_gb_image *update = sbuf->dma.updates;
+
assert(update);
for (i = 0; i < sbuf->map.num_ranges; ++i, ++update) {
@@ -871,6 +875,9 @@ svga_buffer_update_hw(struct svga_context *svga, struct svga_buffer *sbuf,
memcpy((uint8_t *) map + start, (uint8_t *) sbuf->swbuf + start, len);
}
+ if (svga->swc->force_coherent)
+ sbuf->map.num_ranges = 0;
+
svga_buffer_hw_storage_unmap(svga, sbuf);
/* This user/malloc buffer is now indistinguishable from a gpu buffer */
@@ -1029,6 +1036,8 @@ svga_buffer_handle(struct svga_context *svga, struct pipe_resource *buf,
}
assert(sbuf->handle);
+ if (svga->swc->force_coherent)
+ return sbuf->handle;
if (sbuf->map.num_ranges) {
if (!sbuf->dma.pending) {
diff --git a/src/gallium/drivers/svga/svga_resource_texture.c b/src/gallium/drivers/svga/svga_resource_texture.c
index 307b5ca4a10..0b872da3ed2 100644
--- a/src/gallium/drivers/svga/svga_resource_texture.c
+++ b/src/gallium/drivers/svga/svga_resource_texture.c
@@ -401,21 +401,23 @@ svga_texture_transfer_map_direct(struct svga_context *svga,
svga_surfaces_flush(svga);
- for (i = 0; i < st->box.d; i++) {
- if (svga_have_vgpu10(svga)) {
- ret = readback_image_vgpu10(svga, surf, st->slice + i, level,
- tex->b.b.last_level + 1);
- } else {
- ret = readback_image_vgpu9(svga, surf, st->slice + i, level);
+ if (!svga->swc->force_coherent || tex->imported) {
+ for (i = 0; i < st->box.d; i++) {
+ if (svga_have_vgpu10(svga)) {
+ ret = readback_image_vgpu10(svga, surf, st->slice + i, level,
+ tex->b.b.last_level + 1);
+ } else {
+ ret = readback_image_vgpu9(svga, surf, st->slice + i, level);
+ }
}
- }
- svga->hud.num_readbacks++;
- SVGA_STATS_COUNT_INC(sws, SVGA_STATS_COUNT_TEXREADBACK);
+ svga->hud.num_readbacks++;
+ SVGA_STATS_COUNT_INC(sws, SVGA_STATS_COUNT_TEXREADBACK);
- assert(ret == PIPE_OK);
- (void) ret;
+ assert(ret == PIPE_OK);
+ (void) ret;
- svga_context_flush(svga, NULL);
+ svga_context_flush(svga, NULL);
+ }
/*
* Note: if PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE were specified
* we could potentially clear the flag for all faces/layers/mips.
@@ -694,6 +696,15 @@ svga_texture_surface_unmap(struct svga_context *svga,
ret = SVGA3D_BindGBSurface(swc, surf);
assert(ret == PIPE_OK);
}
+ if (swc->force_coherent) {
+ ret = SVGA3D_UpdateGBSurface(swc, surf);
+ if (ret != PIPE_OK) {
+ /* flush and retry */
+ svga_context_flush(svga, NULL);
+ ret = SVGA3D_UpdateGBSurface(swc, surf);
+ assert(ret == PIPE_OK);
+ }
+ }
}
}
@@ -816,19 +827,22 @@ svga_texture_transfer_unmap_direct(struct svga_context *svga,
box.x, box.y, box.z,
box.w, box.h, box.d);
- if (svga_have_vgpu10(svga)) {
- unsigned i;
+ if (!svga->swc->force_coherent || tex->imported) {
+ if (svga_have_vgpu10(svga)) {
+ unsigned i;
- for (i = 0; i < nlayers; i++) {
- ret = update_image_vgpu10(svga, surf, &box,
- st->slice + i, transfer->level,
- tex->b.b.last_level + 1);
+ for (i = 0; i < nlayers; i++) {
+ ret = update_image_vgpu10(svga, surf, &box,
+ st->slice + i, transfer->level,
+ tex->b.b.last_level + 1);
+ assert(ret == PIPE_OK);
+ }
+ } else {
+ assert(nlayers == 1);
+ ret = update_image_vgpu9(svga, surf, &box, st->slice,
+ transfer->level);
assert(ret == PIPE_OK);
}
- } else {
- assert(nlayers == 1);
- ret = update_image_vgpu9(svga, surf, &box, st->slice, transfer->level);
- assert(ret == PIPE_OK);
}
(void) ret;
}
diff --git a/src/gallium/drivers/svga/svga_winsys.h b/src/gallium/drivers/svga/svga_winsys.h
index 174b5f3b78f..ee39db3bbbc 100644
--- a/src/gallium/drivers/svga/svga_winsys.h
+++ b/src/gallium/drivers/svga/svga_winsys.h
@@ -385,6 +385,7 @@ struct svga_winsys_context
**/
boolean have_gb_objects;
+ boolean force_coherent;
/**
* Map a guest-backed surface.
diff --git a/src/gallium/winsys/svga/drm/vmw_context.c b/src/gallium/winsys/svga/drm/vmw_context.c
index d073cd4859f..8b82a9f90d3 100644
--- a/src/gallium/winsys/svga/drm/vmw_context.c
+++ b/src/gallium/winsys/svga/drm/vmw_context.c
@@ -852,6 +852,7 @@ vmw_svga_winsys_context_create(struct svga_winsys_screen *sws)
vswc->fctx = debug_flush_ctx_create(TRUE, VMW_DEBUG_FLUSH_STACK);
#endif
+ vswc->base.force_coherent = vws->force_coherent;
return &vswc->base;
out_no_hash:
diff --git a/src/gallium/winsys/svga/drm/vmw_screen.c b/src/gallium/winsys/svga/drm/vmw_screen.c
index 56294fec60e..e3440bfd957 100644
--- a/src/gallium/winsys/svga/drm/vmw_screen.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen.c
@@ -90,12 +90,12 @@ vmw_winsys_create( int fd )
vws->device = stat_buf.st_rdev;
vws->open_count = 1;
vws->ioctl.drm_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
- vws->base.have_gb_dma = TRUE;
- vws->base.need_to_rebind_resources = FALSE;
-
+ vws->force_coherent = FALSE;
if (!vmw_ioctl_init(vws))
goto out_no_ioctl;
+ 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;
vws->fence_ops = vmw_fence_ops_create(vws);
if (!vws->fence_ops)
diff --git a/src/gallium/winsys/svga/drm/vmw_screen.h b/src/gallium/winsys/svga/drm/vmw_screen.h
index cb34fec48e7..e0b1bb33bc4 100644
--- a/src/gallium/winsys/svga/drm/vmw_screen.h
+++ b/src/gallium/winsys/svga/drm/vmw_screen.h
@@ -104,6 +104,8 @@ struct vmw_winsys_screen
cnd_t cs_cond;
mtx_t cs_mutex;
+
+ boolean force_coherent;
};
diff --git a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
index 3b14f1d3513..c7310dc7eb4 100644
--- a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
@@ -243,6 +243,9 @@ vmw_ioctl_gb_surface_create(struct vmw_winsys_screen *vws,
if (usage & SVGA_SURFACE_USAGE_SHARED)
req->base.drm_surface_flags |= drm_vmw_surface_flag_shareable;
+ if (vws->force_coherent)
+ req->base.drm_surface_flags |= drm_vmw_surface_flag_coherent;
+
req->base.drm_surface_flags |= drm_vmw_surface_flag_create_buffer;
req->base.base_size.width = size.width;
req->base.base_size.height = size.height;
@@ -969,6 +972,7 @@ vmw_ioctl_init(struct vmw_winsys_screen *vws)
drmVersionPtr version;
boolean drm_gb_capable;
boolean have_drm_2_5;
+ boolean have_drm_2_16;
const char *getenv_val;
VMW_FUNC;
@@ -985,6 +989,8 @@ vmw_ioctl_init(struct vmw_winsys_screen *vws)
(version->version_major == 2 && version->version_minor > 8);
vws->ioctl.have_drm_2_15 = version->version_major > 2 ||
(version->version_major == 2 && version->version_minor > 14);
+ have_drm_2_16 = version->version_major > 2 ||
+ (version->version_major == 2 && version->version_minor > 15);
vws->ioctl.drm_execbuf_version = vws->ioctl.have_drm_2_9 ? 2 : 1;
@@ -1108,6 +1114,12 @@ vmw_ioctl_init(struct vmw_winsys_screen *vws)
vws->ioctl.num_cap_3d = size / sizeof(uint32_t);
else
vws->ioctl.num_cap_3d = SVGA3D_DEVCAP_MAX;
+
+ if (have_drm_2_16) {
+ getenv_val = getenv("SVGA_FORCE_COHERENT");
+ if (getenv_val && strcmp(getenv_val, "0") != 0)
+ vws->force_coherent = TRUE;
+ }
} else {
vws->ioctl.num_cap_3d = SVGA3D_DEVCAP_MAX;