All of lore.kernel.org
 help / color / mirror / Atom feed
From: Thomas Hellstrom <thellstrom@vmware.com>
To: dri-devel@lists.freedesktop.org
Subject: [PATCH 09/28] drm/vmwgfx: Refactor vmw_gb_surface_define_ioctl()
Date: Wed, 12 Aug 2015 22:42:58 -0700	[thread overview]
Message-ID: <1439444597-4664-10-git-send-email-thellstrom@vmware.com> (raw)
In-Reply-To: <1439444597-4664-1-git-send-email-thellstrom@vmware.com>

From: Sinclair Yeh <syeh@vmware.com>

Refactored vmw_gb_surface_define_ioctl() and made the surface
definition part a separate function.  This way other parts of vmwgfx
can use it to allocate kernel-visible GB surfaces.

Signed-off-by: Sinclair Yeh <syeh@vmware.com>
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
---
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.h     |   9 ++
 drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 195 ++++++++++++++++++++++----------
 2 files changed, 143 insertions(+), 61 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
index 338dce3..c300a0a 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
@@ -1043,6 +1043,15 @@ extern int vmw_surface_check(struct vmw_private *dev_priv,
 			     uint32_t handle, int *id);
 extern int vmw_surface_validate(struct vmw_private *dev_priv,
 				struct vmw_surface *srf);
+int vmw_surface_gb_priv_define(struct drm_device *dev,
+			       uint32_t user_accounting_size,
+			       uint32_t svga3d_flags,
+			       SVGA3dSurfaceFormat format,
+			       bool for_scanout,
+			       uint32_t num_mip_levels,
+			       uint32_t multisample_count,
+			       struct drm_vmw_size size,
+			       struct vmw_surface **srf_out);
 
 /*
  * Shader management - vmwgfx_shader.c
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
index 4d0c98e..fb54ccd 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
@@ -1,6 +1,6 @@
 /**************************************************************************
  *
- * Copyright © 2009-2012 VMware, Inc., Palo Alto, CA., USA
+ * Copyright © 2009-2014 VMware, Inc., Palo Alto, CA., USA
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -36,7 +36,7 @@
  * @base:           The TTM base object handling user-space visibility.
  * @srf:            The surface metadata.
  * @size:           TTM accounting size for the surface.
- * @master:         master of the creating client. Used for security check.
+ * @master: master of the creating client. Used for security check.
  */
 struct vmw_user_surface {
 	struct ttm_prime_object prime;
@@ -1218,6 +1218,7 @@ static int vmw_gb_surface_destroy(struct vmw_resource *res)
 	return 0;
 }
 
+
 /**
  * vmw_gb_surface_define_ioctl - Ioctl function implementing
  *                               the user surface define functionality.
@@ -1241,77 +1242,43 @@ int vmw_gb_surface_define_ioctl(struct drm_device *dev, void *data,
 	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
 	int ret;
 	uint32_t size;
-	const struct svga3d_surface_desc *desc;
 	uint32_t backup_handle;
 
+
 	if (unlikely(vmw_user_surface_size == 0))
 		vmw_user_surface_size = ttm_round_pot(sizeof(*user_srf)) +
 			128;
 
 	size = vmw_user_surface_size + 128;
 
-	desc = svga3dsurface_get_desc(req->format);
-	if (unlikely(desc->block_desc == SVGA3DBLOCKDESC_NONE)) {
-		DRM_ERROR("Invalid surface format for surface creation.\n");
-		return -EINVAL;
-	}
-
-	ret = ttm_read_lock(&dev_priv->reservation_sem, true);
+	/* Define a surface based on the parameters. */
+	ret = vmw_surface_gb_priv_define(dev,
+			size,
+			req->svga3d_flags,
+			req->format,
+			req->drm_surface_flags & drm_vmw_surface_flag_scanout,
+			req->mip_levels,
+			req->multisample_count,
+			req->base_size,
+			&srf);
 	if (unlikely(ret != 0))
 		return ret;
 
