[Mesa-dev] [PATCH] winsys/svga: use new ioctl for logging

2020-01-21 Thread VMware
From: Roland Scheidegger 

Use the new ioctl for logging (rather than duplicating what the kernel
is doing). This way it's also independent from the actual guest/host
mechanism to do the logging.

Signed-off-by: Roland Scheidegger 
Reviewed-by: Thomas Hellstrom 
---
 src/gallium/winsys/svga/drm/vmw_msg.c | 22 ---
 src/gallium/winsys/svga/drm/vmw_screen.h  |  2 ++
 .../winsys/svga/drm/vmw_screen_ioctl.c|  7 +++---
 src/gallium/winsys/svga/drm/vmwgfx_drm.h  | 17 ++
 4 files changed, 42 insertions(+), 6 deletions(-)

diff --git a/src/gallium/winsys/svga/drm/vmw_msg.c 
b/src/gallium/winsys/svga/drm/vmw_msg.c
index 2a2d6a61297..e664769c279 100644
--- a/src/gallium/winsys/svga/drm/vmw_msg.c
+++ b/src/gallium/winsys/svga/drm/vmw_msg.c
@@ -31,6 +31,9 @@
 #include "pipe/p_defines.h"
 #include "svga_winsys.h"
 #include "vmw_msg.h"
+#include "vmwgfx_drm.h"
+#include "vmw_screen.h"
+#include "xf86drm.h"
 
 
 #define MESSAGE_STATUS_SUCCESS  0x0001
