mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-29 07:04:10 +08:00
Merge branch 'vmwgfx-next' of https://gitlab.freedesktop.org/drawat/linux into drm-next
Resource dirtying improvement by Thomas, user-space error logging improvement and some other minor fixes. Signed-off-by: Dave Airlie <airlied@redhat.com> From: Deepak Rawat <drawat@vmware.com> Link: https://patchwork.freedesktop.org/patch/msgid/20190423211630.61874-1-drawat@vmware.com
This commit is contained in:
commit
b3edf499dd
@ -499,12 +499,9 @@ static int vmw_binding_scrub_shader(struct vmw_ctx_bindinfo *bi, bool rebind)
|
||||
SVGA3dCmdSetShader body;
|
||||
} *cmd;
|
||||
|
||||
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for shader "
|
||||
"unbinding.\n");
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmd->header.id = SVGA_3D_CMD_SET_SHADER;
|
||||
cmd->header.size = sizeof(cmd->body);
|
||||
@ -534,12 +531,9 @@ static int vmw_binding_scrub_render_target(struct vmw_ctx_bindinfo *bi,
|
||||
SVGA3dCmdSetRenderTarget body;
|
||||
} *cmd;
|
||||
|
||||
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for render target "
|
||||
"unbinding.\n");
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmd->header.id = SVGA_3D_CMD_SETRENDERTARGET;
|
||||
cmd->header.size = sizeof(cmd->body);
|
||||
@ -576,12 +570,9 @@ static int vmw_binding_scrub_texture(struct vmw_ctx_bindinfo *bi,
|
||||
} body;
|
||||
} *cmd;
|
||||
|
||||
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for texture "
|
||||
"unbinding.\n");
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmd->header.id = SVGA_3D_CMD_SETTEXTURESTATE;
|
||||
cmd->header.size = sizeof(cmd->body);
|
||||
@ -610,12 +601,10 @@ static int vmw_binding_scrub_dx_shader(struct vmw_ctx_bindinfo *bi, bool rebind)
|
||||
SVGA3dCmdDXSetShader body;
|
||||
} *cmd;
|
||||
|
||||
cmd = vmw_fifo_reserve_dx(dev_priv, sizeof(*cmd), bi->ctx->id);
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for DX shader "
|
||||
"unbinding.\n");
|
||||
cmd = VMW_FIFO_RESERVE_DX(dev_priv, sizeof(*cmd), bi->ctx->id);
|
||||
if (unlikely(cmd == NULL))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmd->header.id = SVGA_3D_CMD_DX_SET_SHADER;
|
||||
cmd->header.size = sizeof(cmd->body);
|
||||
cmd->body.type = binding->shader_slot + SVGA3D_SHADERTYPE_MIN;
|
||||
@ -641,12 +630,9 @@ static int vmw_binding_scrub_cb(struct vmw_ctx_bindinfo *bi, bool rebind)
|
||||
SVGA3dCmdDXSetSingleConstantBuffer body;
|
||||
} *cmd;
|
||||
|
||||
cmd = vmw_fifo_reserve_dx(dev_priv, sizeof(*cmd), bi->ctx->id);
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for DX shader "
|
||||
"unbinding.\n");
|
||||
cmd = VMW_FIFO_RESERVE_DX(dev_priv, sizeof(*cmd), bi->ctx->id);
|
||||
if (unlikely(cmd == NULL))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmd->header.id = SVGA_3D_CMD_DX_SET_SINGLE_CONSTANT_BUFFER;
|
||||
cmd->header.size = sizeof(cmd->body);
|
||||
@ -768,12 +754,9 @@ static int vmw_emit_set_sr(struct vmw_ctx_binding_state *cbs,
|
||||
|
||||
view_id_size = cbs->bind_cmd_count*sizeof(uint32);
|
||||
cmd_size = sizeof(*cmd) + view_id_size;
|
||||
cmd = vmw_fifo_reserve_dx(ctx->dev_priv, cmd_size, ctx->id);
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for DX shader"
|
||||
" resource binding.\n");
|
||||
cmd = VMW_FIFO_RESERVE_DX(ctx->dev_priv, cmd_size, ctx->id);
|
||||
if (unlikely(cmd == NULL))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmd->header.id = SVGA_3D_CMD_DX_SET_SHADER_RESOURCES;
|
||||
cmd->header.size = sizeof(cmd->body) + view_id_size;
|
||||
@ -807,12 +790,9 @@ static int vmw_emit_set_rt(struct vmw_ctx_binding_state *cbs)
|
||||
vmw_collect_view_ids(cbs, loc, SVGA3D_MAX_SIMULTANEOUS_RENDER_TARGETS);
|
||||
view_id_size = cbs->bind_cmd_count*sizeof(uint32);
|
||||
cmd_size = sizeof(*cmd) + view_id_size;
|
||||
cmd = vmw_fifo_reserve_dx(ctx->dev_priv, cmd_size, ctx->id);
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for DX render-target"
|
||||
" binding.\n");
|
||||
cmd = VMW_FIFO_RESERVE_DX(ctx->dev_priv, cmd_size, ctx->id);
|
||||
if (unlikely(cmd == NULL))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmd->header.id = SVGA_3D_CMD_DX_SET_RENDERTARGETS;
|
||||
cmd->header.size = sizeof(cmd->body) + view_id_size;
|
||||
@ -894,12 +874,9 @@ static int vmw_emit_set_so(struct vmw_ctx_binding_state *cbs)
|
||||
|
||||
so_target_size = cbs->bind_cmd_count*sizeof(SVGA3dSoTarget);
|
||||
cmd_size = sizeof(*cmd) + so_target_size;
|
||||
cmd = vmw_fifo_reserve_dx(ctx->dev_priv, cmd_size, ctx->id);
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for DX SO target"
|
||||
" binding.\n");
|
||||
cmd = VMW_FIFO_RESERVE_DX(ctx->dev_priv, cmd_size, ctx->id);
|
||||
if (unlikely(cmd == NULL))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmd->header.id = SVGA_3D_CMD_DX_SET_SOTARGETS;
|
||||
cmd->header.size = sizeof(cmd->body) + so_target_size;
|
||||
@ -1011,12 +988,9 @@ static int vmw_emit_set_vb(struct vmw_ctx_binding_state *cbs)
|
||||
|
||||
set_vb_size = cbs->bind_cmd_count*sizeof(SVGA3dVertexBuffer);
|
||||
cmd_size = sizeof(*cmd) + set_vb_size;
|
||||
cmd = vmw_fifo_reserve_dx(ctx->dev_priv, cmd_size, ctx->id);
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for DX vertex buffer"
|
||||
" binding.\n");
|
||||
cmd = VMW_FIFO_RESERVE_DX(ctx->dev_priv, cmd_size, ctx->id);
|
||||
if (unlikely(cmd == NULL))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmd->header.id = SVGA_3D_CMD_DX_SET_VERTEX_BUFFERS;
|
||||
cmd->header.size = sizeof(cmd->body) + set_vb_size;
|
||||
@ -1167,12 +1141,10 @@ static int vmw_binding_scrub_ib(struct vmw_ctx_bindinfo *bi, bool rebind)
|
||||
SVGA3dCmdDXSetIndexBuffer body;
|
||||
} *cmd;
|
||||
|
||||
cmd = vmw_fifo_reserve_dx(dev_priv, sizeof(*cmd), bi->ctx->id);
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for DX index buffer "
|
||||
"binding.\n");
|
||||
cmd = VMW_FIFO_RESERVE_DX(dev_priv, sizeof(*cmd), bi->ctx->id);
|
||||
if (unlikely(cmd == NULL))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmd->header.id = SVGA_3D_CMD_DX_SET_INDEX_BUFFER;
|
||||
cmd->header.size = sizeof(cmd->body);
|
||||
if (rebind) {
|
||||
@ -1269,6 +1241,32 @@ void vmw_binding_state_reset(struct vmw_ctx_binding_state *cbs)
|
||||
vmw_binding_drop(entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* vmw_binding_dirtying - Return whether a binding type is dirtying its resource
|
||||
* @binding_type: The binding type
|
||||
*
|
||||
* Each time a resource is put on the validation list as the result of a
|
||||
* context binding referencing it, we need to determine whether that resource
|
||||
* will be dirtied (written to by the GPU) as a result of the corresponding
|
||||
* GPU operation. Currently rendertarget-, depth-stencil-, and
|
||||
* stream-output-target bindings are capable of dirtying its resource.
|
||||
*
|
||||
* Return: Whether the binding type dirties the resource its binding points to.
|
||||
*/
|
||||
u32 vmw_binding_dirtying(enum vmw_ctx_binding_type binding_type)
|
||||
{
|
||||
static u32 is_binding_dirtying[vmw_ctx_binding_max] = {
|
||||
[vmw_ctx_binding_rt] = VMW_RES_DIRTY_SET,
|
||||
[vmw_ctx_binding_dx_rt] = VMW_RES_DIRTY_SET,
|
||||
[vmw_ctx_binding_ds] = VMW_RES_DIRTY_SET,
|
||||
[vmw_ctx_binding_so] = VMW_RES_DIRTY_SET,
|
||||
};
|
||||
|
||||
/* Review this function as new bindings are added. */
|
||||
BUILD_BUG_ON(vmw_ctx_binding_max != 11);
|
||||
return is_binding_dirtying[binding_type];
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is unused at run-time, and only used to hold various build
|
||||
* asserts important for code optimization assumptions.
|
||||
|
@ -205,5 +205,7 @@ extern void vmw_binding_state_free(struct vmw_ctx_binding_state *cbs);
|
||||
extern struct list_head *
|
||||
vmw_binding_state_list(struct vmw_ctx_binding_state *cbs);
|
||||
extern void vmw_binding_state_reset(struct vmw_ctx_binding_state *cbs);
|
||||
extern u32 vmw_binding_dirtying(enum vmw_ctx_binding_type binding_type);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -393,6 +393,7 @@ static void vmw_cmdbuf_ctx_process(struct vmw_cmdbuf_man *man,
|
||||
__vmw_cmdbuf_header_free(entry);
|
||||
break;
|
||||
case SVGA_CB_STATUS_COMMAND_ERROR:
|
||||
WARN_ONCE(true, "Command buffer error.\n");
|
||||
entry->cb_header->status = SVGA_CB_STATUS_NONE;
|
||||
list_add_tail(&entry->list, &man->error);
|
||||
schedule_work(&man->work);
|
||||
@ -511,17 +512,14 @@ static void vmw_cmdbuf_work_func(struct work_struct *work)
|
||||
container_of(work, struct vmw_cmdbuf_man, work);
|
||||
struct vmw_cmdbuf_header *entry, *next;
|
||||
uint32_t dummy;
|
||||
bool restart[SVGA_CB_CONTEXT_MAX];
|
||||
bool send_fence = false;
|
||||
struct list_head restart_head[SVGA_CB_CONTEXT_MAX];
|
||||
int i;
|
||||
struct vmw_cmdbuf_context *ctx;
|
||||
bool global_block = false;
|
||||
|
||||
for_each_cmdbuf_ctx(man, i, ctx) {
|
||||
for_each_cmdbuf_ctx(man, i, ctx)
|
||||
INIT_LIST_HEAD(&restart_head[i]);
|
||||
restart[i] = false;
|
||||
}
|
||||
|
||||
mutex_lock(&man->error_mutex);
|
||||
spin_lock(&man->lock);
|
||||
@ -533,23 +531,23 @@ static void vmw_cmdbuf_work_func(struct work_struct *work)
|
||||
const char *cmd_name;
|
||||
|
||||
list_del_init(&entry->list);
|
||||
restart[entry->cb_context] = true;
|
||||
global_block = true;
|
||||
|
||||
if (!vmw_cmd_describe(header, &error_cmd_size, &cmd_name)) {
|
||||
DRM_ERROR("Unknown command causing device error.\n");
|
||||
DRM_ERROR("Command buffer offset is %lu\n",
|
||||
(unsigned long) cb_hdr->errorOffset);
|
||||
VMW_DEBUG_USER("Unknown command causing device error.\n");
|
||||
VMW_DEBUG_USER("Command buffer offset is %lu\n",
|
||||
(unsigned long) cb_hdr->errorOffset);
|
||||
__vmw_cmdbuf_header_free(entry);
|
||||
send_fence = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
DRM_ERROR("Command \"%s\" causing device error.\n", cmd_name);
|
||||
DRM_ERROR("Command buffer offset is %lu\n",
|
||||
(unsigned long) cb_hdr->errorOffset);
|
||||
DRM_ERROR("Command size is %lu\n",
|
||||
(unsigned long) error_cmd_size);
|
||||
VMW_DEBUG_USER("Command \"%s\" causing device error.\n",
|
||||
cmd_name);
|
||||
VMW_DEBUG_USER("Command buffer offset is %lu\n",
|
||||
(unsigned long) cb_hdr->errorOffset);
|
||||
VMW_DEBUG_USER("Command size is %lu\n",
|
||||
(unsigned long) error_cmd_size);
|
||||
|
||||
new_start_offset = cb_hdr->errorOffset + error_cmd_size;
|
||||
|
||||
|
@ -156,12 +156,9 @@ static void vmw_hw_context_destroy(struct vmw_resource *res)
|
||||
}
|
||||
|
||||
vmw_execbuf_release_pinned_bo(dev_priv);
|
||||
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for surface "
|
||||
"destruction.\n");
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL))
|
||||
return;
|
||||
}
|
||||
|
||||
cmd->header.id = SVGA_3D_CMD_CONTEXT_DESTROY;
|
||||
cmd->header.size = sizeof(cmd->body);
|
||||
@ -210,7 +207,7 @@ static int vmw_gb_context_init(struct vmw_private *dev_priv,
|
||||
for (i = 0; i < SVGA_COTABLE_DX10_MAX; ++i) {
|
||||
uctx->cotables[i] = vmw_cotable_alloc(dev_priv,
|
||||
&uctx->res, i);
|
||||
if (unlikely(IS_ERR(uctx->cotables[i]))) {
|
||||
if (IS_ERR(uctx->cotables[i])) {
|
||||
ret = PTR_ERR(uctx->cotables[i]);
|
||||
goto out_cotables;
|
||||
}
|
||||
@ -259,9 +256,8 @@ static int vmw_context_init(struct vmw_private *dev_priv,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Fifo reserve failed.\n");
|
||||
vmw_resource_unreference(&res);
|
||||
return -ENOMEM;
|
||||
}
|
||||
@ -311,10 +307,8 @@ static int vmw_gb_context_create(struct vmw_resource *res)
|
||||
goto out_no_fifo;
|
||||
}
|
||||
|
||||
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for context "
|
||||
"creation.\n");
|
||||
ret = -ENOMEM;
|
||||
goto out_no_fifo;
|
||||
}
|
||||
@ -345,12 +339,10 @@ static int vmw_gb_context_bind(struct vmw_resource *res,
|
||||
|
||||
BUG_ON(bo->mem.mem_type != VMW_PL_MOB);
|
||||
|
||||
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for context "
|
||||
"binding.\n");
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmd->header.id = SVGA_3D_CMD_BIND_GB_CONTEXT;
|
||||
cmd->header.size = sizeof(cmd->body);
|
||||
cmd->body.cid = res->id;
|
||||
@ -391,10 +383,8 @@ static int vmw_gb_context_unbind(struct vmw_resource *res,
|
||||
|
||||
submit_size = sizeof(*cmd2) + (readback ? sizeof(*cmd1) : 0);
|
||||
|
||||
cmd = vmw_fifo_reserve(dev_priv, submit_size);
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, submit_size);
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for context "
|
||||
"unbinding.\n");
|
||||
mutex_unlock(&dev_priv->binding_mutex);
|
||||
return -ENOMEM;
|
||||
}
|
||||
@ -441,12 +431,9 @@ static int vmw_gb_context_destroy(struct vmw_resource *res)
|
||||
if (likely(res->id == -1))
|
||||
return 0;
|
||||
|
||||
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for context "
|
||||
"destruction.\n");
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmd->header.id = SVGA_3D_CMD_DESTROY_GB_CONTEXT;
|
||||
cmd->header.size = sizeof(cmd->body);
|
||||
@ -487,10 +474,8 @@ static int vmw_dx_context_create(struct vmw_resource *res)
|
||||
goto out_no_fifo;
|
||||
}
|
||||
|
||||
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for context "
|
||||
"creation.\n");
|
||||
ret = -ENOMEM;
|
||||
goto out_no_fifo;
|
||||
}
|
||||
@ -521,12 +506,9 @@ static int vmw_dx_context_bind(struct vmw_resource *res,
|
||||
|
||||
BUG_ON(bo->mem.mem_type != VMW_PL_MOB);
|
||||
|
||||
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for context "
|
||||
"binding.\n");
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmd->header.id = SVGA_3D_CMD_DX_BIND_CONTEXT;
|
||||
cmd->header.size = sizeof(cmd->body);
|
||||
@ -615,10 +597,8 @@ static int vmw_dx_context_unbind(struct vmw_resource *res,
|
||||
|
||||
submit_size = sizeof(*cmd2) + (readback ? sizeof(*cmd1) : 0);
|
||||
|
||||
cmd = vmw_fifo_reserve(dev_priv, submit_size);
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, submit_size);
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for context "
|
||||
"unbinding.\n");
|
||||
mutex_unlock(&dev_priv->binding_mutex);
|
||||
return -ENOMEM;
|
||||
}
|
||||
@ -665,12 +645,9 @@ static int vmw_dx_context_destroy(struct vmw_resource *res)
|
||||
if (likely(res->id == -1))
|
||||
return 0;
|
||||
|
||||
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for context "
|
||||
"destruction.\n");
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmd->header.id = SVGA_3D_CMD_DX_DESTROY_CONTEXT;
|
||||
cmd->header.size = sizeof(cmd->body);
|
||||
@ -751,7 +728,7 @@ static int vmw_context_define(struct drm_device *dev, void *data,
|
||||
int ret;
|
||||
|
||||
if (!dev_priv->has_dx && dx) {
|
||||
DRM_ERROR("DX contexts not supported by device.\n");
|
||||
VMW_DEBUG_USER("DX contexts not supported by device.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -171,12 +171,9 @@ static int vmw_cotable_unscrub(struct vmw_resource *res)
|
||||
WARN_ON_ONCE(bo->mem.mem_type != VMW_PL_MOB);
|
||||
lockdep_assert_held(&bo->resv->lock.base);
|
||||
|
||||
cmd = vmw_fifo_reserve_dx(dev_priv, sizeof(*cmd), SVGA3D_INVALID_ID);
|
||||
if (!cmd) {
|
||||
DRM_ERROR("Failed reserving FIFO space for cotable "
|
||||
"binding.\n");
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
|
||||
if (!cmd)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
WARN_ON(vcotbl->ctx->id == SVGA3D_INVALID_ID);
|
||||
WARN_ON(bo->mem.mem_type != VMW_PL_MOB);
|
||||
@ -262,12 +259,9 @@ int vmw_cotable_scrub(struct vmw_resource *res, bool readback)
|
||||
if (readback)
|
||||
submit_size += sizeof(*cmd0);
|
||||
|
||||
cmd1 = vmw_fifo_reserve_dx(dev_priv, submit_size, SVGA3D_INVALID_ID);
|
||||
if (!cmd1) {
|
||||
DRM_ERROR("Failed reserving FIFO space for cotable "
|
||||
"unbinding.\n");
|
||||
cmd1 = VMW_FIFO_RESERVE(dev_priv, submit_size);
|
||||
if (!cmd1)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
vcotbl->size_read_back = 0;
|
||||
if (readback) {
|
||||
@ -351,13 +345,10 @@ static int vmw_cotable_readback(struct vmw_resource *res)
|
||||
struct vmw_fence_obj *fence;
|
||||
|
||||
if (!vcotbl->scrubbed) {
|
||||
cmd = vmw_fifo_reserve_dx(dev_priv, sizeof(*cmd),
|
||||
SVGA3D_INVALID_ID);
|
||||
if (!cmd) {
|
||||
DRM_ERROR("Failed reserving FIFO space for cotable "
|
||||
"readback.\n");
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
|
||||
if (!cmd)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmd->header.id = SVGA_3D_CMD_DX_READBACK_COTABLE;
|
||||
cmd->header.size = sizeof(cmd->body);
|
||||
cmd->body.cid = vcotbl->ctx->id;
|
||||
|
@ -699,6 +699,8 @@ extern int vmw_user_stream_lookup(struct vmw_private *dev_priv,
|
||||
uint32_t *inout_id,
|
||||
struct vmw_resource **out);
|
||||
extern void vmw_resource_unreserve(struct vmw_resource *res,
|
||||
bool dirty_set,
|
||||
bool dirty,
|
||||
bool switch_backup,
|
||||
struct vmw_buffer_object *new_backup,
|
||||
unsigned long new_backup_offset);
|
||||
@ -811,7 +813,6 @@ extern int vmw_fifo_init(struct vmw_private *dev_priv,
|
||||
struct vmw_fifo_state *fifo);
|
||||
extern void vmw_fifo_release(struct vmw_private *dev_priv,
|
||||
struct vmw_fifo_state *fifo);
|
||||
extern void *vmw_fifo_reserve(struct vmw_private *dev_priv, uint32_t bytes);
|
||||
extern void *
|
||||
vmw_fifo_reserve_dx(struct vmw_private *dev_priv, uint32_t bytes, int ctx_id);
|
||||
extern void vmw_fifo_commit(struct vmw_private *dev_priv, uint32_t bytes);
|
||||
@ -827,6 +828,18 @@ extern int vmw_fifo_emit_dummy_query(struct vmw_private *dev_priv,
|
||||
extern int vmw_fifo_flush(struct vmw_private *dev_priv,
|
||||
bool interruptible);
|
||||
|
||||
#define VMW_FIFO_RESERVE_DX(__priv, __bytes, __ctx_id) \
|
||||
({ \
|
||||
vmw_fifo_reserve_dx(__priv, __bytes, __ctx_id) ? : ({ \
|
||||
DRM_ERROR("FIFO reserve failed at %s for %u bytes\n", \
|
||||
__func__, (unsigned int) __bytes); \
|
||||
NULL; \
|
||||
}); \
|
||||
})
|
||||
|
||||
#define VMW_FIFO_RESERVE(__priv, __bytes) \
|
||||
VMW_FIFO_RESERVE_DX(__priv, __bytes, SVGA3D_INVALID_ID)
|
||||
|
||||
/**
|
||||
* TTM glue - vmwgfx_ttm_glue.c
|
||||
*/
|
||||
@ -1311,6 +1324,20 @@ int vmw_host_get_guestinfo(const char *guest_info_param,
|
||||
char *buffer, size_t *length);
|
||||
int vmw_host_log(const char *log);
|
||||
|
||||
/* VMW logging */
|
||||
|
||||
/**
|
||||
* VMW_DEBUG_USER - Debug output for user-space debugging.
|
||||
*
|
||||
* @fmt: printf() like format string.
|
||||
*
|
||||
* This macro is for logging user-space error and debugging messages for e.g.
|
||||
* command buffer execution errors due to malformed commands, invalid context,
|
||||
* etc.
|
||||
*/
|
||||
#define VMW_DEBUG_USER(fmt, ...) \
|
||||
DRM_DEBUG_DRIVER(fmt, ##__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Inline helper functions
|
||||
*/
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -642,12 +642,11 @@ int vmw_fb_init(struct vmw_private *vmw_priv)
|
||||
struct vmw_fb_par *par;
|
||||
struct fb_info *info;
|
||||
unsigned fb_width, fb_height;
|
||||
unsigned fb_bpp, fb_depth, fb_offset, fb_pitch, fb_size;
|
||||
unsigned int fb_bpp, fb_pitch, fb_size;
|
||||
struct drm_display_mode *init_mode;
|
||||
int ret;
|
||||
|
||||
fb_bpp = 32;
|
||||
fb_depth = 24;
|
||||
|
||||
/* XXX As shouldn't these be as well. */
|
||||
fb_width = min(vmw_priv->fb_max_width, (unsigned)2048);
|
||||
@ -655,7 +654,6 @@ int vmw_fb_init(struct vmw_private *vmw_priv)
|
||||
|
||||
fb_pitch = fb_width * fb_bpp / 8;
|
||||
fb_size = fb_pitch * fb_height;
|
||||
fb_offset = vmw_read(vmw_priv, SVGA_REG_FB_OFFSET);
|
||||
|
||||
info = framebuffer_alloc(sizeof(*par), device);
|
||||
if (!info)
|
||||
|
@ -395,12 +395,8 @@ void *vmw_fifo_reserve_dx(struct vmw_private *dev_priv, uint32_t bytes,
|
||||
WARN(1, "Command buffer has not been allocated.\n");
|
||||
ret = NULL;
|
||||
}
|
||||
if (IS_ERR_OR_NULL(ret)) {
|
||||
DRM_ERROR("Fifo reserve failure of %u bytes.\n",
|
||||
(unsigned) bytes);
|
||||
dump_stack();
|
||||
if (IS_ERR_OR_NULL(ret))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -544,7 +540,7 @@ int vmw_fifo_send_fence(struct vmw_private *dev_priv, uint32_t *seqno)
|
||||
int ret = 0;
|
||||
uint32_t bytes = sizeof(u32) + sizeof(*cmd_fence);
|
||||
|
||||
fm = vmw_fifo_reserve(dev_priv, bytes);
|
||||
fm = VMW_FIFO_RESERVE(dev_priv, bytes);
|
||||
if (unlikely(fm == NULL)) {
|
||||
*seqno = atomic_read(&dev_priv->marker_seq);
|
||||
ret = -ENOMEM;
|
||||
@ -603,12 +599,9 @@ static int vmw_fifo_emit_dummy_legacy_query(struct vmw_private *dev_priv,
|
||||
SVGA3dCmdWaitForQuery body;
|
||||
} *cmd;
|
||||
|
||||
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
|
||||
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Out of fifo space for dummy query.\n");
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmd->header.id = SVGA_3D_CMD_WAIT_FOR_QUERY;
|
||||
cmd->header.size = sizeof(cmd->body);
|
||||
@ -652,12 +645,9 @@ static int vmw_fifo_emit_dummy_gb_query(struct vmw_private *dev_priv,
|
||||
SVGA3dCmdWaitForGBQuery body;
|
||||
} *cmd;
|
||||
|
||||
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
|
||||
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Out of fifo space for dummy query.\n");
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmd->header.id = SVGA_3D_CMD_WAIT_FOR_GB_QUERY;
|
||||
cmd->header.size = sizeof(cmd->body);
|
||||
@ -699,8 +689,3 @@ int vmw_fifo_emit_dummy_query(struct vmw_private *dev_priv,
|
||||
|
||||
return vmw_fifo_emit_dummy_legacy_query(dev_priv, cid);
|
||||
}
|
||||
|
||||
void *vmw_fifo_reserve(struct vmw_private *dev_priv, uint32_t bytes)
|
||||
{
|
||||
return vmw_fifo_reserve_dx(dev_priv, bytes, SVGA3D_INVALID_ID);
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ static int vmw_gmr2_bind(struct vmw_private *dev_priv,
|
||||
uint32_t cmd_size = define_size + remap_size;
|
||||
uint32_t i;
|
||||
|
||||
cmd_orig = cmd = vmw_fifo_reserve(dev_priv, cmd_size);
|
||||
cmd_orig = cmd = VMW_FIFO_RESERVE(dev_priv, cmd_size);
|
||||
if (unlikely(cmd == NULL))
|
||||
return -ENOMEM;
|
||||
|
||||
@ -110,11 +110,10 @@ static void vmw_gmr2_unbind(struct vmw_private *dev_priv,
|
||||
uint32_t define_size = sizeof(define_cmd) + 4;
|
||||
uint32_t *cmd;
|
||||
|
||||
cmd = vmw_fifo_reserve(dev_priv, define_size);
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("GMR2 unbind failed.\n");
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, define_size);
|
||||
if (unlikely(cmd == NULL))
|
||||
return;
|
||||
}
|
||||
|
||||
define_cmd.gmrId = gmr_id;
|
||||
define_cmd.numPages = 0;
|
||||
|
||||
|
@ -188,7 +188,7 @@ int vmw_get_cap_3d_ioctl(struct drm_device *dev, void *data,
|
||||
struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv);
|
||||
|
||||
if (unlikely(arg->pad64 != 0 || arg->max_size == 0)) {
|
||||
DRM_ERROR("Illegal GET_3D_CAP argument.\n");
|
||||
VMW_DEBUG_USER("Illegal GET_3D_CAP argument.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -268,7 +268,7 @@ int vmw_present_ioctl(struct drm_device *dev, void *data,
|
||||
return 0;
|
||||
|
||||
if (clips_ptr == NULL) {
|
||||
DRM_ERROR("Variable clips_ptr must be specified.\n");
|
||||
VMW_DEBUG_USER("Variable clips_ptr must be specified.\n");
|
||||
ret = -EINVAL;
|
||||
goto out_clips;
|
||||
}
|
||||
@ -291,7 +291,7 @@ int vmw_present_ioctl(struct drm_device *dev, void *data,
|
||||
|
||||
fb = drm_framebuffer_lookup(dev, file_priv, arg->fb_id);
|
||||
if (!fb) {
|
||||
DRM_ERROR("Invalid framebuffer id.\n");
|
||||
VMW_DEBUG_USER("Invalid framebuffer id.\n");
|
||||
ret = -ENOENT;
|
||||
goto out_no_fb;
|
||||
}
|
||||
@ -351,7 +351,7 @@ int vmw_present_readback_ioctl(struct drm_device *dev, void *data,
|
||||
return 0;
|
||||
|
||||
if (clips_ptr == NULL) {
|
||||
DRM_ERROR("Argument clips_ptr must be specified.\n");
|
||||
VMW_DEBUG_USER("Argument clips_ptr must be specified.\n");
|
||||
ret = -EINVAL;
|
||||
goto out_clips;
|
||||
}
|
||||
@ -374,14 +374,14 @@ int vmw_present_readback_ioctl(struct drm_device *dev, void *data,
|
||||
|
||||
fb = drm_framebuffer_lookup(dev, file_priv, arg->fb_id);
|
||||
if (!fb) {
|
||||
DRM_ERROR("Invalid framebuffer id.\n");
|
||||
VMW_DEBUG_USER("Invalid framebuffer id.\n");
|
||||
ret = -ENOENT;
|
||||
goto out_no_fb;
|
||||
}
|
||||
|
||||
vfb = vmw_framebuffer_to_vfb(fb);
|
||||
if (!vfb->bo) {
|
||||
DRM_ERROR("Framebuffer not buffer backed.\n");
|
||||
VMW_DEBUG_USER("Framebuffer not buffer backed.\n");
|
||||
ret = -EINVAL;
|
||||
goto out_no_ttm_lock;
|
||||
}
|
||||
|
@ -64,11 +64,9 @@ static int vmw_cursor_update_image(struct vmw_private *dev_priv,
|
||||
if (!image)
|
||||
return -EINVAL;
|
||||
|
||||
cmd = vmw_fifo_reserve(dev_priv, cmd_size);
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Fifo reserve failed.\n");
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, cmd_size);
|
||||
if (unlikely(cmd == NULL))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(cmd, 0, sizeof(*cmd));
|
||||
|
||||
@ -1202,7 +1200,7 @@ static int vmw_create_bo_proxy(struct drm_device *dev,
|
||||
vmw_bo_unreference(&res->backup);
|
||||
res->backup = vmw_bo_reference(bo_mob);
|
||||
res->backup_offset = 0;
|
||||
vmw_resource_unreserve(res, false, NULL, 0);
|
||||
vmw_resource_unreserve(res, false, false, false, NULL, 0);
|
||||
mutex_unlock(&res->dev_priv->cmdbuf_mutex);
|
||||
|
||||
return 0;
|
||||
@ -2468,13 +2466,11 @@ int vmw_kms_helper_dirty(struct vmw_private *dev_priv,
|
||||
|
||||
dirty->unit = unit;
|
||||
if (dirty->fifo_reserve_size > 0) {
|
||||
dirty->cmd = vmw_fifo_reserve(dev_priv,
|
||||
dirty->cmd = VMW_FIFO_RESERVE(dev_priv,
|
||||
dirty->fifo_reserve_size);
|
||||
if (!dirty->cmd) {
|
||||
DRM_ERROR("Couldn't reserve fifo space "
|
||||
"for dirty blits.\n");
|
||||
if (!dirty->cmd)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(dirty->cmd, 0, dirty->fifo_reserve_size);
|
||||
}
|
||||
dirty->num_hits = 0;
|
||||
@ -2604,12 +2600,9 @@ int vmw_kms_update_proxy(struct vmw_resource *res,
|
||||
if (!clips)
|
||||
return 0;
|
||||
|
||||
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd) * num_clips);
|
||||
if (!cmd) {
|
||||
DRM_ERROR("Couldn't reserve fifo space for proxy surface "
|
||||
"update.\n");
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd) * num_clips);
|
||||
if (!cmd)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_clips; ++i, clips += increment, ++cmd) {
|
||||
box = &cmd->body.box;
|
||||
@ -2827,7 +2820,8 @@ int vmw_du_helper_plane_update(struct vmw_du_update_plane *update)
|
||||
container_of(update->vfb, typeof(*vfbs), base);
|
||||
|
||||
ret = vmw_validation_add_resource(&val_ctx, &vfbs->surface->res,
|
||||
0, NULL, NULL);
|
||||
0, VMW_RES_DIRTY_NONE, NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
@ -2838,7 +2832,7 @@ int vmw_du_helper_plane_update(struct vmw_du_update_plane *update)
|
||||
goto out_unref;
|
||||
|
||||
reserved_size = update->calc_fifo_size(update, num_hits);
|
||||
cmd_start = vmw_fifo_reserve(update->dev_priv, reserved_size);
|
||||
cmd_start = VMW_FIFO_RESERVE(update->dev_priv, reserved_size);
|
||||
if (!cmd_start) {
|
||||
ret = -ENOMEM;
|
||||
goto out_revert;
|
||||
|
@ -554,11 +554,9 @@ int vmw_kms_ldu_do_bo_dirty(struct vmw_private *dev_priv,
|
||||
} *cmd;
|
||||
|
||||
fifo_size = sizeof(*cmd) * num_clips;
|
||||
cmd = vmw_fifo_reserve(dev_priv, fifo_size);
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Fifo reserve failed.\n");
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, fifo_size);
|
||||
if (unlikely(cmd == NULL))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(cmd, 0, fifo_size);
|
||||
for (i = 0; i < num_clips; i++, clips += increment) {
|
||||
|
@ -146,9 +146,8 @@ static int vmw_setup_otable_base(struct vmw_private *dev_priv,
|
||||
mob->pt_level += VMW_MOBFMT_PTDEPTH_1 - SVGA3D_MOBFMT_PTDEPTH_1;
|
||||
}
|
||||
|
||||
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for OTable setup.\n");
|
||||
ret = -ENOMEM;
|
||||
goto out_no_fifo;
|
||||
}
|
||||
@ -202,12 +201,9 @@ static void vmw_takedown_otable_base(struct vmw_private *dev_priv,
|
||||
return;
|
||||
|
||||
bo = otable->page_table->pt_bo;
|
||||
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for OTable "
|
||||
"takedown.\n");
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL))
|
||||
return;
|
||||
}
|
||||
|
||||
memset(cmd, 0, sizeof(*cmd));
|
||||
cmd->header.id = SVGA_3D_CMD_SET_OTABLE_BASE;
|
||||
@ -614,16 +610,14 @@ void vmw_mob_unbind(struct vmw_private *dev_priv,
|
||||
BUG_ON(ret != 0);
|
||||
}
|
||||
|
||||
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for Memory "
|
||||
"Object unbinding.\n");
|
||||
} else {
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
|
||||
if (cmd) {
|
||||
cmd->header.id = SVGA_3D_CMD_DESTROY_GB_MOB;
|
||||
cmd->header.size = sizeof(cmd->body);
|
||||
cmd->body.mobid = mob->id;
|
||||
vmw_fifo_commit(dev_priv, sizeof(*cmd));
|
||||
}
|
||||
|
||||
if (bo) {
|
||||
vmw_bo_fence_single(bo, NULL);
|
||||
ttm_bo_unreserve(bo);
|
||||
@ -683,12 +677,9 @@ int vmw_mob_bind(struct vmw_private *dev_priv,
|
||||
|
||||
vmw_fifo_resource_inc(dev_priv);
|
||||
|
||||
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for Memory "
|
||||
"Object binding.\n");
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL))
|
||||
goto out_no_cmd_space;
|
||||
}
|
||||
|
||||
cmd->header.id = SVGA_3D_CMD_DEFINE_GB_MOB64;
|
||||
cmd->header.size = sizeof(cmd->body);
|
||||
|
@ -124,7 +124,7 @@ static int vmw_overlay_send_put(struct vmw_private *dev_priv,
|
||||
|
||||
fifo_size = sizeof(*cmds) + sizeof(*flush) + sizeof(*items) * num_items;
|
||||
|
||||
cmds = vmw_fifo_reserve(dev_priv, fifo_size);
|
||||
cmds = VMW_FIFO_RESERVE(dev_priv, fifo_size);
|
||||
/* hardware has hung, can't do anything here */
|
||||
if (!cmds)
|
||||
return -ENOMEM;
|
||||
@ -194,7 +194,7 @@ static int vmw_overlay_send_stop(struct vmw_private *dev_priv,
|
||||
int ret;
|
||||
|
||||
for (;;) {
|
||||
cmds = vmw_fifo_reserve(dev_priv, sizeof(*cmds));
|
||||
cmds = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmds));
|
||||
if (cmds)
|
||||
break;
|
||||
|
||||
|
@ -365,14 +365,6 @@ static int vmw_resource_do_validate(struct vmw_resource *res,
|
||||
list_add_tail(&res->mob_head, &res->backup->res_list);
|
||||
}
|
||||
|
||||
/*
|
||||
* Only do this on write operations, and move to
|
||||
* vmw_resource_unreserve if it can be called after
|
||||
* backup buffers have been unreserved. Otherwise
|
||||
* sort out locking.
|
||||
*/
|
||||
res->res_dirty = true;
|
||||
|
||||
return 0;
|
||||
|
||||
out_bind_failed:
|
||||
@ -386,6 +378,8 @@ out_bind_failed:
|
||||
* command submission.
|
||||
*
|
||||
* @res: Pointer to the struct vmw_resource to unreserve.
|
||||
* @dirty_set: Change dirty status of the resource.
|
||||
* @dirty: When changing dirty status indicates the new status.
|
||||
* @switch_backup: Backup buffer has been switched.
|
||||
* @new_backup: Pointer to new backup buffer if command submission
|
||||
* switched. May be NULL.
|
||||
@ -395,6 +389,8 @@ out_bind_failed:
|
||||
* resource lru list, so that it can be evicted if necessary.
|
||||
*/
|
||||
void vmw_resource_unreserve(struct vmw_resource *res,
|
||||
bool dirty_set,
|
||||
bool dirty,
|
||||
bool switch_backup,
|
||||
struct vmw_buffer_object *new_backup,
|
||||
unsigned long new_backup_offset)
|
||||
@ -422,6 +418,9 @@ void vmw_resource_unreserve(struct vmw_resource *res,
|
||||
if (switch_backup)
|
||||
res->backup_offset = new_backup_offset;
|
||||
|
||||
if (dirty_set)
|
||||
res->res_dirty = dirty;
|
||||
|
||||
if (!res->func->may_evict || res->id == -1 || res->pin_count)
|
||||
return;
|
||||
|
||||
@ -696,7 +695,7 @@ void vmw_resource_unbind_list(struct vmw_buffer_object *vbo)
|
||||
if (!res->func->unbind)
|
||||
continue;
|
||||
|
||||
(void) res->func->unbind(res, true, &val_buf);
|
||||
(void) res->func->unbind(res, res->res_dirty, &val_buf);
|
||||
res->backup_dirty = true;
|
||||
res->res_dirty = false;
|
||||
list_del_init(&res->mob_head);
|
||||
@ -731,12 +730,9 @@ int vmw_query_readback_all(struct vmw_buffer_object *dx_query_mob)
|
||||
dx_query_ctx = dx_query_mob->dx_query_ctx;
|
||||
dev_priv = dx_query_ctx->dev_priv;
|
||||
|
||||
cmd = vmw_fifo_reserve_dx(dev_priv, sizeof(*cmd), dx_query_ctx->id);
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for "
|
||||
"query MOB read back.\n");
|
||||
cmd = VMW_FIFO_RESERVE_DX(dev_priv, sizeof(*cmd), dx_query_ctx->id);
|
||||
if (unlikely(cmd == NULL))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmd->header.id = SVGA_3D_CMD_DX_READBACK_ALL_QUERY;
|
||||
cmd->header.size = sizeof(cmd->body);
|
||||
@ -932,7 +928,7 @@ int vmw_resource_pin(struct vmw_resource *res, bool interruptible)
|
||||
res->pin_count++;
|
||||
|
||||
out_no_validate:
|
||||
vmw_resource_unreserve(res, false, NULL, 0UL);
|
||||
vmw_resource_unreserve(res, false, false, false, NULL, 0UL);
|
||||
out_no_reserve:
|
||||
mutex_unlock(&dev_priv->cmdbuf_mutex);
|
||||
ttm_write_unlock(&dev_priv->reservation_sem);
|
||||
@ -968,7 +964,7 @@ void vmw_resource_unpin(struct vmw_resource *res)
|
||||
ttm_bo_unreserve(&vbo->base);
|
||||
}
|
||||
|
||||
vmw_resource_unreserve(res, false, NULL, 0UL);
|
||||
vmw_resource_unreserve(res, false, false, false, NULL, 0UL);
|
||||
|
||||
mutex_unlock(&dev_priv->cmdbuf_mutex);
|
||||
ttm_read_unlock(&dev_priv->reservation_sem);
|
||||
|
@ -130,12 +130,9 @@ static int vmw_sou_fifo_create(struct vmw_private *dev_priv,
|
||||
BUG_ON(!sou->buffer);
|
||||
|
||||
fifo_size = sizeof(*cmd);
|
||||
cmd = vmw_fifo_reserve(dev_priv, fifo_size);
|
||||
/* The hardware has hung, nothing we can do about it here. */
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Fifo reserve failed.\n");
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, fifo_size);
|
||||
if (unlikely(cmd == NULL))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(cmd, 0, fifo_size);
|
||||
cmd->header.cmdType = SVGA_CMD_DEFINE_SCREEN;
|
||||
@ -182,12 +179,9 @@ static int vmw_sou_fifo_destroy(struct vmw_private *dev_priv,
|
||||
return 0;
|
||||
|
||||
fifo_size = sizeof(*cmd);
|
||||
cmd = vmw_fifo_reserve(dev_priv, fifo_size);
|
||||
/* the hardware has hung, nothing we can do about it here */
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Fifo reserve failed.\n");
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, fifo_size);
|
||||
if (unlikely(cmd == NULL))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(cmd, 0, fifo_size);
|
||||
cmd->header.cmdType = SVGA_CMD_DESTROY_SCREEN;
|
||||
@ -998,11 +992,9 @@ static int do_bo_define_gmrfb(struct vmw_private *dev_priv,
|
||||
if (depth == 32)
|
||||
depth = 24;
|
||||
|
||||
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
|
||||
if (!cmd) {
|
||||
DRM_ERROR("Out of fifo space for dirty framebuffer command.\n");
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
|
||||
if (!cmd)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmd->header = SVGA_CMD_DEFINE_GMRFB;
|
||||
cmd->body.format.bitsPerPixel = framebuffer->base.format->cpp[0] * 8;
|
||||
@ -1148,7 +1140,8 @@ int vmw_kms_sou_do_surface_dirty(struct vmw_private *dev_priv,
|
||||
if (!srf)
|
||||
srf = &vfbs->surface->res;
|
||||
|
||||
ret = vmw_validation_add_resource(&val_ctx, srf, 0, NULL, NULL);
|
||||
ret = vmw_validation_add_resource(&val_ctx, srf, 0, VMW_RES_DIRTY_NONE,
|
||||
NULL, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -218,10 +218,8 @@ static int vmw_gb_shader_create(struct vmw_resource *res)
|
||||
goto out_no_fifo;
|
||||
}
|
||||
|
||||
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for shader "
|
||||
"creation.\n");
|
||||
ret = -ENOMEM;
|
||||
goto out_no_fifo;
|
||||
}
|
||||
@ -254,12 +252,9 @@ static int vmw_gb_shader_bind(struct vmw_resource *res,
|
||||
|
||||
BUG_ON(bo->mem.mem_type != VMW_PL_MOB);
|
||||
|
||||
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for shader "
|
||||
"binding.\n");
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmd->header.id = SVGA_3D_CMD_BIND_GB_SHADER;
|
||||
cmd->header.size = sizeof(cmd->body);
|
||||
@ -285,12 +280,9 @@ static int vmw_gb_shader_unbind(struct vmw_resource *res,
|
||||
|
||||
BUG_ON(res->backup->base.mem.mem_type != VMW_PL_MOB);
|
||||
|
||||
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for shader "
|
||||
"unbinding.\n");
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmd->header.id = SVGA_3D_CMD_BIND_GB_SHADER;
|
||||
cmd->header.size = sizeof(cmd->body);
|
||||
@ -328,10 +320,8 @@ static int vmw_gb_shader_destroy(struct vmw_resource *res)
|
||||
mutex_lock(&dev_priv->binding_mutex);
|
||||
vmw_binding_res_list_scrub(&res->binding_head);
|
||||
|
||||
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for shader "
|
||||
"destruction.\n");
|
||||
mutex_unlock(&dev_priv->binding_mutex);
|
||||
return -ENOMEM;
|
||||
}
|
||||
@ -400,13 +390,9 @@ static int vmw_dx_shader_unscrub(struct vmw_resource *res)
|
||||
if (!list_empty(&shader->cotable_head) || !shader->committed)
|
||||
return 0;
|
||||
|
||||
cmd = vmw_fifo_reserve_dx(dev_priv, sizeof(*cmd),
|
||||
shader->ctx->id);
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for shader "
|
||||
"scrubbing.\n");
|
||||
cmd = VMW_FIFO_RESERVE_DX(dev_priv, sizeof(*cmd), shader->ctx->id);
|
||||
if (unlikely(cmd == NULL))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmd->header.id = SVGA_3D_CMD_DX_BIND_SHADER;
|
||||
cmd->header.size = sizeof(cmd->body);
|
||||
@ -491,12 +477,9 @@ static int vmw_dx_shader_scrub(struct vmw_resource *res)
|
||||
return 0;
|
||||
|
||||
WARN_ON_ONCE(!shader->committed);
|
||||
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for shader "
|
||||
"scrubbing.\n");
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmd->header.id = SVGA_3D_CMD_DX_BIND_SHADER;
|
||||
cmd->header.size = sizeof(cmd->body);
|
||||
@ -865,14 +848,13 @@ static int vmw_shader_define(struct drm_device *dev, struct drm_file *file_priv,
|
||||
ret = vmw_user_bo_lookup(tfile, buffer_handle,
|
||||
&buffer, NULL);
|
||||
if (unlikely(ret != 0)) {
|
||||
DRM_ERROR("Could not find buffer for shader "
|
||||
"creation.\n");
|
||||
VMW_DEBUG_USER("Couldn't find buffer for shader creation.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((u64)buffer->base.num_pages * PAGE_SIZE <
|
||||
(u64)size + (u64)offset) {
|
||||
DRM_ERROR("Illegal buffer- or shader size.\n");
|
||||
VMW_DEBUG_USER("Illegal buffer- or shader size.\n");
|
||||
ret = -EINVAL;
|
||||
goto out_bad_arg;
|
||||
}
|
||||
@ -886,7 +868,7 @@ static int vmw_shader_define(struct drm_device *dev, struct drm_file *file_priv,
|
||||
shader_type = SVGA3D_SHADERTYPE_PS;
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Illegal shader type.\n");
|
||||
VMW_DEBUG_USER("Illegal shader type.\n");
|
||||
ret = -EINVAL;
|
||||
goto out_bad_arg;
|
||||
}
|
||||
|
@ -239,17 +239,17 @@ vmw_simple_resource_lookup(struct ttm_object_file *tfile,
|
||||
|
||||
base = ttm_base_object_lookup(tfile, handle);
|
||||
if (!base) {
|
||||
DRM_ERROR("Invalid %s handle 0x%08lx.\n",
|
||||
func->res_func.type_name,
|
||||
(unsigned long) handle);
|
||||
VMW_DEBUG_USER("Invalid %s handle 0x%08lx.\n",
|
||||
func->res_func.type_name,
|
||||
(unsigned long) handle);
|
||||
return ERR_PTR(-ESRCH);
|
||||
}
|
||||
|
||||
if (ttm_base_object_type(base) != func->ttm_res_type) {
|
||||
ttm_base_object_unref(&base);
|
||||
DRM_ERROR("Invalid type of %s handle 0x%08lx.\n",
|
||||
func->res_func.type_name,
|
||||
(unsigned long) handle);
|
||||
VMW_DEBUG_USER("Invalid type of %s handle 0x%08lx.\n",
|
||||
func->res_func.type_name,
|
||||
(unsigned long) handle);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
|
@ -170,13 +170,12 @@ static int vmw_view_create(struct vmw_resource *res)
|
||||
return 0;
|
||||
}
|
||||
|
||||
cmd = vmw_fifo_reserve_dx(res->dev_priv, view->cmd_size,
|
||||
view->ctx->id);
|
||||
cmd = VMW_FIFO_RESERVE_DX(res->dev_priv, view->cmd_size, view->ctx->id);
|
||||
if (!cmd) {
|
||||
DRM_ERROR("Failed reserving FIFO space for view creation.\n");
|
||||
mutex_unlock(&dev_priv->binding_mutex);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memcpy(cmd, &view->cmd, view->cmd_size);
|
||||
WARN_ON(cmd->body.view_id != view->view_id);
|
||||
/* Sid may have changed due to surface eviction. */
|
||||
@ -214,12 +213,9 @@ static int vmw_view_destroy(struct vmw_resource *res)
|
||||
if (!view->committed || res->id == -1)
|
||||
return 0;
|
||||
|
||||
cmd = vmw_fifo_reserve_dx(dev_priv, sizeof(*cmd), view->ctx->id);
|
||||
if (!cmd) {
|
||||
DRM_ERROR("Failed reserving FIFO space for view "
|
||||
"destruction.\n");
|
||||
cmd = VMW_FIFO_RESERVE_DX(dev_priv, sizeof(*cmd), view->ctx->id);
|
||||
if (!cmd)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmd->header.id = vmw_view_destroy_cmds[view->view_type];
|
||||
cmd->header.size = sizeof(cmd->body);
|
||||
@ -338,12 +334,12 @@ int vmw_view_add(struct vmw_cmdbuf_res_manager *man,
|
||||
|
||||
if (cmd_size != vmw_view_define_sizes[view_type] +
|
||||
sizeof(SVGA3dCmdHeader)) {
|
||||
DRM_ERROR("Illegal view create command size.\n");
|
||||
VMW_DEBUG_USER("Illegal view create command size.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!vmw_view_id_ok(user_key, view_type)) {
|
||||
DRM_ERROR("Illegal view add view id.\n");
|
||||
VMW_DEBUG_USER("Illegal view add view id.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -352,8 +348,7 @@ int vmw_view_add(struct vmw_cmdbuf_res_manager *man,
|
||||
ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv), size, &ttm_opt_ctx);
|
||||
if (ret) {
|
||||
if (ret != -ERESTARTSYS)
|
||||
DRM_ERROR("Out of graphics memory for view"
|
||||
" creation.\n");
|
||||
DRM_ERROR("Out of graphics memory for view creation\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -413,7 +408,7 @@ int vmw_view_remove(struct vmw_cmdbuf_res_manager *man,
|
||||
struct vmw_resource **res_p)
|
||||
{
|
||||
if (!vmw_view_id_ok(user_key, view_type)) {
|
||||
DRM_ERROR("Illegal view remove view id.\n");
|
||||
VMW_DEBUG_USER("Illegal view remove view id.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -497,6 +492,30 @@ struct vmw_resource *vmw_view_lookup(struct vmw_cmdbuf_res_manager *man,
|
||||
vmw_view_key(user_key, view_type));
|
||||
}
|
||||
|
||||
/**
|
||||
* vmw_view_dirtying - Return whether a view type is dirtying its resource
|
||||
* @res: Pointer to the view
|
||||
*
|
||||
* Each time a resource is put on the validation list as the result of a
|
||||
* view pointing to it, we need to determine whether that resource will
|
||||
* be dirtied (written to by the GPU) as a result of the corresponding
|
||||
* GPU operation. Currently only rendertarget- and depth-stencil views are
|
||||
* capable of dirtying its resource.
|
||||
*
|
||||
* Return: Whether the view type of @res dirties the resource it points to.
|
||||
*/
|
||||
u32 vmw_view_dirtying(struct vmw_resource *res)
|
||||
{
|
||||
static u32 view_is_dirtying[vmw_view_max] = {
|
||||
[vmw_view_rt] = VMW_RES_DIRTY_SET,
|
||||
[vmw_view_ds] = VMW_RES_DIRTY_SET,
|
||||
};
|
||||
|
||||
/* Update this function as we add more view types */
|
||||
BUILD_BUG_ON(vmw_view_max != 3);
|
||||
return view_is_dirtying[vmw_view(res)->view_type];
|
||||
}
|
||||
|
||||
const u32 vmw_view_destroy_cmds[] = {
|
||||
[vmw_view_sr] = SVGA_3D_CMD_DX_DESTROY_SHADERRESOURCE_VIEW,
|
||||
[vmw_view_rt] = SVGA_3D_CMD_DX_DESTROY_RENDERTARGET_VIEW,
|
||||
|
@ -157,4 +157,5 @@ extern struct vmw_resource *vmw_view_srf(struct vmw_resource *res);
|
||||
extern struct vmw_resource *vmw_view_lookup(struct vmw_cmdbuf_res_manager *man,
|
||||
enum vmw_view_type view_type,
|
||||
u32 user_key);
|
||||
extern u32 vmw_view_dirtying(struct vmw_resource *res);
|
||||
#endif
|
||||
|
@ -111,7 +111,7 @@ struct vmw_stdu_update_gb_image {
|
||||
*/
|
||||
struct vmw_screen_target_display_unit {
|
||||
struct vmw_display_unit base;
|
||||
const struct vmw_surface *display_srf;
|
||||
struct vmw_surface *display_srf;
|
||||
enum stdu_content_type content_fb_type;
|
||||
s32 display_width, display_height;
|
||||
|
||||
@ -167,12 +167,9 @@ static int vmw_stdu_define_st(struct vmw_private *dev_priv,
|
||||
SVGA3dCmdDefineGBScreenTarget body;
|
||||
} *cmd;
|
||||
|
||||
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
|
||||
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Out of FIFO space defining Screen Target\n");
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmd->header.id = SVGA_3D_CMD_DEFINE_GB_SCREENTARGET;
|
||||
cmd->header.size = sizeof(cmd->body);
|
||||
@ -229,12 +226,9 @@ static int vmw_stdu_bind_st(struct vmw_private *dev_priv,
|
||||
memset(&image, 0, sizeof(image));
|
||||
image.sid = res ? res->id : SVGA3D_INVALID_ID;
|
||||
|
||||
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
|
||||
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Out of FIFO space binding a screen target\n");
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmd->header.id = SVGA_3D_CMD_BIND_GB_SCREENTARGET;
|
||||
cmd->header.size = sizeof(cmd->body);
|
||||
@ -296,12 +290,9 @@ static int vmw_stdu_update_st(struct vmw_private *dev_priv,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
|
||||
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Out of FIFO space updating a Screen Target\n");
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
vmw_stdu_populate_update(cmd, stdu->base.unit,
|
||||
0, stdu->display_width,
|
||||
@ -335,12 +326,9 @@ static int vmw_stdu_destroy_st(struct vmw_private *dev_priv,
|
||||
if (unlikely(!stdu->defined))
|
||||
return 0;
|
||||
|
||||
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
|
||||
|
||||
if (unlikely(cmd == NULL)) {
|
||||
DRM_ERROR("Out of FIFO space, screen target not destroyed\n");
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(cmd == NULL))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmd->header.id = SVGA_3D_CMD_DESTROY_GB_SCREENTARGET;
|
||||
cmd->header.size = sizeof(cmd->body);
|
||||
@ -533,6 +521,7 @@ static void vmw_stdu_bo_fifo_commit(struct vmw_kms_dirty *dirty)
|
||||
|
||||
vmw_fifo_commit(dirty->dev_priv, sizeof(*cmd) + blit_size);
|
||||
|
||||
stdu->display_srf->res.res_dirty = true;
|
||||
ddirty->left = ddirty->top = S32_MAX;
|
||||
ddirty->right = ddirty->bottom = S32_MIN;
|
||||
}
|
||||
@ -629,20 +618,16 @@ static void vmw_stdu_bo_cpu_commit(struct vmw_kms_dirty *dirty)
|
||||
region.x2 = diff.rect.x2;
|
||||
region.y1 = diff.rect.y1;
|
||||
region.y2 = diff.rect.y2;
|
||||
ret = vmw_kms_update_proxy(
|
||||
(struct vmw_resource *) &stdu->display_srf->res,
|
||||
(const struct drm_clip_rect *) ®ion, 1, 1);
|
||||
ret = vmw_kms_update_proxy(&stdu->display_srf->res, ®ion,
|
||||
1, 1);
|
||||
if (ret)
|
||||
goto out_cleanup;
|
||||
|
||||
|
||||
dev_priv = vmw_priv(stdu->base.crtc.dev);
|
||||
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
|
||||
|
||||
if (!cmd) {
|
||||
DRM_ERROR("Cannot reserve FIFO space to update STDU");
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
|
||||
if (!cmd)
|
||||
goto out_cleanup;
|
||||
}
|
||||
|
||||
vmw_stdu_populate_update(cmd, stdu->base.unit,
|
||||
region.x1, region.x2,
|
||||
@ -820,6 +805,7 @@ static void vmw_kms_stdu_surface_fifo_commit(struct vmw_kms_dirty *dirty)
|
||||
cmd->body.dest.sid = stdu->display_srf->res.id;
|
||||
update = (struct vmw_stdu_update *) &blit[dirty->num_hits];
|
||||
commit_size = sizeof(*cmd) + blit_size + sizeof(*update);
|
||||
stdu->display_srf->res.res_dirty = true;
|
||||
} else {
|
||||
update = dirty->cmd;
|
||||
commit_size = sizeof(*update);
|
||||
@ -876,7 +862,8 @@ int vmw_kms_stdu_surface_dirty(struct vmw_private *dev_priv,
|
||||
if (!srf)
|
||||
srf = &vfbs->surface->res;
|
||||
|
||||
ret = vmw_validation_add_resource(&val_ctx, srf, 0, NULL, NULL);
|
||||
ret = vmw_validation_add_resource(&val_ctx, srf, 0, VMW_RES_DIRTY_NONE,
|
||||
NULL, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -342,12 +342,9 @@ static void vmw_hw_surface_destroy(struct vmw_resource *res)
|
||||
|
||||
if (res->id != -1) {
|
||||
|
||||
cmd = vmw_fifo_reserve(dev_priv, vmw_surface_destroy_size());
|
||||
if (unlikely(!cmd)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for surface "
|
||||
"destruction.\n");
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, vmw_surface_destroy_size());
|
||||
if (unlikely(!cmd))
|
||||
return;
|
||||
}
|
||||
|
||||
vmw_surface_destroy_encode(res->id, cmd);
|
||||
vmw_fifo_commit(dev_priv, vmw_surface_destroy_size());
|
||||
@ -414,10 +411,8 @@ static int vmw_legacy_srf_create(struct vmw_resource *res)
|
||||
*/
|
||||
|
||||
submit_size = vmw_surface_define_size(srf);
|
||||
cmd = vmw_fifo_reserve(dev_priv, submit_size);
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, submit_size);
|
||||
if (unlikely(!cmd)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for surface "
|
||||
"creation.\n");
|
||||
ret = -ENOMEM;
|
||||
goto out_no_fifo;
|
||||
}
|
||||
@ -468,12 +463,10 @@ static int vmw_legacy_srf_dma(struct vmw_resource *res,
|
||||
|
||||
BUG_ON(!val_buf->bo);
|
||||
submit_size = vmw_surface_dma_size(srf);
|
||||
cmd = vmw_fifo_reserve(dev_priv, submit_size);
|
||||
if (unlikely(!cmd)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for surface "
|
||||
"DMA.\n");
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, submit_size);
|
||||
if (unlikely(!cmd))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
vmw_bo_get_guest_ptr(val_buf->bo, &ptr);
|
||||
vmw_surface_dma_encode(srf, cmd, &ptr, bind);
|
||||
|
||||
@ -556,12 +549,9 @@ static int vmw_legacy_srf_destroy(struct vmw_resource *res)
|
||||
*/
|
||||
|
||||
submit_size = vmw_surface_destroy_size();
|
||||
cmd = vmw_fifo_reserve(dev_priv, submit_size);
|
||||
if (unlikely(!cmd)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for surface "
|
||||
"eviction.\n");
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, submit_size);
|
||||
if (unlikely(!cmd))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
vmw_surface_destroy_encode(res->id, cmd);
|
||||
vmw_fifo_commit(dev_priv, submit_size);
|
||||
@ -748,11 +738,10 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
|
||||
ttm_round_pot(num_sizes * sizeof(struct drm_vmw_size)) +
|
||||
ttm_round_pot(num_sizes * sizeof(struct vmw_surface_offset));
|
||||
|
||||
|
||||
desc = svga3dsurface_get_desc(req->format);
|
||||
if (unlikely(desc->block_desc == SVGA3DBLOCKDESC_NONE)) {
|
||||
DRM_ERROR("Invalid surface format for surface creation.\n");
|
||||
DRM_ERROR("Format requested is: %d\n", req->format);
|
||||
VMW_DEBUG_USER("Invalid format %d for surface creation.\n",
|
||||
req->format);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -764,8 +753,7 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data,
|
||||
size, &ctx);
|
||||
if (unlikely(ret != 0)) {
|
||||
if (ret != -ERESTARTSYS)
|
||||
DRM_ERROR("Out of graphics memory for surface"
|
||||
" creation.\n");
|
||||
DRM_ERROR("Out of graphics memory for surface.\n");
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
@ -939,12 +927,12 @@ vmw_surface_handle_reference(struct vmw_private *dev_priv,
|
||||
ret = -EINVAL;
|
||||
base = ttm_base_object_lookup_for_ref(dev_priv->tdev, handle);
|
||||
if (unlikely(!base)) {
|
||||
DRM_ERROR("Could not find surface to reference.\n");
|
||||
VMW_DEBUG_USER("Could not find surface to reference.\n");
|
||||
goto out_no_lookup;
|
||||
}
|
||||
|
||||
if (unlikely(ttm_base_object_type(base) != VMW_RES_SURFACE)) {
|
||||
DRM_ERROR("Referenced object is not a surface.\n");
|
||||
VMW_DEBUG_USER("Referenced object is not a surface.\n");
|
||||
goto out_bad_resource;
|
||||
}
|
||||
|
||||
@ -1022,8 +1010,8 @@ int vmw_surface_reference_ioctl(struct drm_device *dev, void *data,
|
||||
ret = copy_to_user(user_sizes, &srf->base_size,
|
||||
sizeof(srf->base_size));
|
||||
if (unlikely(ret != 0)) {
|
||||
DRM_ERROR("copy_to_user failed %p %u\n",
|
||||
user_sizes, srf->num_sizes);
|
||||
VMW_DEBUG_USER("copy_to_user failed %p %u\n", user_sizes,
|
||||
srf->num_sizes);
|
||||
ttm_ref_object_base_unref(tfile, base->handle, TTM_REF_USAGE);
|
||||
ret = -EFAULT;
|
||||
}
|
||||
@ -1088,12 +1076,10 @@ static int vmw_gb_surface_create(struct vmw_resource *res)
|
||||
submit_len = sizeof(*cmd);
|
||||
}
|
||||
|
||||
cmd = vmw_fifo_reserve(dev_priv, submit_len);
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, submit_len);
|
||||
cmd2 = (typeof(cmd2))cmd;
|
||||
cmd3 = (typeof(cmd3))cmd;
|
||||
if (unlikely(!cmd)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for surface "
|
||||
"creation.\n");
|
||||
ret = -ENOMEM;
|
||||
goto out_no_fifo;
|
||||
}
|
||||
@ -1171,12 +1157,9 @@ static int vmw_gb_surface_bind(struct vmw_resource *res,
|
||||
|
||||
submit_size = sizeof(*cmd1) + (res->backup_dirty ? sizeof(*cmd2) : 0);
|
||||
|
||||
cmd1 = vmw_fifo_reserve(dev_priv, submit_size);
|
||||
if (unlikely(!cmd1)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for surface "
|
||||
"binding.\n");
|
||||
cmd1 = VMW_FIFO_RESERVE(dev_priv, submit_size);
|
||||
if (unlikely(!cmd1))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
cmd1->header.id = SVGA_3D_CMD_BIND_GB_SURFACE;
|
||||
cmd1->header.size = sizeof(cmd1->body);
|
||||
@ -1221,12 +1204,9 @@ static int vmw_gb_surface_unbind(struct vmw_resource *res,
|
||||
BUG_ON(bo->mem.mem_type != VMW_PL_MOB);
|
||||
|
||||
submit_size = sizeof(*cmd3) + (readback ? sizeof(*cmd1) : sizeof(*cmd2));
|
||||
cmd = vmw_fifo_reserve(dev_priv, submit_size);
|
||||
if (unlikely(!cmd)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for surface "
|
||||
"unbinding.\n");
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, submit_size);
|
||||
if (unlikely(!cmd))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (readback) {
|
||||
cmd1 = (void *) cmd;
|
||||
@ -1280,10 +1260,8 @@ static int vmw_gb_surface_destroy(struct vmw_resource *res)
|
||||
vmw_view_surface_list_destroy(dev_priv, &srf->view_list);
|
||||
vmw_binding_res_list_scrub(&res->binding_head);
|
||||
|
||||
cmd = vmw_fifo_reserve(dev_priv, sizeof(*cmd));
|
||||
cmd = VMW_FIFO_RESERVE(dev_priv, sizeof(*cmd));
|
||||
if (unlikely(!cmd)) {
|
||||
DRM_ERROR("Failed reserving FIFO space for surface "
|
||||
"destruction.\n");
|
||||
mutex_unlock(&dev_priv->binding_mutex);
|
||||
return -ENOMEM;
|
||||
}
|
||||
@ -1405,16 +1383,16 @@ int vmw_surface_gb_priv_define(struct drm_device *dev,
|
||||
|
||||
if (for_scanout) {
|
||||
if (!svga3dsurface_is_screen_target_format(format)) {
|
||||
DRM_ERROR("Invalid Screen Target surface format.");
|
||||
VMW_DEBUG_USER("Invalid Screen Target surface format.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (size.width > dev_priv->texture_max_width ||
|
||||
size.height > dev_priv->texture_max_height) {
|
||||
DRM_ERROR("%ux%u\n, exceeds max surface size %ux%u",
|
||||
size.width, size.height,
|
||||
dev_priv->texture_max_width,
|
||||
dev_priv->texture_max_height);
|
||||
VMW_DEBUG_USER("%ux%u\n, exceeds max surface size %ux%u",
|
||||
size.width, size.height,
|
||||
dev_priv->texture_max_width,
|
||||
dev_priv->texture_max_height);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
@ -1422,14 +1400,14 @@ int vmw_surface_gb_priv_define(struct drm_device *dev,
|
||||
|
||||
desc = svga3dsurface_get_desc(format);
|
||||
if (unlikely(desc->block_desc == SVGA3DBLOCKDESC_NONE)) {
|
||||
DRM_ERROR("Invalid surface format.\n");
|
||||
VMW_DEBUG_USER("Invalid surface format.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* array_size must be null for non-GL3 host. */
|
||||
if (array_size > 0 && !dev_priv->has_dx) {
|
||||
DRM_ERROR("Tried to create DX surface on non-DX host.\n");
|
||||
VMW_DEBUG_USER("Tried to create DX surface on non-DX host.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -1651,7 +1629,7 @@ vmw_gb_surface_define_internal(struct drm_device *dev,
|
||||
if (ret == 0) {
|
||||
if (res->backup->base.num_pages * PAGE_SIZE <
|
||||
res->backup_size) {
|
||||
DRM_ERROR("Surface backup buffer too small.\n");
|
||||
VMW_DEBUG_USER("Surface backup buffer too small.\n");
|
||||
vmw_bo_unreference(&res->backup);
|
||||
ret = -EINVAL;
|
||||
goto out_unlock;
|
||||
|
@ -76,6 +76,8 @@ struct vmw_validation_res_node {
|
||||
u32 switching_backup : 1;
|
||||
u32 first_usage : 1;
|
||||
u32 reserved : 1;
|
||||
u32 dirty : 1;
|
||||
u32 dirty_set : 1;
|
||||
unsigned long private[0];
|
||||
};
|
||||
|
||||
@ -299,6 +301,7 @@ int vmw_validation_add_bo(struct vmw_validation_context *ctx,
|
||||
* @ctx: The validation context.
|
||||
* @res: The resource.
|
||||
* @priv_size: Size of private, additional metadata.
|
||||
* @dirty: Whether to change dirty status.
|
||||
* @p_node: Output pointer of additional metadata address.
|
||||
* @first_usage: Whether this was the first time this resource was seen.
|
||||
*
|
||||
@ -307,6 +310,7 @@ int vmw_validation_add_bo(struct vmw_validation_context *ctx,
|
||||
int vmw_validation_add_resource(struct vmw_validation_context *ctx,
|
||||
struct vmw_resource *res,
|
||||
size_t priv_size,
|
||||
u32 dirty,
|
||||
void **p_node,
|
||||
bool *first_usage)
|
||||
{
|
||||
@ -321,8 +325,7 @@ int vmw_validation_add_resource(struct vmw_validation_context *ctx,
|
||||
|
||||
node = vmw_validation_mem_alloc(ctx, sizeof(*node) + priv_size);
|
||||
if (!node) {
|
||||
DRM_ERROR("Failed to allocate a resource validation "
|
||||
"entry.\n");
|
||||
VMW_DEBUG_USER("Failed to allocate a resource validation entry.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@ -358,6 +361,11 @@ int vmw_validation_add_resource(struct vmw_validation_context *ctx,
|
||||
}
|
||||
|
||||
out_fill:
|
||||
if (dirty) {
|
||||
node->dirty_set = 1;
|
||||
/* Overwriting previous information here is intentional! */
|
||||
node->dirty = (dirty & VMW_RES_DIRTY_SET) ? 1 : 0;
|
||||
}
|
||||
if (first_usage)
|
||||
*first_usage = node->first_usage;
|
||||
if (p_node)
|
||||
@ -366,6 +374,29 @@ out_fill:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* vmw_validation_res_set_dirty - Register a resource dirty set or clear during
|
||||
* validation.
|
||||
* @ctx: The validation context.
|
||||
* @val_private: The additional meta-data pointer returned when the
|
||||
* resource was registered with the validation context. Used to identify
|
||||
* the resource.
|
||||
* @dirty: Dirty information VMW_RES_DIRTY_XX
|
||||
*/
|
||||
void vmw_validation_res_set_dirty(struct vmw_validation_context *ctx,
|
||||
void *val_private, u32 dirty)
|
||||
{
|
||||
struct vmw_validation_res_node *val;
|
||||
|
||||
if (!dirty)
|
||||
return;
|
||||
|
||||
val = container_of(val_private, typeof(*val), private);
|
||||
val->dirty_set = 1;
|
||||
/* Overwriting previous information here is intentional! */
|
||||
val->dirty = (dirty & VMW_RES_DIRTY_SET) ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* vmw_validation_res_switch_backup - Register a backup MOB switch during
|
||||
* validation.
|
||||
@ -450,15 +481,23 @@ void vmw_validation_res_unreserve(struct vmw_validation_context *ctx,
|
||||
struct vmw_validation_res_node *val;
|
||||
|
||||
list_splice_init(&ctx->resource_ctx_list, &ctx->resource_list);
|
||||
|
||||
list_for_each_entry(val, &ctx->resource_list, head) {
|
||||
if (val->reserved)
|
||||
vmw_resource_unreserve(val->res,
|
||||
!backoff &&
|
||||
val->switching_backup,
|
||||
val->new_backup,
|
||||
val->new_backup_offset);
|
||||
}
|
||||
if (backoff)
|
||||
list_for_each_entry(val, &ctx->resource_list, head) {
|
||||
if (val->reserved)
|
||||
vmw_resource_unreserve(val->res,
|
||||
false, false, false,
|
||||
NULL, 0);
|
||||
}
|
||||
else
|
||||
list_for_each_entry(val, &ctx->resource_list, head) {
|
||||
if (val->reserved)
|
||||
vmw_resource_unreserve(val->res,
|
||||
val->dirty_set,
|
||||
val->dirty,
|
||||
val->switching_backup,
|
||||
val->new_backup,
|
||||
val->new_backup_offset);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -33,6 +33,10 @@
|
||||
#include <linux/ww_mutex.h>
|
||||
#include <drm/ttm/ttm_execbuf_util.h>
|
||||
|
||||
#define VMW_RES_DIRTY_NONE 0
|
||||
#define VMW_RES_DIRTY_SET BIT(0)
|
||||
#define VMW_RES_DIRTY_CLEAR BIT(1)
|
||||
|
||||
/**
|
||||
* struct vmw_validation_mem - Custom interface to provide memory reservations
|
||||
* for the validation code.
|
||||
@ -237,6 +241,7 @@ void vmw_validation_unref_lists(struct vmw_validation_context *ctx);
|
||||
int vmw_validation_add_resource(struct vmw_validation_context *ctx,
|
||||
struct vmw_resource *res,
|
||||
size_t priv_size,
|
||||
u32 dirty,
|
||||
void **p_node,
|
||||
bool *first_usage);
|
||||
void vmw_validation_drop_ht(struct vmw_validation_context *ctx);
|
||||
@ -261,4 +266,6 @@ void *vmw_validation_mem_alloc(struct vmw_validation_context *ctx,
|
||||
int vmw_validation_preload_bo(struct vmw_validation_context *ctx);
|
||||
int vmw_validation_preload_res(struct vmw_validation_context *ctx,
|
||||
unsigned int size);
|
||||
void vmw_validation_res_set_dirty(struct vmw_validation_context *ctx,
|
||||
void *val_private, u32 dirty);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user