[PATCH v2 12/17] drm/vmwgfx: Add support for streamoutput with mob commands

2020-03-23 Thread Roland Scheidegger (VMware)
From: Deepak Rawat 

With SM5 capability a new version of streamoutput is supported by device
which need backing mob and a new field. With this change the new command
is supported in command buffer.

v2: Also track streamoutput context binding in binding manager.

v3: Track only one streamoutput as only one can be set to context.
v4: Fix comment typos

Signed-off-by: Deepak Rawat 
Signed-off-by: Neha Bhende 
Reviewed-by: Thomas Hellström (VMware) 
Reviewed-by: Roland Scheidegger 
Signed-off-by: Roland Scheidegger 
---
 drivers/gpu/drm/vmwgfx/Makefile  |   2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_binding.c  |  39 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_binding.h  |  11 +
 drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c  |   2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.h  |  22 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c  | 173 -
 drivers/gpu/drm/vmwgfx/vmwgfx_so.h   |   1 +
 drivers/gpu/drm/vmwgfx/vmwgfx_streamoutput.c | 387 +++
 8 files changed, 630 insertions(+), 7 deletions(-)
 create mode 100644 drivers/gpu/drm/vmwgfx/vmwgfx_streamoutput.c

diff --git a/drivers/gpu/drm/vmwgfx/Makefile b/drivers/gpu/drm/vmwgfx/Makefile
index c877a21a0739..5c3515e8cce1 100644
--- a/drivers/gpu/drm/vmwgfx/Makefile
+++ b/drivers/gpu/drm/vmwgfx/Makefile
@@ -8,7 +8,7 @@ vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_kms.o 
vmwgfx_drv.o \
vmwgfx_cmdbuf_res.o vmwgfx_cmdbuf.o vmwgfx_stdu.o \
vmwgfx_cotable.o vmwgfx_so.o vmwgfx_binding.o vmwgfx_msg.o \
vmwgfx_simple_resource.o vmwgfx_va.o vmwgfx_blit.o \
-   vmwgfx_validation.o vmwgfx_page_dirty.o \
+   vmwgfx_validation.o vmwgfx_page_dirty.o vmwgfx_streamoutput.o \
ttm_object.o ttm_lock.o
 
 obj-$(CONFIG_DRM_VMWGFX) := vmwgfx.o
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c
index f923b3c7c152..f41550797970 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c
@@ -78,6 +78,7 @@
  * @index_buffer: Index buffer binding.
  * @per_shader: Per shader-type bindings.
  * @ua_views: UAV bindings.
+ * @so_state: StreamOutput bindings.
  * @dirty: Bitmap tracking per binding-type changes that have not yet
  * been emitted to the device.
  * @dirty_vb: Bitmap tracking individual vertex buffer binding changes that
