@@ -267,6 +267,7 @@ struct vmw_surface {
struct vmw_cmdbuf_surface {
struct vmw_surface surface;
struct ttm_base_object base;
+ bool cmdbuf_destroy;
};
struct vmw_fifo_state {
@@ -3374,6 +3374,8 @@ static int vmw_cmd_destroy_gb_surface(struct vmw_private *dev_priv,
SVGA3dCmdHeader *header)
{
VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDestroyGBSurface);
+ struct vmw_resource *res;
+ struct vmw_cmdbuf_surface *surface;
int ret;
cmd = container_of(header, typeof(*cmd), header);
@@ -3382,10 +3384,13 @@ static int vmw_cmd_destroy_gb_surface(struct vmw_private *dev_priv,
return -EINVAL;
ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
- VMW_RES_DIRTY_NONE, NULL, &cmd->body.sid, NULL);
+ VMW_RES_DIRTY_NONE, NULL, &cmd->body.sid, &res);
if (unlikely(ret))
return ret;
+ surface = vmw_res_to_cmdbuf_srf(res);
+ surface->cmdbuf_destroy = true;
+
ret = vmw_cmdbuf_surface_destroy(dev_priv, sw_context, cmd->body.sid);
if (unlikely(ret))
return ret;
@@ -2403,6 +2403,43 @@ static void vmw_cmdbuf_surface_base_release(struct ttm_base_object **p_base)
}
+static void vmw_cmdbuf_surface_hw_destroy(struct vmw_resource *res)
+{
+ struct vmw_private *dev_priv = res->dev_priv;
+ struct vmw_cmdbuf_surface *surface;
+ struct {
+ SVGA3dCmdHeader header;
+ SVGA3dCmdDestroyGBSurface body;
+ } *cmd;
+
+ if (res->id == -1)
+ return;
+
+ surface = vmw_res_to_cmdbuf_srf(res);
+ /**
+ * If userspace is submitting a destroy command there is no need for
+ * kernel to do so.
+ */
+ if (surface->cmdbuf_destroy)
+ return;
+
+ mutex_lock(&dev_priv->binding_mutex);
+ vmw_view_surface_list_destroy(dev_priv, &surface->surface.view_list);
+
+ cmd = VMW_CMD_RESERVE(dev_priv, sizeof(*cmd));
+ if (unlikely(!cmd)) {
+ mutex_unlock(&dev_priv->binding_mutex);
+ return;
+ }
+
+ cmd->header.id = SVGA_3D_CMD_DESTROY_GB_SURFACE;
+ cmd->header.size = sizeof(cmd->body);
+ cmd->body.sid = res->id;
+ vmw_cmd_commit(dev_priv, sizeof(*cmd));
+ mutex_unlock(&dev_priv->binding_mutex);
+}
+
+
int vmw_cmdbuf_surface_define(struct vmw_private *dev_priv,
struct vmw_sw_context *sw_context,
struct vmw_surface_metadata *metadata,
@@ -2484,6 +2521,9 @@ int vmw_cmdbuf_surface_define(struct vmw_private *dev_priv,
return ret;
}
+ res->hw_destroy = vmw_cmdbuf_surface_hw_destroy;
+ surface->cmdbuf_destroy = false;
+
return 0;
}
A userspace may create a userspace managed surface but not destroy it, add hw_destroy function for userspace surfaces so that vmwgfx records the destroy command and submits it when the userspace context is destroyed. Signed-off-by: Maaz Mombasawala <maaz.mombasawala@broadcom.com> --- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 1 + drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 7 ++++- drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 40 +++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-)