drm/vmwgfx: Command parser fixes for DX
authorCharmaine Lee <charmainel@vmware.com>
Mon, 10 Aug 2015 17:45:11 +0000 (10:45 -0700)
committerThomas Hellstrom <thellstrom@vmware.com>
Wed, 12 Aug 2015 17:06:37 +0000 (10:06 -0700)
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>
drivers/gpu/drm/vmwgfx/vmwgfx_context.c
drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c
drivers/gpu/drm/vmwgfx/vmwgfx_surface.c

index abfe67c893c77d7b884ef98f927cbfb35a9f122e..b14583d6f3877c26f1663ab5d242b9aabcea6f03 100644 (file)
@@ -37,6 +37,7 @@ struct vmw_user_context {
        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);
index 401305bbb8103208ba08554b45b934b735fc0295..2553baa7b4d81ffcefe244c48af0aa40b273d583 100644 (file)
@@ -553,6 +553,7 @@ static int vmw_resources_reserve(struct vmw_sw_context *sw_context)
                                return ret;
                }
        }
+
        return 0;
 }
 
@@ -2484,6 +2485,63 @@ static int vmw_cmd_dx_view_define(struct vmw_private *dev_priv,
                            &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 @@ static const struct vmw_cmd_entry vmw_cmd_entries[SVGA_3D_CMD_MAX] = {
                    &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, &vmw_cmd_dx_cid_check,
+                   true, false, true),
+       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_INDEXED_INSTANCED, &vmw_cmd_invalid,
+       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_AUTO, &vmw_cmd_invalid,
+       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 @@ static const struct vmw_cmd_entry vmw_cmd_entries[SVGA_3D_CMD_MAX] = {
                    &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 @@ static const struct vmw_cmd_entry vmw_cmd_entries[SVGA_3D_CMD_MAX] = {
                    &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 @@ int vmw_execbuf_process(struct drm_file *file_priv,
        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 @@ int vmw_execbuf_process(struct drm_file *file_priv,
 
        ret = vmw_cmd_check_all(dev_priv, sw_context, kernel_commands,
                                command_size);
-       if (unlikely(ret != 0))
-               goto out_err_nores;
 
+       /*
+        * 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;
+
        ret = vmw_resources_reserve(sw_context);
        if (unlikely(ret != 0))
                goto out_err_nores;
index dca7f7f41aab2b34779eb7d8de4023dec1acfdd8..893359c8d52266acb6c7d09256786a290a9a8147 100644 (file)
@@ -196,8 +196,8 @@ int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data,
                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) {
index 12ade0cf98d0d5ed55d1f972c59fa7ed59aa4d80..ca496a6eb59f380d95f6e88e2f3708645b6b6b25 100644 (file)
@@ -1533,6 +1533,7 @@ int vmw_surface_gb_priv_define(struct drm_device *dev,
        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)