@@ -103,6 +104,7 @@ struct vmw_ctx_binding_state {
struct vmw_ctx_bindinfo_ib index_buffer;
struct vmw_dx_shader_bindings per_shader[SVGA3D_NUM_SHADERTYPE];
struct vmw_ctx_bindinfo_uav ua_views[VMW_MAX_UAV_BIND_TYPE];
+   struct vmw_ctx_bindinfo_so so_state;
 
unsigned long dirty;
DECLARE_BITMAP(dirty_vb, SVGA3D_DX_MAX_VERTEXBUFFERS);
@@ -127,6 +129,7 @@ static int vmw_binding_scrub_ib(struct vmw_ctx_bindinfo 
*bi, bool rebind);
 static int vmw_binding_scrub_vb(struct vmw_ctx_bindinfo *bi, bool rebind);
 static int vmw_binding_scrub_uav(struct vmw_ctx_bindinfo *bi, bool rebind);
 static int vmw_binding_scrub_cs_uav(struct vmw_ctx_bindinfo *bi, bool rebind);
+static int vmw_binding_scrub_so(struct vmw_ctx_bindinfo *bi, bool rebind);
 
 static void vmw_binding_build_asserts(void) __attribute__ ((unused));
 
@@ -202,6 +205,9 @@ static const size_t vmw_binding_uav_offsets[] = {
 static const size_t vmw_binding_cs_uav_offsets[] = {
offsetof(struct vmw_ctx_binding_state, ua_views[1].views),
 };
+static const size_t vmw_binding_so_offsets[] = {
+   offsetof(struct vmw_ctx_binding_state, so_state),
+};
 
 static const struct vmw_binding_info vmw_binding_infos[] = {
[vmw_ctx_binding_shader] = {
@@ -256,6 +262,10 @@ static const struct vmw_binding_info vmw_binding_infos[] = 
{
.size = sizeof(struct vmw_ctx_bindinfo_view),
.offsets = vmw_binding_cs_uav_offsets,
.scrub_func = vmw_binding_scrub_cs_uav},
+   [vmw_ctx_binding_so] = {
+   .size = sizeof(struct vmw_ctx_bindinfo_so),
+   .offsets = vmw_binding_so_offsets,
+   .scrub_func = vmw_binding_scrub_so},
 };
 
 /**
@@ -1290,6 +1300,33 @@ static int vmw_binding_scrub_cs_uav(struct 
vmw_ctx_bindinfo *bi, bool rebind)
return 0;
 }
 
+/**
+ * vmw_binding_scrub_so - Scrub a streamoutput binding from context.
+ * @bi: Single binding information.
+ * @rebind: Whether to issue a bind instead of scrub command.
+ */
+static int vmw_binding_scrub_so(struct vmw_ctx_bindinfo *bi, bool rebind)
+{
+   struct vmw_ctx_bindinfo_so *binding =
+   container_of(bi, typeof(*binding), bi);
+   struct vmw_private *dev_priv = bi->ctx->dev_priv;
+   struct {
+   SVGA3dCmdHeader header;
+   SVGA3dCmdDXSetStreamOutput body;
+   } *cmd;
+
+   cmd = VMW_FIFO_RESERVE_DX(dev_priv, sizeof(*cmd), bi->ctx->id);
+   if (!cmd)
+   return -ENOMEM;
+
+   cmd->header.id = SVGA_3D_CMD_DX_SET_STREAMOUTPUT;
+   cmd->header.size = sizeof(cmd->body);

[PATCH v2 12/17] drm/vmwgfx: Add support for streamoutput with mob commands

2020-03-23 Thread Roland Scheidegger
From: Deepak Rawat 

With SM5 capability a new version of streamoutput is supported by device
which need backing mob and a new field. With this change the new command
is supported in command buffer.

v2: Also track streamoutput context binding in binding manager.

v3: Track only one streamoutput as only one can be set to context.
v4: Fix comment typos

Signed-off-by: Deepak Rawat 
Signed-off-by: Neha Bhende 
Reviewed-by: Thomas Hellström (VMware) 
Reviewed-by: Roland Scheidegger 
Signed-off-by: Roland Scheidegger 
---
 drivers/gpu/drm/vmwgfx/Makefile  |   2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_binding.c  |  39 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_binding.h  |  11 +
 drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c  |   2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.h  |  22 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c  | 173 -
 drivers/gpu/drm/vmwgfx/vmwgfx_so.h   |   1 +
 drivers/gpu/drm/vmwgfx/vmwgfx_streamoutput.c | 387 +++
 8 files changed, 630 insertions(+), 7 deletions(-)
 create mode 100644 drivers/gpu/drm/vmwgfx/vmwgfx_streamoutput.c

diff --git a/drivers/gpu/drm/vmwgfx/Makefile b/drivers/gpu/drm/vmwgfx/Makefile
index c877a21a0739..5c3515e8cce1 100644
--- a/drivers/gpu/drm/vmwgfx/Makefile
+++ b/drivers/gpu/drm/vmwgfx/Makefile
@@ -8,7 +8,7 @@ vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_kms.o 
vmwgfx_drv.o \
vmwgfx_cmdbuf_res.o vmwgfx_cmdbuf.o vmwgfx_stdu.o \
vmwgfx_cotable.o vmwgfx_so.o vmwgfx_binding.o vmwgfx_msg.o \
vmwgfx_simple_resource.o vmwgfx_va.o vmwgfx_blit.o \
-   vmwgfx_validation.o vmwgfx_page_dirty.o \
+   vmwgfx_validation.o vmwgfx_page_dirty.o vmwgfx_streamoutput.o \
ttm_object.o ttm_lock.o
 
 obj-$(CONFIG_DRM_VMWGFX) := vmwgfx.o
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c 
b/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c
index f923b3c7c152..f41550797970 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_binding.c
@@ -78,6 +78,7 @@
  * @index_buffer: Index buffer binding.
  * @per_shader: Per shader-type bindings.
  * @ua_views: UAV bindings.
+ * @so_state: StreamOutput bindings.
  * @dirty: Bitmap tracking per binding-type changes that have not yet
  * been emitted to the device.
  * @dirty_vb: Bitmap tracking individual vertex buffer binding changes that
@@ -103,6 +104,7 @@ struct vmw_ctx_binding_state {
struct vmw_ctx_bindinfo_ib index_buffer;
struct vmw_dx_shader_bindings per_shader[SVGA3D_NUM_SHADERTYPE];
struct vmw_ctx_bindinfo_uav ua_views[VMW_MAX_UAV_BIND_TYPE];
+   struct vmw_ctx_bindinfo_so so_state;
 
unsigned long dirty;
DECLARE_BITMAP(dirty_vb, SVGA3D_DX_MAX_VERTEXBUFFERS);
@@ -127,6 +129,7 @@ static int vmw_binding_scrub_ib(struct vmw_ctx_bindinfo 
*bi, bool rebind);
 static int vmw_binding_scrub_vb(struct vmw_ctx_bindinfo *bi, bool rebind);
 static int vmw_binding_scrub_uav(struct vmw_ctx_bindinfo *bi, bool rebind);
 static int vmw_binding_scrub_cs_uav(struct vmw_ctx_bindinfo *bi, bool rebind);
+static int vmw_binding_scrub_so(struct vmw_ctx_bindinfo *bi, bool rebind);
 
 static void vmw_binding_build_asserts(void) __attribute__ ((unused));
 
@@ -202,6 +205,9 @@ static const size_t vmw_binding_uav_offsets[] = {
 static const size_t vmw_binding_cs_uav_offsets[] = {
offsetof(struct vmw_ctx_binding_state, ua_views[1].views),
 };
+static const size_t vmw_binding_so_offsets[] = {
+   offsetof(struct vmw_ctx_binding_state, so_state),
+};
 
 static const struct vmw_binding_info vmw_binding_infos[] = {
[vmw_ctx_binding_shader] = {
@@ -256,6 +262,10 @@ static const struct vmw_binding_info vmw_binding_infos[] = 
{
.size = sizeof(struct vmw_ctx_bindinfo_view),
.offsets = vmw_binding_cs_uav_offsets,
.scrub_func = vmw_binding_scrub_cs_uav},
+   [vmw_ctx_binding_so] = {
+   .size = sizeof(struct vmw_ctx_bindinfo_so),
+   .offsets = vmw_binding_so_offsets,
+   .scrub_func = vmw_binding_scrub_so},
 };
 
 /**
@@ -1290,6 +1300,33 @@ static int vmw_binding_scrub_cs_uav(struct 
vmw_ctx_bindinfo *bi, bool rebind)
return 0;
 }
 
+/**
+ * vmw_binding_scrub_so - Scrub a streamoutput binding from context.
+ * @bi: Single binding information.
+ * @rebind: Whether to issue a bind instead of scrub command.
+ */
+static int vmw_binding_scrub_so(struct vmw_ctx_bindinfo *bi, bool rebind)
+{
+   struct vmw_ctx_bindinfo_so *binding =
+   container_of(bi, typeof(*binding), bi);
+   struct vmw_private *dev_priv = bi->ctx->dev_priv;
+   struct {
+   SVGA3dCmdHeader header;
+   SVGA3dCmdDXSetStreamOutput body;
+   } *cmd;
+
+   cmd = VMW_FIFO_RESERVE_DX(dev_priv, sizeof(*cmd), bi->ctx->id);
+   if (!cmd)
+   return -ENOMEM;
+
+   cmd->header.id = SVGA_3D_CMD_DX_SET_STREAMOUTPUT;
+   cmd->header.size = sizeof(cmd->body);