drm/vmwgfx: Command parser fixes for DX
Implement support for a couple of missing commands and fix a command parser
error path. Also fix uninitialized devcaps and surface size computation.
Signed-off-by: Charmaine Lee <charmainel@vmware.com>
Signed-off-by: Sinclair Yeh <syeh@vmware.com>
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c
index abfe67c..b14583d 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c
@@ -37,6 +37,7 @@
struct vmw_cmdbuf_res_manager *man;
struct vmw_resource *cotables[SVGA_COTABLE_DX10_MAX];
spinlock_t cotable_lock;
+ struct vmw_dma_buffer *dx_query_mob;
};
static void vmw_user_context_free(struct vmw_resource *res);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
index 401305b..2553baa 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
@@ -553,6 +553,7 @@
return ret;
}
}
+
return 0;
}
@@ -2484,6 +2485,63 @@
&sw_context->staged_cmd_res);
}
+/**
+ * vmw_cmd_dx_set_so_targets - Validate an
+ * SVGA_3D_CMD_DX_SET_SOTARGETS command.
+ *
+ * @dev_priv: Pointer to a device private struct.
+ * @sw_context: The software context being used for this batch.
+ * @header: Pointer to the command header in the command stream.
+ */
+static int vmw_cmd_dx_set_so_targets(struct vmw_private *dev_priv,
+ struct vmw_sw_context *sw_context,
+ SVGA3dCmdHeader *header)
+{
+ struct vmw_resource_val_node *ctx_node = sw_context->dx_ctx_node;
+ struct vmw_ctx_bindinfo_so binding;
+ struct vmw_resource_val_node *res_node;
+ struct {
+ SVGA3dCmdHeader header;
+ SVGA3dCmdDXSetSOTargets body;
+ SVGA3dSoTarget targets[];
+ } *cmd;
+ int i, ret, num;
+
+ if (unlikely(ctx_node == NULL)) {
+ DRM_ERROR("DX Context not set.\n");
+ return -EINVAL;
+ }
+
+ cmd = container_of(header, typeof(*cmd), header);
+ num = (cmd->header.size - sizeof(cmd->body)) /
+ sizeof(SVGA3dSoTarget);
+
+ if (num > SVGA3D_DX_MAX_SOTARGETS) {
+ DRM_ERROR("Invalid DX SO binding.\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < num; i++) {
+ ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
+ user_surface_converter,
+ &cmd->targets[i].sid, &res_node);
+ if (unlikely(ret != 0))
+ return ret;
+
+ binding.bi.ctx = ctx_node->res;
+ binding.bi.res = ((res_node) ? res_node->res : NULL);
+ binding.bi.bt = vmw_ctx_binding_so,
+ binding.offset = cmd->targets[i].offset;
+ binding.size = cmd->targets[i].sizeInBytes;
+ binding.slot = i;
+
+ vmw_binding_add(ctx_node->staged_bindings, &binding.bi,
+ 0, binding.slot);
+ }
+
+ return 0;
+}
+
static int vmw_cmd_dx_so_define(struct vmw_private *dev_priv,
struct vmw_sw_context *sw_context,
SVGA3dCmdHeader *header)
@@ -2971,11 +3029,17 @@
&vmw_cmd_dx_set_shader_res, true, false, true),
VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_SHADER, &vmw_cmd_dx_set_shader,
true, false, true),
- VMW_CMD_DEF(SVGA_3D_CMD_DX_DRAW_INSTANCED, &vmw_cmd_invalid,
+ VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_SAMPLERS, &vmw_cmd_dx_cid_check,
true, false, true),
- VMW_CMD_DEF(SVGA_3D_CMD_DX_DRAW_INDEXED_INSTANCED, &vmw_cmd_invalid,
+ VMW_CMD_DEF(SVGA_3D_CMD_DX_DRAW, &vmw_cmd_dx_cid_check,
true, false, true),
- VMW_CMD_DEF(SVGA_3D_CMD_DX_DRAW_AUTO, &vmw_cmd_invalid,
+ VMW_CMD_DEF(SVGA_3D_CMD_DX_DRAW_INDEXED, &vmw_cmd_dx_cid_check,
+ true, false, true),
+ VMW_CMD_DEF(SVGA_3D_CMD_DX_DRAW_INSTANCED, &vmw_cmd_dx_cid_check,
+ true, false, true),
+ VMW_CMD_DEF(SVGA_3D_CMD_DX_DRAW_INDEXED_INSTANCED,
+ &vmw_cmd_dx_cid_check, true, false, true),
+ VMW_CMD_DEF(SVGA_3D_CMD_DX_DRAW_AUTO, &vmw_cmd_dx_cid_check,
true, false, true),
VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_VERTEX_BUFFERS,
&vmw_cmd_dx_set_vertex_buffers, true, false, true),
@@ -2985,11 +3049,10 @@
&vmw_cmd_dx_set_rendertargets, true, false, true),
VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_BLEND_STATE, &vmw_cmd_dx_cid_check,
true, false, true),
- VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_RASTERIZER_STATE, &vmw_cmd_dx_cid_check,
- true, false, true),
VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_DEPTHSTENCIL_STATE,
- &vmw_cmd_dx_cid_check,
- true, false, true),
+ &vmw_cmd_dx_cid_check, true, false, true),
+ VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_RASTERIZER_STATE,
+ &vmw_cmd_dx_cid_check, true, false, true),
VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_QUERY, &vmw_cmd_invalid,
true, false, true),
VMW_CMD_DEF(SVGA_3D_CMD_DX_DESTROY_QUERY, &vmw_cmd_invalid,
@@ -3066,8 +3129,10 @@
&vmw_cmd_dx_so_define, true, false, true),
VMW_CMD_DEF(SVGA_3D_CMD_DX_DESTROY_STREAMOUTPUT,
&vmw_cmd_dx_cid_check, true, false, true),
- VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_STREAMOUTPUT, &vmw_cmd_invalid,
+ VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_STREAMOUTPUT, &vmw_cmd_dx_cid_check,
true, false, true),
+ VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_SOTARGETS,
+ &vmw_cmd_dx_set_so_targets, true, false, true),
VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_INPUT_LAYOUT,
&vmw_cmd_dx_cid_check, true, false, true),
VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_TOPOLOGY,
@@ -3621,14 +3686,14 @@
uint32_t handle;
int ret;
- if (throttle_us) {
+ if (throttle_us) {
ret = vmw_wait_lag(dev_priv, &dev_priv->fifo.marker_queue,
throttle_us);
-
+
if (ret)
return ret;
}
-
+
kernel_commands = vmw_execbuf_cmdbuf(dev_priv, user_commands,
kernel_commands, command_size,
&header);
@@ -3692,11 +3757,18 @@
ret = vmw_cmd_check_all(dev_priv, sw_context, kernel_commands,
command_size);
+
+ /*
+ * Merge the resource lists before checking the return status
+ * from vmd_cmd_check_all so that all the open hashtabs will
+ * be handled properly even if vmw_cmd_check_all fails.
+ */
+ list_splice_init(&sw_context->ctx_resource_list,
+ &sw_context->resource_list);
+
if (unlikely(ret != 0))
goto out_err_nores;
- list_splice_init(&sw_context->ctx_resource_list,
- &sw_context->resource_list);
ret = vmw_resources_reserve(sw_context);
if (unlikely(ret != 0))
goto out_err_nores;
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
index dca7f7f..893359c 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
@@ -196,8 +196,8 @@
uint32_t *bounce32 = (uint32_t *) bounce;
num = size / sizeof(uint32_t);
- if (num > SVGA3D_DEVCAP_DX)
- num = SVGA3D_DEVCAP_DX;
+ if (num > SVGA3D_DEVCAP_MAX)
+ num = SVGA3D_DEVCAP_MAX;
spin_lock(&dev_priv->cap_lock);
for (i = 0; i < num; ++i) {
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
index 12ade0c..ca496a6 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
@@ -1533,6 +1533,7 @@
srf->offsets = NULL;
srf->base_size = size;
srf->autogen_filter = SVGA3D_TEX_FILTER_NONE;
+ srf->array_size = array_size;
srf->multisample_count = multisample_count;
if (array_size)