-	ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv),
-				   size, false, true);
-	if (unlikely(ret != 0)) {
-		if (ret != -ERESTARTSYS)
-			DRM_ERROR("Out of graphics memory for surface"
-				  " creation.\n");
-		goto out_unlock;
-	}
-
-	user_srf = kzalloc(sizeof(*user_srf), GFP_KERNEL);
-	if (unlikely(user_srf == NULL)) {
-		ret = -ENOMEM;
-		goto out_no_user_srf;
-	}
-
-	srf = &user_srf->srf;
-	res = &srf->res;
-
-	srf->flags = req->svga3d_flags;
-	srf->format = req->format;
-	srf->scanout = req->drm_surface_flags & drm_vmw_surface_flag_scanout;
-	srf->mip_levels[0] = req->mip_levels;
-	srf->num_sizes = 1;
-	srf->sizes = NULL;
-	srf->offsets = NULL;
-	user_srf->size = size;
-	srf->base_size = req->base_size;
-	srf->autogen_filter = SVGA3D_TEX_FILTER_NONE;
-	srf->multisample_count = req->multisample_count;
-	res->backup_size = svga3dsurface_get_serialized_size
-	  (srf->format, srf->base_size, srf->mip_levels[0],
-	   srf->flags & SVGA3D_SURFACE_CUBEMAP);
-
-	user_srf->prime.base.shareable = false;
-	user_srf->prime.base.tfile = NULL;
+	user_srf = container_of(srf, struct vmw_user_surface, srf);
 	if (drm_is_primary_client(file_priv))
 		user_srf->master = drm_master_get(file_priv->master);
 
-	/**
-	 * From this point, the generic resource management functions
-	 * destroy the object on failure.
-	 */
-
-	ret = vmw_surface_init(dev_priv, srf, vmw_user_surface_free);
+	ret = ttm_read_lock(&dev_priv->reservation_sem, true);
 	if (unlikely(ret != 0))
-		goto out_unlock;
+		return ret;
+
+	res = &user_srf->srf.res;
 