@@ -424,6 +427,7 @@ void
 vmw_svga_winsys_host_log(struct svga_winsys_screen *sws, const char *log)
 {
struct rpc_channel channel;
+   struct vmw_winsys_screen *vws = vmw_winsys_screen(sws);
char *msg;
int msg_len;
int ret;
@@ -444,9 +448,21 @@ vmw_svga_winsys_host_log(struct svga_winsys_screen *sws, 
const char *log)
 
sprintf(msg, "log %s", log);
 
-   if (!(ret = vmw_open_channel(, RPCI_PROTOCOL_NUM))) {
-  ret = vmw_send_msg(, msg);
-  vmw_close_channel();
+   if (vws->ioctl.have_drm_2_17) {
+  struct drm_vmw_msg_arg msg_arg;
+
+  memset(_arg, 0, sizeof(msg_arg));
+  msg_arg.send = (uint64_t) (unsigned long) (msg);
+  msg_arg.send_only = 1;
+
+  ret = drmCommandWriteRead(vws->ioctl.drm_fd, DRM_VMW_MSG,
+_arg, sizeof(msg_arg));
+
+   } else {
+  if (!(ret = vmw_open_channel(, RPCI_PROTOCOL_NUM))) {
+ ret = vmw_send_msg(, msg);
+ vmw_close_channel();
+  }
}
 
if (ret)
diff --git a/src/gallium/winsys/svga/drm/vmw_screen.h 
b/src/gallium/winsys/svga/drm/vmw_screen.h
index e0b1bb33bc4..c55de4a2b6f 100644
--- a/src/gallium/winsys/svga/drm/vmw_screen.h
+++ b/src/gallium/winsys/svga/drm/vmw_screen.h
@@ -78,6 +78,8 @@ struct vmw_winsys_screen
   boolean have_drm_2_9;
   uint32_t drm_execbuf_version;
   boolean have_drm_2_15;
+  boolean have_drm_2_16;
+  boolean have_drm_2_17;
} ioctl;
 
struct {
diff --git a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c 
b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
index 2e84c811e82..4ce953fee8d 100644
--- a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
@@ -973,7 +973,6 @@ 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;
@@ -990,8 +989,10 @@ 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 ||
+   vws->ioctl.have_drm_2_16 = version->version_major > 2 ||
   (version->version_major == 2 && version->version_minor > 15);
+   vws->ioctl.have_drm_2_17 = version->version_major > 2 ||
+  (version->version_major == 2 && version->version_minor > 16);
 
vws->ioctl.drm_execbuf_version = vws->ioctl.have_drm_2_9 ? 2 : 1;
 
@@ -1116,7 +1117,7 @@ vmw_ioctl_init(struct vmw_winsys_screen *vws)
   else
  vws->ioctl.num_cap_3d = SVGA3D_DEVCAP_MAX;
 
-  if (have_drm_2_16) {
+  if (vws->ioctl.have_drm_2_16) {
  vws->base.have_coherent = TRUE;
  getenv_val = getenv("SVGA_FORCE_COHERENT");
  if (getenv_val && strcmp(getenv_val, "0") != 0)
diff --git a/src/gallium/winsys/svga/drm/vmwgfx_drm.h 
b/src/gallium/winsys/svga/drm/vmwgfx_drm.h
index 02cab33f2f2..fcb741e3068 100644
--- a/src/gallium/winsys/svga/drm/vmwgfx_drm.h
+++ b/src/gallium/winsys/svga/drm/vmwgfx_drm.h
@@ -71,6 +71,7 @@ extern "C" {
 #define DRM_VMW_CREATE_EXTENDED_CONTEXT 26
 #define DRM_VMW_GB_SURFACE_CREATE_EXT   27
 #define DRM_VMW_GB_SURFACE_REF_EXT  28
+#define DRM_VMW_MSG 29
 
 /*/
 /**
@@ -1213,6 +1214,22 @@ union drm_vmw_gb_surface_reference_ext_arg {
struct drm_vmw_surface_arg req;
 };
 
+/**
+ * struct drm_vmw_msg_arg
+ *
+ * @send: Pointer to user-space msg string (null terminated).
+ * @receive: Pointer to user-space receive buffer.
+ * @send_only: Boolean whether this is only sending or receiving too.
+ *
+ * Argument to the DRM_VMW_MSG ioctl.
+ */
+struct drm_vmw_msg_arg {
+   __u64 send;
+   __u64 receive;
+   __s32 send_only;
+   __u32 receive_len;
+};
+
 #if defined(__cplusplus)
 }
 #endif

[Mesa-dev] [PATCH 1/2] svga: Fix banded DMA upload unmap

2019-10-09 Thread VMware
From: Thomas Hellstrom 

Even with banded DMA uploads, st->hwbuf is always non-NULL, but when we've
allocated a software buffer to hold the full upload, unmapping of the
hardware buffer has already been done before
svga_texture_transfer_unmap_dma(), and the code was performing an unmap of
an already mapped buffer.

Fix this by testing for software buffer not present.

Fixes: a9c4a861d5d ("svga: refactor svga_texture_transfer_map/unmap functions")
Signed-off-by: Thomas Hellstrom 
Reviewed-by: Brian Paul 
Reviewed-by: Charmaine Lee 
Reviewed-by: Roland Scheidegger 
---
 src/gallium/drivers/svga/svga_resource_texture.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/gallium/drivers/svga/svga_resource_texture.c 
b/src/gallium/drivers/svga/svga_resource_texture.c
index b04542d711a..f1d16563efb 100644
--- a/src/gallium/drivers/svga/svga_resource_texture.c
+++ b/src/gallium/drivers/svga/svga_resource_texture.c
@@ -758,7 +758,7 @@ svga_texture_transfer_unmap_dma(struct svga_context *svga,
 {
struct svga_winsys_screen *sws = svga_screen(svga->pipe.screen)->sws;
 
-   if (st->hwbuf)
+   if (!st->swbuf)
   sws->buffer_unmap(sws, st->hwbuf);
 
if (st->base.usage & PIPE_TRANSFER_WRITE) {
-- 
2.21.0

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

[Mesa-dev] [PATCH 2/2] winsys/svga: Limit the maximum DMA hardware buffer size

2019-10-09 Thread VMware
From: Thomas Hellstrom 

The kernel total GMR/DMA size is limited, but it's definitely possible for the
kernel to allow a larger buffer allocation to succeed, but command
submission using that buffer as a GMR would fail typically causing an
application crash.

So have the winsys limit the size of GMR/DMA buffers. The pipe driver will
then resort to allocating smaller buffers and perform the DMA transfer in
multiple bands, also allowing for the pre-flush mechanism to kick in.

This avoids the related application crashes.

Fixes: e7843273fae ("winsys/svga: Update to vmwgfx kernel module 2.1")
Signed-off-by: Thomas Hellstrom 
Reviewed-by: Brian Paul 
Reviewed-by: Charmaine Lee 
Reviewed-by: Roland Scheidegger 
---
 src/gallium/winsys/svga/drm/vmw_screen_svga.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/gallium/winsys/svga/drm/vmw_screen_svga.c 
b/src/gallium/winsys/svga/drm/vmw_screen_svga.c
index cd3f21f6033..fb0bee77822 100644
--- a/src/gallium/winsys/svga/drm/vmw_screen_svga.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen_svga.c
@@ -80,8 +80,11 @@ vmw_svga_winsys_buffer_create(struct svga_winsys_screen *sws,
   provider = vws->pools.query_fenced;
} else if (usage == SVGA_BUFFER_USAGE_SHADER) {
   provider = vws->pools.mob_shader_slab_fenced;
-   } else
+   } else {
+  if (size > VMW_GMR_POOL_SIZE)
+ return NULL;
   provider = vws->pools.gmr_fenced;
+   }
 
assert(provider);
buffer = provider->create_buffer(provider, size, _desc);
-- 
2.21.0

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

[Mesa-dev] [PATCH 1/6] gallium/util: Make u_debug_flush support persistent maps

2019-06-19 Thread VMware
From: Thomas Hellstrom 

Previously unsynchronized maps have been assumed to also be persistent,
Now destinguish between persistent and unsynchronized map and also support
PIPE_TRANSFER_PERSISTENT from ARB_buffer_storage.

Signed-off-by: Thomas Hellstrom 
Reviewed-by: Brian Paul 
---
 src/gallium/auxiliary/util/u_debug_flush.c | 91 +++---
 src/gallium/auxiliary/util/u_debug_flush.h |  4 +-
 2 files changed, 66 insertions(+), 29 deletions(-)

diff --git a/src/gallium/auxiliary/util/u_debug_flush.c 
b/src/gallium/auxiliary/util/u_debug_flush.c
index c49af095ed1..c0be6681800 100644
--- a/src/gallium/auxiliary/util/u_debug_flush.c
+++ b/src/gallium/auxiliary/util/u_debug_flush.c
@@ -50,17 +50,26 @@
 #include "os/os_thread.h"
 #include 
 
+/* Future improvement: Use realloc instead? */
+#define DEBUG_FLUSH_MAP_DEPTH 16
+
+struct debug_map_item {
+   struct debug_stack_frame *frame;
+   boolean persistent;
+};
+
 struct debug_flush_buf {
/* Atomic */
struct pipe_reference reference; /* Must be the first member. */
mtx_t mutex;
/* Immutable */
-   boolean supports_unsync;
+   boolean supports_persistent;
unsigned bt_depth;
/* Protected by mutex */
-   boolean mapped;
-   boolean mapped_sync;
-   struct debug_stack_frame *map_frame;
+   int map_count;
+   boolean has_sync_map;
+   int last_sync_map;
+   struct debug_map_item maps[DEBUG_FLUSH_MAP_DEPTH];
 };
 
 struct debug_flush_item {
@@ -106,14 +115,14 @@ debug_flush_pointer_hash(void *key)
 }
 
 struct debug_flush_buf *
-debug_flush_buf_create(boolean supports_unsync, unsigned bt_depth)
+debug_flush_buf_create(boolean supports_persistent, unsigned bt_depth)
 {
struct debug_flush_buf *fbuf = CALLOC_STRUCT(debug_flush_buf);
 
if (!fbuf)
   goto out_no_buf;
 
-   fbuf->supports_unsync = supports_unsync;
+   fbuf->supports_persistent = supports_persistent;
fbuf->bt_depth = bt_depth;
pipe_reference_init(>reference, 1);
(void) mtx_init(>mutex, mtx_plain);
@@ -132,8 +141,11 @@ debug_flush_buf_reference(struct debug_flush_buf **dst,
struct debug_flush_buf *fbuf = *dst;
 
if (pipe_reference(&(*dst)->reference, >reference)) {
-  FREE(fbuf->map_frame);
+  int i;
 
+  for (i = 0; i < fbuf->map_count; ++i) {
+ FREE(fbuf->maps[i].frame);
+  }
   FREE(fbuf);
}
 
@@ -211,26 +223,41 @@ debug_flush_alert(const char *s, const char *op,
 void
 debug_flush_map(struct debug_flush_buf *fbuf, unsigned flags)
 {
-   boolean mapped_sync = FALSE;
+   boolean map_sync, persistent;
 
if (!fbuf)
   return;
 
mtx_lock(>mutex);
-   if (fbuf->mapped) {
-  debug_flush_alert("Recursive map detected.", "Map",
+   map_sync = !(flags & PIPE_TRANSFER_UNSYNCHRONIZED);
+   persistent = !map_sync || fbuf->supports_persistent ||
+  !!(flags & PIPE_TRANSFER_PERSISTENT);
+
+   /* Recursive maps are allowed if previous maps are persistent,
+* or if the current map is unsync. In other cases we might flush
+* with unpersistent maps.
+*/
+   if (fbuf->has_sync_map && !map_sync) {
+  debug_flush_alert("Recursive sync map detected.", "Map",
 2, fbuf->bt_depth, TRUE, TRUE, NULL);
   debug_flush_alert(NULL, "Previous map", 0, fbuf->bt_depth, FALSE,
-FALSE, fbuf->map_frame);
-   } else if (!(flags & PIPE_TRANSFER_UNSYNCHRONIZED) ||
-  !fbuf->supports_unsync) {
-  fbuf->mapped_sync = mapped_sync = TRUE;
+FALSE, fbuf->maps[fbuf->last_sync_map].frame);
+   }
+
+   fbuf->maps[fbuf->map_count].frame =
+  debug_flush_capture_frame(1, fbuf->bt_depth);
+   fbuf->maps[fbuf->map_count].persistent = persistent;
+   if (!persistent) {
+  fbuf->has_sync_map = TRUE;
+  fbuf->last_sync_map = fbuf->map_count;
}
-   fbuf->map_frame = debug_flush_capture_frame(1, fbuf->bt_depth);
-   fbuf->mapped = TRUE;
+
+   fbuf->map_count++;
+   assert(fbuf->map_count < DEBUG_FLUSH_MAP_DEPTH);
+
mtx_unlock(>mutex);
 
-   if (mapped_sync) {
+   if (!persistent) {
   struct debug_flush_ctx *fctx;
 
   mtx_lock(_mutex);
@@ -256,14 +283,24 @@ debug_flush_unmap(struct debug_flush_buf *fbuf)
   return;
 
mtx_lock(>mutex);
-   if (!fbuf->mapped)
+   if (--fbuf->map_count < 0) {
   debug_flush_alert("Unmap not previously mapped detected.", "Map",
 2, fbuf->bt_depth, FALSE, TRUE, NULL);
-
-   fbuf->mapped_sync = FALSE;
-   fbuf->mapped = FALSE;
-   FREE(fbuf->map_frame);
-   fbuf->map_frame = NULL;
+   } else {
+  if (fbuf->has_sync_map && fbuf->last_sync_map == fbuf->map_count) {
+ int i = fbuf->map_count;
+
+ fbuf->has_sync_map = FALSE;
+ while (i-- && !fbuf->has_sync_map) {
+if (!fbuf->maps[i].persistent) {
+   fbuf->has_sync_map = TRUE;
+   fbuf->last_sync_map = i;
+}
+ }
+ FREE(fbuf->maps[fbuf->map_count].frame);
+ fbuf->maps[fbuf->map_count].frame = NULL;
+  

[Mesa-dev] [PATCH 4/6] svga: Map vertex- index- and constant buffers ansynchronously when reading

2019-06-19 Thread VMware
From: Thomas Hellstrom 

With SWTNL and index translation we're mapping buffers for reading. These
buffers are commonly upload_mgr buffers that might already be referenced
by another submitted or unsubmitted GPU command. A synchronous map will
then trigger a flush and sync, at least on Linux that doesn't distinguish
between read- and write referencing. So map these buffers async. If they
for some obscure reason happen to be dirty (stream-output, buffer-copy),
the resource_buffer code will read-back and sync anyway. For persistent /
coherent buffers a corresponding read-back and sync will happen in the
kernel fault handler.

Testing: Piglit quick. No regressions.

Signed-off-by: Thomas Hellstrom 
Reviewed-by: Brian Paul 
---
 src/gallium/drivers/svga/svga_draw_elements.c | 4 +++-
 src/gallium/drivers/svga/svga_swtnl_draw.c| 9 ++---
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/src/gallium/drivers/svga/svga_draw_elements.c 
b/src/gallium/drivers/svga/svga_draw_elements.c
index b955b2f77e2..41cd4d18993 100644
--- a/src/gallium/drivers/svga/svga_draw_elements.c
+++ b/src/gallium/drivers/svga/svga_draw_elements.c
@@ -120,7 +120,9 @@ translate_indices(struct svga_hwtnl *hwtnl,
  goto fail;
 
   *out_offset = 0;
-  src_map = pipe_buffer_map(pipe, info->index.resource, PIPE_TRANSFER_READ,
+  src_map = pipe_buffer_map(pipe, info->index.resource,
+PIPE_TRANSFER_READ |
+PIPE_TRANSFER_UNSYNCHRONIZED,
 _transfer);
   if (!src_map)
  goto fail;
diff --git a/src/gallium/drivers/svga/svga_swtnl_draw.c 
b/src/gallium/drivers/svga/svga_swtnl_draw.c
index a7db73e02ee..1aa15d8cd26 100644
--- a/src/gallium/drivers/svga/svga_swtnl_draw.c
+++ b/src/gallium/drivers/svga/svga_swtnl_draw.c
@@ -73,7 +73,8 @@ svga_swtnl_draw_vbo(struct svga_context *svga,
   if (svga->curr.vb[i].buffer.resource) {
  map = pipe_buffer_map(>pipe,
svga->curr.vb[i].buffer.resource,
-   PIPE_TRANSFER_READ,
+   PIPE_TRANSFER_READ |
+   PIPE_TRANSFER_UNSYNCHRONIZED,
_transfer[i]);
 
  draw_set_mapped_vertex_buffer(draw, i, map, ~0);
@@ -88,7 +89,8 @@ svga_swtnl_draw_vbo(struct svga_context *svga,
  map = (ubyte *) info->index.user;
   } else {
  map = pipe_buffer_map(>pipe, info->index.resource,
-   PIPE_TRANSFER_READ, _transfer);
+   PIPE_TRANSFER_READ |
+   PIPE_TRANSFER_UNSYNCHRONIZED, _transfer);
   }
   draw_set_indexes(draw,
(const ubyte *) map,
@@ -103,7 +105,8 @@ svga_swtnl_draw_vbo(struct svga_context *svga,
 
   map = pipe_buffer_map(>pipe,
 svga->curr.constbufs[PIPE_SHADER_VERTEX][i].buffer,
-PIPE_TRANSFER_READ,
+PIPE_TRANSFER_READ |
+PIPE_TRANSFER_UNSYNCHRONIZED,
 _transfer[i]);
   assert(map);
   draw_set_mapped_constant_buffer(
-- 
2.20.1

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

[Mesa-dev] [PATCH 3/6] svga: Fix index buffer uploads

2019-06-19 Thread VMware
From: Thomas Hellstrom 

In the case of SWTNL and index translation we were uploading index buffers
and then reading out from them using the CPU. Furthermore, when translating
indices we often cached the results with an upload_mgr buffer, causing the
cached indexes to be immediately discarded on the next write to that
upload_mgr buffer.

Fix this by only uploading when we know the index buffer is going to be
used by hardware. If translating, only cache translated indices if the
original buffer was not a user buffer. In the latter case when we're not
caching, use an upload_mgr buffer for the hardware indices.

This means we can also remove the SWTNL hand-crafted index buffer upload
mechanism in favour of the upload_mgr.

Finally avoid using util_upload_index_buffer(). It wastes index buffer
space by trying to make sure that the offset of the indices in the
upload_mgr buffer is larger or equal to the position of the indices in
the source buffer. From what I can tell, the SVGA device does not
require that.

Testing done: Piglit quick. No regressions.

Signed-off-by: Thomas Hellstrom 
Reviewed-by: Brian Paul 
---
 src/gallium/drivers/svga/svga_draw.h  |  10 +-
 src/gallium/drivers/svga/svga_draw_elements.c | 168 +++---
 src/gallium/drivers/svga/svga_pipe_draw.c |  58 +-
 src/gallium/drivers/svga/svga_swtnl.h |   4 +-
 src/gallium/drivers/svga/svga_swtnl_backend.c |  58 ++
 src/gallium/drivers/svga/svga_swtnl_draw.c|  16 +-
 6 files changed, 142 insertions(+), 172 deletions(-)

diff --git a/src/gallium/drivers/svga/svga_draw.h 
b/src/gallium/drivers/svga/svga_draw.h
index baefcd94ec8..9d79676d3f9 100644
--- a/src/gallium/drivers/svga/svga_draw.h
+++ b/src/gallium/drivers/svga/svga_draw.h
@@ -64,13 +64,8 @@ svga_hwtnl_draw_arrays(struct svga_hwtnl *hwtnl,
 
 enum pipe_error
 svga_hwtnl_draw_range_elements(struct svga_hwtnl *hwtnl,
-   struct pipe_resource *indexBuffer,
-   unsigned index_size,
-   int index_bias,
-   unsigned min_index,
-   unsigned max_index,
-   enum pipe_prim_type prim, unsigned start, 
unsigned count,
-   unsigned start_instance, unsigned 
instance_count);
+   const struct pipe_draw_info *info,
+   unsigned count);
 
 boolean
 svga_hwtnl_is_buffer_referred(struct svga_hwtnl *hwtnl,
@@ -80,5 +75,4 @@ enum pipe_error svga_hwtnl_flush(struct svga_hwtnl *hwtnl);
 
 void svga_hwtnl_set_index_bias(struct svga_hwtnl *hwtnl, int index_bias);
 
-
 #endif /* SVGA_DRAW_H_ */
diff --git a/src/gallium/drivers/svga/svga_draw_elements.c 
b/src/gallium/drivers/svga/svga_draw_elements.c
index b1db8710740..b955b2f77e2 100644
--- a/src/gallium/drivers/svga/svga_draw_elements.c
+++ b/src/gallium/drivers/svga/svga_draw_elements.c
@@ -59,33 +59,41 @@
  * \return error code to indicate success failure
  */
 static enum pipe_error
-translate_indices(struct svga_hwtnl *hwtnl, struct pipe_resource *src,
-  unsigned offset,
-  enum pipe_prim_type orig_prim, enum pipe_prim_type gen_prim,
+translate_indices(struct svga_hwtnl *hwtnl,
+  const struct pipe_draw_info *info,
+  enum pipe_prim_type gen_prim,
   unsigned orig_nr, unsigned gen_nr,
-  unsigned index_size,
-  u_translate_func translate, struct pipe_resource **out_buf)
+  unsigned gen_size,
+  u_translate_func translate,
+  struct pipe_resource **out_buf,
+  unsigned *out_offset)
 {
struct pipe_context *pipe = >svga->pipe;
struct svga_screen *screen = svga_screen(pipe->screen);
-   struct svga_buffer *src_sbuf = svga_buffer(src);
+   struct svga_buffer *src_sbuf = NULL;
struct pipe_transfer *src_transfer = NULL;
struct pipe_transfer *dst_transfer = NULL;
-   unsigned size = index_size * gen_nr;
+   const unsigned size = gen_size * gen_nr;
+   const unsigned offset = info->start * info->index_size;
const void *src_map = NULL;
struct pipe_resource *dst = NULL;
void *dst_map = NULL;
 
-   assert(index_size == 2 || index_size == 4);
+   assert(gen_size == 2 || gen_size == 4);
+   if (!info->has_user_indices)
+  src_sbuf = svga_buffer(info->index.resource);
 
-   if (!screen->debug.no_cache_index_buffers) {
+   /* If the draw_info provides us with a buffer rather than a
+* user pointer, Check to see if we've already translated that buffer
+*/
+   if (src_sbuf && !screen->debug.no_cache_index_buffers) {
   /* Check if we already have a translated index buffer */
   if (src_sbuf->translated_indices.buffer &&
-  src_sbuf->translated_indices.orig_prim == orig_prim &&
+  src_sbuf->translated_indices.orig_prim == info->mode &&
   

[Mesa-dev] [PATCH 2/6] winsys/svga: Make it possible to specify coherent resources

2019-06-19 Thread VMware
From: Thomas Hellstrom 

Add a flag in the surface cache key and a winsys usage flag to
specify coherent memory.

Signed-off-by: Thomas Hellstrom 
Reviewed-by: Brian Paul 
---
 src/gallium/drivers/svga/svga_screen_cache.c   |  2 ++
 src/gallium/drivers/svga/svga_screen_cache.h   |  1 +
 src/gallium/drivers/svga/svga_winsys.h |  7 +--
 src/gallium/winsys/svga/drm/vmw_buffer.c   |  4 ++--
 src/gallium/winsys/svga/drm/vmw_screen_ioctl.c |  3 ++-
 src/gallium/winsys/svga/drm/vmw_surface.c  | 18 ++
 6 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/src/gallium/drivers/svga/svga_screen_cache.c 
b/src/gallium/drivers/svga/svga_screen_cache.c
index e2282d6a15c..1916a64245c 100644
--- a/src/gallium/drivers/svga/svga_screen_cache.c
+++ b/src/gallium/drivers/svga/svga_screen_cache.c
@@ -550,6 +550,8 @@ svga_screen_surface_create(struct svga_screen *svgascreen,
  usage |= SVGA_SURFACE_USAGE_SHARED;
   if (key->scanout)
  usage |= SVGA_SURFACE_USAGE_SCANOUT;
+  if (key->coherent)
+ usage |= SVGA_SURFACE_USAGE_COHERENT;
 
   handle = sws->surface_create(sws,
key->flags,
diff --git a/src/gallium/drivers/svga/svga_screen_cache.h 
b/src/gallium/drivers/svga/svga_screen_cache.h
index a239b761fc2..055a267c189 100644
--- a/src/gallium/drivers/svga/svga_screen_cache.h
+++ b/src/gallium/drivers/svga/svga_screen_cache.h
@@ -69,6 +69,7 @@ struct svga_host_surface_cache_key
uint32_t cachable:1; /* False if this is a shared surface */
uint32_t sampleCount:5;
uint32_t scanout:1;
+   uint32_t coherent:1;
 };
 
 
diff --git a/src/gallium/drivers/svga/svga_winsys.h 
b/src/gallium/drivers/svga/svga_winsys.h
index ee39db3bbbc..30d3f8776d9 100644
--- a/src/gallium/drivers/svga/svga_winsys.h
+++ b/src/gallium/drivers/svga/svga_winsys.h
@@ -81,8 +81,9 @@ struct winsys_handle;
 #define SVGA_FENCE_FLAG_EXEC  (1 << 0)
 #define SVGA_FENCE_FLAG_QUERY (1 << 1)
 
-#define SVGA_SURFACE_USAGE_SHARED  (1 << 0)
-#define SVGA_SURFACE_USAGE_SCANOUT (1 << 1)
+#define SVGA_SURFACE_USAGE_SHARED   (1 << 0)
+#define SVGA_SURFACE_USAGE_SCANOUT  (1 << 1)
+#define SVGA_SURFACE_USAGE_COHERENT (1 << 2)
 
 #define SVGA_QUERY_FLAG_SET(1 << 0)
 #define SVGA_QUERY_FLAG_REF(1 << 1)
@@ -677,6 +678,8 @@ struct svga_winsys_screen
/** Can we do DMA with guest-backed objects enabled? */
bool have_gb_dma;
 
+   /** Do we support coherent surface memory? */
+   bool have_coherent;
/**
 * Create and define a GB shader.
 */
diff --git a/src/gallium/winsys/svga/drm/vmw_buffer.c 
b/src/gallium/winsys/svga/drm/vmw_buffer.c
index 91b5b259435..34c5e341782 100644
--- a/src/gallium/winsys/svga/drm/vmw_buffer.c
+++ b/src/gallium/winsys/svga/drm/vmw_buffer.c
@@ -315,7 +315,7 @@ vmw_svga_winsys_buffer_wrap(struct pb_buffer *buffer)
}
 
buf->pb_buf = buffer;
-   buf->fbuf = debug_flush_buf_create(TRUE, VMW_DEBUG_FLUSH_STACK);
+   buf->fbuf = debug_flush_buf_create(FALSE, VMW_DEBUG_FLUSH_STACK);
return buf;
 }
 
@@ -365,7 +365,7 @@ vmw_svga_winsys_buffer_map(struct svga_winsys_screen *sws,
STATIC_ASSERT((unsigned) PB_USAGE_UNSYNCHRONIZED ==
  (unsigned) PIPE_TRANSFER_UNSYNCHRONIZED);
 
-   map = pb_map(vmw_pb_buffer(buf), flags, NULL);
+   map = pb_map(vmw_pb_buffer(buf), flags & PB_USAGE_ALL, NULL);
 
 #ifdef DEBUG
if (map != NULL)
diff --git a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c 
b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
index a02d31c2bcb..2e84c811e82 100644
--- a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
@@ -246,7 +246,7 @@ 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)
+  if ((usage & SVGA_SURFACE_USAGE_COHERENT) || vws->force_coherent)
  req->base.drm_surface_flags |= drm_vmw_surface_flag_coherent;
 
   req->base.drm_surface_flags |= drm_vmw_surface_flag_create_buffer;
@@ -1117,6 +1117,7 @@ vmw_ioctl_init(struct vmw_winsys_screen *vws)
  vws->ioctl.num_cap_3d = SVGA3D_DEVCAP_MAX;
 
   if (have_drm_2_16) {
+ vws->base.have_coherent = TRUE;
  getenv_val = getenv("SVGA_FORCE_COHERENT");
  if (getenv_val && strcmp(getenv_val, "0") != 0)
 vws->force_coherent = TRUE;
diff --git a/src/gallium/winsys/svga/drm/vmw_surface.c 
b/src/gallium/winsys/svga/drm/vmw_surface.c
index 69408ffe9d9..6aa09e11b76 100644
--- a/src/gallium/winsys/svga/drm/vmw_surface.c
+++ b/src/gallium/winsys/svga/drm/vmw_surface.c
@@ -45,21 +45,14 @@ vmw_svga_winsys_surface_map(struct svga_winsys_context *swc,
struct pb_buffer *pb_buf;
uint32_t pb_flags;
struct vmw_winsys_screen *vws = vsrf->screen;
-   
+
*retry = FALSE;
assert((flags & (PIPE_TRANSFER_READ | PIPE_TRANSFER_WRITE)) != 

[Mesa-dev] [PATCH 5/6] gallium/util: Make it possible to disable persistent maps in the upload manager

2019-06-19 Thread VMware
From: Thomas Hellstrom 

For svga, the use of persistent / coherent maps is typically slightly
slower than without them. It's probably a bit case-dependent and
possible to tune, but for now, make sure we can disable those.

Signed-off-by: Thomas Hellstrom 
Reviewed-by: Brian Paul 
---
 src/gallium/auxiliary/util/u_upload_mgr.c | 14 --
 src/gallium/auxiliary/util/u_upload_mgr.h |  4 
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/src/gallium/auxiliary/util/u_upload_mgr.c 
b/src/gallium/auxiliary/util/u_upload_mgr.c
index c2c0ba957e3..73f6cae0b6d 100644
--- a/src/gallium/auxiliary/util/u_upload_mgr.c
+++ b/src/gallium/auxiliary/util/u_upload_mgr.c
@@ -106,8 +106,10 @@ u_upload_clone(struct pipe_context *pipe, struct 
u_upload_mgr *upload)
struct u_upload_mgr *result = u_upload_create(pipe, upload->default_size,
  upload->bind, upload->usage,
  upload->flags);
-   if (upload->map_persistent &&
-   upload->map_flags & PIPE_TRANSFER_FLUSH_EXPLICIT)
+   if (!upload->map_persistent && result->map_persistent)
+  u_upload_disable_persistent(result);
+   else if (upload->map_persistent &&
+upload->map_flags & PIPE_TRANSFER_FLUSH_EXPLICIT)
   u_upload_enable_flush_explicit(result);
 
return result;
@@ -121,6 +123,14 @@ u_upload_enable_flush_explicit(struct u_upload_mgr *upload)
upload->map_flags |= PIPE_TRANSFER_FLUSH_EXPLICIT;
 }
 
+void
+u_upload_disable_persistent(struct u_upload_mgr *upload)
+{
+   upload->map_persistent = FALSE;
+   upload->map_flags &= ~(PIPE_TRANSFER_COHERENT | PIPE_TRANSFER_PERSISTENT);
+   upload->map_flags |= PIPE_TRANSFER_FLUSH_EXPLICIT;
+}
+
 static void
 upload_unmap_internal(struct u_upload_mgr *upload, boolean destroying)
 {
diff --git a/src/gallium/auxiliary/util/u_upload_mgr.h 
b/src/gallium/auxiliary/util/u_upload_mgr.h
index 80832016272..6a4a60963fe 100644
--- a/src/gallium/auxiliary/util/u_upload_mgr.h
+++ b/src/gallium/auxiliary/util/u_upload_mgr.h
@@ -73,6 +73,10 @@ u_upload_clone(struct pipe_context *pipe, struct 
u_upload_mgr *upload);
 void
 u_upload_enable_flush_explicit(struct u_upload_mgr *upload);
 
+/** Whether to avoid persistent mappings where available */
+void
+u_upload_disable_persistent(struct u_upload_mgr *upload);
+
 /**
  * Destroy the upload manager.
  */
-- 
2.20.1

___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

[Mesa-dev] [PATCH 6/6] svga: Support ARB_buffer_storage

2019-06-19 Thread VMware
From: Thomas Hellstrom 

This basically boils down to supporting persistent and coherent buffer
storage.
We chose to use coherent buffer storage for all persistent buffers
even if it's not explicitly specified, since using glMemoryBarrier to
obtain coherency would be particularly expensive in our driver stack,
and require a lot of additional bookkeeping.

Signed-off-by: Thomas Hellstrom 
Reviewed-by: Brian Paul 
---
 src/gallium/drivers/svga/svga_context.c |  6 ++
 src/gallium/drivers/svga/svga_resource_buffer.c | 13 +
 .../drivers/svga/svga_resource_buffer_upload.c  | 17 +
 .../drivers/svga/svga_resource_texture.c|  3 +++
 src/gallium/drivers/svga/svga_screen.c  |  3 ++-
 5 files changed, 33 insertions(+), 9 deletions(-)

diff --git a/src/gallium/drivers/svga/svga_context.c 
b/src/gallium/drivers/svga/svga_context.c
index 57c0dc49957..104a551356d 100644
--- a/src/gallium/drivers/svga/svga_context.c
+++ b/src/gallium/drivers/svga/svga_context.c
@@ -148,12 +148,16 @@ svga_context_create(struct pipe_screen *screen, void 
*priv, unsigned flags)
if (!svga->pipe.stream_uploader)
   goto cleanup;
 
+   u_upload_disable_persistent(svga->pipe.stream_uploader);
+
svga->pipe.const_uploader = u_upload_create(>pipe, 128 * 1024,
PIPE_BIND_CONSTANT_BUFFER,
PIPE_USAGE_STREAM, 0);
if (!svga->pipe.const_uploader)
   goto cleanup;
 
+   u_upload_disable_persistent(svga->pipe.const_uploader);
+
svga->swc = svgascreen->sws->context_create(svgascreen->sws);
if (!svga->swc)
   goto cleanup;
@@ -236,6 +240,8 @@ svga_context_create(struct pipe_screen *screen, void *priv, 
unsigned flags)
if (!svga->const0_upload)
   goto cleanup;
 
+   u_upload_disable_persistent(svga->const0_upload);
+
if (!svga_texture_transfer_map_upload_create(svga))
   goto cleanup;
 
diff --git a/src/gallium/drivers/svga/svga_resource_buffer.c 
b/src/gallium/drivers/svga/svga_resource_buffer.c
index 234d825d5a2..712fffc83d3 100644
--- a/src/gallium/drivers/svga/svga_resource_buffer.c
+++ b/src/gallium/drivers/svga/svga_resource_buffer.c
@@ -71,6 +71,9 @@ svga_buffer_needs_hw_storage(const struct svga_screen *ss,
  bind_mask |= PIPE_BIND_CONSTANT_BUFFER;
}
 
+   if (template->flags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT)
+  return TRUE;
+
return !!(template->bind & bind_mask);
 }
 
@@ -126,7 +129,8 @@ svga_buffer_transfer_map(struct pipe_context *pipe,
   pipe_resource_reference(>translated_indices.buffer, NULL);
}
 
-   if ((usage & PIPE_TRANSFER_READ) && sbuf->dirty) {
+   if ((usage & PIPE_TRANSFER_READ) && sbuf->dirty &&
+   !sbuf->key.coherent && !svga->swc->force_coherent) {
   enum pipe_error ret;
 
   /* Host-side buffers can only be dirtied with vgpu10 features
@@ -160,7 +164,8 @@ svga_buffer_transfer_map(struct pipe_context *pipe,
}
 
if (usage & PIPE_TRANSFER_WRITE) {
-  if (usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) {
+  if ((usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) &&
+  !(resource->flags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT)) {
  /*
   * Flush any pending primitives, finish writing any pending DMA
   * commands, and tell the host to discard the buffer contents on
@@ -317,7 +322,7 @@ svga_buffer_transfer_flush_region(struct pipe_context *pipe,
assert(transfer->usage & PIPE_TRANSFER_WRITE);
assert(transfer->usage & PIPE_TRANSFER_FLUSH_EXPLICIT);
 
-   if (!svga->swc->force_coherent || sbuf->swbuf) {
+   if (!(svga->swc->force_coherent || sbuf->key.coherent) || sbuf->swbuf) {
   mtx_lock(>swc_mutex);
   svga_buffer_add_range(sbuf, offset, offset + length);
   mtx_unlock(>swc_mutex);
@@ -361,7 +366,7 @@ svga_buffer_transfer_unmap(struct pipe_context *pipe,
 
  sbuf->dma.flags.discard = TRUE;
 
- if (!svga->swc->force_coherent || sbuf->swbuf)
+ if (!(svga->swc->force_coherent || sbuf->key.coherent) || sbuf->swbuf)
 svga_buffer_add_range(sbuf, 0, sbuf->b.b.width0);
   }
}
diff --git a/src/gallium/drivers/svga/svga_resource_buffer_upload.c 
b/src/gallium/drivers/svga/svga_resource_buffer_upload.c
index 64f75231a65..1bb7431abf4 100644
--- a/src/gallium/drivers/svga/svga_resource_buffer_upload.c
+++ b/src/gallium/drivers/svga/svga_resource_buffer_upload.c
@@ -183,6 +183,14 @@ svga_buffer_create_host_surface(struct svga_screen *ss,
  sbuf->key.flags = SVGA3D_SURFACE_TRANSFER_FROM_BUFFER;
   }
 
+  if (sbuf->b.b.flags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT) {
+ /* This surface can be mapped persistently. We use
+  * coherent memory to avoid implementing memory barriers for
+  * persistent non-coherent memory for now.
+  */
+ sbuf->key.coherent = 1;
+  }
+
   sbuf->key.size.width = sbuf->b.b.width0;
   sbuf->key.size.height = 1;