Commit 2f633e5e authored by Charmaine Lee's avatar Charmaine Lee Committed by Thomas Hellstrom
Browse files

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: default avatarCharmaine Lee <charmainel@vmware.com>
Signed-off-by: default avatarSinclair Yeh <syeh@vmware.com>
Signed-off-by: default avatarThomas Hellstrom <thellstrom@vmware.com>
parent d80efd5c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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);
+85 −13
Original line number Diff line number Diff line
@@ -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_INSTANCED, &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_AUTO, &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_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,
@@ -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;
+2 −2
Original line number Diff line number Diff line
@@ -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) {
+1 −0
Original line number Diff line number Diff line
@@ -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)