-	if (req->buffer_handle != SVGA3D_INVALID_ID) {
+
+	if (req->buffer_handle != SVGA3D_INVALID_ID)
 		ret = vmw_user_dmabuf_lookup(tfile, req->buffer_handle,
 					     &res->backup);
-	} else if (req->drm_surface_flags &
-		   drm_vmw_surface_flag_create_buffer)
+	else if (req->drm_surface_flags & drm_vmw_surface_flag_create_buffer)
 		ret = vmw_user_dmabuf_alloc(dev_priv, tfile,
 					    res->backup_size,
 					    req->drm_surface_flags &
@@ -1324,7 +1291,7 @@ int vmw_gb_surface_define_ioctl(struct drm_device *dev, void *data,
 		goto out_unlock;
 	}
 
-	tmp = vmw_resource_reference(&srf->res);
+	tmp = vmw_resource_reference(res);
 	ret = ttm_prime_object_init(tfile, res->backup_size, &user_srf->prime,
 				    req->drm_surface_flags &
 				    drm_vmw_surface_flag_shareable,
@@ -1337,7 +1304,7 @@ int vmw_gb_surface_define_ioctl(struct drm_device *dev, void *data,
 		goto out_unlock;
 	}
 
-	rep->handle = user_srf->prime.base.hash.key;
+	rep->handle      = user_srf->prime.base.hash.key;
 	rep->backup_size = res->backup_size;
 	if (res->backup) {
 		rep->buffer_map_handle =
@@ -1352,10 +1319,6 @@ int vmw_gb_surface_define_ioctl(struct drm_device *dev, void *data,
 
 	vmw_resource_unreference(&res);
 
-	ttm_read_unlock(&dev_priv->reservation_sem);
-	return 0;
-out_no_user_srf:
-	ttm_mem_global_free(vmw_mem_glob(dev_priv), size);
 out_unlock:
 	ttm_read_unlock(&dev_priv->reservation_sem);
 	return ret;
@@ -1429,3 +1392,113 @@ out_bad_resource:
 
 	return ret;
 }
+
+/**
+ * vmw_surface_gb_priv_define - Define a private GB surface
+ *
+ * @dev:  Pointer to a struct drm_device
+ * @user_accounting_size:  Used to track user-space memory usage, set
+ *                         to 0 for kernel mode only memory
+ * @svga3d_flags: SVGA3d surface flags for the device
+ * @format: requested surface format
+ * @for_scanout: true if inteded to be used for scanout buffer
+ * @num_mip_levels:  number of MIP levels
+ * @multisample_count:
+ * @size: width, heigh, depth of the surface requested
+ * @user_srf_out: allocated user_srf.  Set to NULL on failure.
+ *
+ * GB surfaces allocated by this function will not have a user mode handle, and
+ * thus will only be visible to vmwgfx.  For optimization reasons the
+ * surface may later be given a user mode handle by another function to make
+ * it available to user mode drivers.
+ */
+int vmw_surface_gb_priv_define(struct drm_device *dev,
+			       uint32_t user_accounting_size,
+			       uint32_t svga3d_flags,
+			       SVGA3dSurfaceFormat format,
+			       bool for_scanout,
+			       uint32_t num_mip_levels,
+			       uint32_t multisample_count,
+			       struct drm_vmw_size size,
+			       struct vmw_surface **srf_out)
+{
+	struct vmw_private *dev_priv = vmw_priv(dev);
+	struct vmw_user_surface *user_srf;
+	struct vmw_surface *srf;
+	int ret;
+
+
+	*srf_out = NULL;
+
+	if (for_scanout) {
+		if (!svga3dsurface_is_screen_target_format(format)) {
+			DRM_ERROR("Invalid Screen Target surface format.");
+			return -EINVAL;
+		}
+	} else {
+		const struct svga3d_surface_desc *desc;
+
+		desc = svga3dsurface_get_desc(format);
+		if (unlikely(desc->block_desc == SVGA3DBLOCKDESC_NONE)) {
+			DRM_ERROR("Invalid surface format.\n");
+			return -EINVAL;
+		}
+	}
+
+	ret = ttm_read_lock(&dev_priv->reservation_sem, true);
+	if (unlikely(ret != 0))
+		return ret;
+
+	ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv),
+				   user_accounting_size, false, true);
+	if (unlikely(ret != 0)) {
+		if (ret != -ERESTARTSYS)
+			DRM_ERROR("Out of graphics memory for surface"
+				  " creation.\n");
+		goto out_unlock;
+	}
+
+	user_srf = kzalloc(sizeof(*user_srf), GFP_KERNEL);
+	if (unlikely(user_srf == NULL)) {
+		ret = -ENOMEM;
+		goto out_no_user_srf;
+	}
+
+	*srf_out  = &user_srf->srf;
+	user_srf->size = user_accounting_size;
+	user_srf->prime.base.shareable = false;
+	user_srf->prime.base.tfile     = NULL;
+
+	srf = &user_srf->srf;
+	srf->flags             = svga3d_flags;
+	srf->format            = format;
+	srf->scanout           = for_scanout;
+	srf->mip_levels[0]     = num_mip_levels;
+	srf->num_sizes         = 1;
+	srf->sizes             = NULL;
+	srf->offsets           = NULL;
+	srf->base_size         = size;
+	srf->autogen_filter    = SVGA3D_TEX_FILTER_NONE;
+	srf->multisample_count = multisample_count;
+
+	srf->res.backup_size   = svga3dsurface_get_serialized_size(srf->format,
+					srf->base_size,
+					srf->mip_levels[0],
+					srf->flags & SVGA3D_SURFACE_CUBEMAP);
+
+	/*
+	 * From this point, the generic resource management functions
+	 * destroy the object on failure.
+	 */
+	ret = vmw_surface_init(dev_priv, srf, vmw_user_surface_free);
+
+	ttm_read_unlock(&dev_priv->reservation_sem);
+	return ret;
+
+out_no_user_srf:
+	ttm_mem_global_free(vmw_mem_glob(dev_priv), user_accounting_size);
+
+out_unlock:
+	ttm_read_unlock(&dev_priv->reservation_sem);
+	return ret;
+}
-- 
2.1.0


_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

  parent reply	other threads:[~2015-08-13  6:03 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-08-13  5:42 [PATCH 00/28] vmwgfx preparation for GL3 Thomas Hellstrom
2015-08-13  5:42 ` [PATCH 01/28] drm/vmwgfx: Fix an fb unlocking bug Thomas Hellstrom
2015-08-13  5:42 ` [PATCH 02/28] vmwgfx: Rework device initialization Thomas Hellstrom
2015-08-13  5:42 ` [PATCH 03/28] drm/vmwgfx: Fix OTABLE takedown Thomas Hellstrom
2015-08-13  5:42 ` [PATCH 04/28] vmwgfx: Update device headers for command buffers Thomas Hellstrom
2015-08-13  5:42 ` [PATCH 05/28] drm/vmwgfx: Add command buffer support v3 Thomas Hellstrom
2015-08-13  5:42 ` [PATCH 06/28] drm/vmwgfx: Fix an overlay lockdep error Thomas Hellstrom
2015-08-13  5:42 ` [PATCH 07/28] drm/vmwgfx: Add an interface to pin a resource v3 Thomas Hellstrom
2015-08-13  5:42 ` [PATCH 08/28] drm/vmwgfx: SVGA device definition update Thomas Hellstrom
2015-08-13  5:42 ` Thomas Hellstrom [this message]
2015-08-13  5:42 ` [PATCH 10/28] vmwgfx: Major KMS refactoring / cleanup in preparation of screen targets Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 11/28] drm/vmwgfx: Add "quirk" to handling command verification exceptions Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 12/28] drm/vmwgfx: Implement screen targets Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 13/28] drm/vmwgfx: Replace SurfaceDMA usage with SurfaceCopy in 2D VMs Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 14/28] drm/vmwgfx: Introduce a pin count to allow for recursive pinning v2 Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 15/28] drm/vmwgfx: Add kms helpers for dirty- and readback functions Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 16/28] drm/vmwgfx: Convert screen objects to the new helpers Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 17/28] drm/vmwgfx: Convert screen targets to new helpers v3 Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 18/28] drm/vmwgfx: Avoid cmdbuf alloc sleeping if !TASK_RUNNING Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 19/28] drm/vmwgfx: Add a kernel interface to create a framebuffer v2 Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 20/28] drm/vmwgfx: Implement fbdev on kms v2 Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 21/28] drm/vmwgfx: Reinstate the legacy display system dirty callback Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 22/28] drm/vmwgfx: Fix kms preferred mode sorting Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 23/28] drm/vmwgfx: Kill a bunch of sparse warnings Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 24/28] drm/vmwgfx: Fix compiler warning with 32-bit dma_addr_t Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 25/28] drm/vmwgfx: Fix an uninitialized value Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 26/28] drm/vmwgfx: Fixed topology boundary checking for Screen Targets Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 27/28] drm/vmwgfx: Fix framebuffer creation on older hardware Thomas Hellstrom
2015-08-13  5:43 ` [PATCH 28/28] drm/vmwgfx: Fix crash when unloading vmwgfx v2 Thomas Hellstrom

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1439444597-4664-10-git-send-email-thellstrom@vmware.com \
    --to=thellstrom@vmware.com \
    --cc=dri-devel@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.