All of lore.kernel.org
 help / color / mirror / Atom feed
* [0/9] Collection of patches queued up for vmwgfx-next
@ 2017-03-27 22:17 Sinclair Yeh
  2017-03-27 22:17 ` [PATCH 1/9] drm/vmwgfx: Explicityly track screen target width and height Sinclair Yeh
                   ` (8 more replies)
  0 siblings, 9 replies; 13+ messages in thread
From: Sinclair Yeh @ 2017-03-27 22:17 UTC (permalink / raw)
  To: dri-devel; +Cc: thellstrom

These are a collection of patches currently queued for vmwgfx-next

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

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 1/9] drm/vmwgfx: Explicityly track screen target width and height
  2017-03-27 22:17 [0/9] Collection of patches queued up for vmwgfx-next Sinclair Yeh
@ 2017-03-27 22:17 ` Sinclair Yeh
  2017-03-27 22:17 ` [PATCH 2/9] drm/vmwgfx: Skipping fbdev fb pinning for ldu Sinclair Yeh
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: Sinclair Yeh @ 2017-03-27 22:17 UTC (permalink / raw)
  To: dri-devel; +Cc: thellstrom

We can no longer make the assumption that vmw_stdu_update_st() will
be called when there's a valid display surface attached.  So
instead of using display_srf for width and height, make a record of
these paremeters when the screen target is first defined.

Signed-off-by: Sinclair Yeh <syeh@vmware.com>
Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
---
 drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
index ff00817..9e40138 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
@@ -106,6 +106,7 @@ struct vmw_screen_target_display_unit {
 	struct vmw_display_unit base;
 	const struct vmw_surface *display_srf;
 	enum stdu_content_type content_fb_type;
+	s32 display_width, display_height;
 
 	bool defined;
 };
@@ -184,6 +185,8 @@ static int vmw_stdu_define_st(struct vmw_private *dev_priv,
 	vmw_fifo_commit(dev_priv, sizeof(*cmd));
 
 	stdu->defined = true;
+	stdu->display_width  = mode->hdisplay;
+	stdu->display_height = mode->vdisplay;
 
 	return 0;
 }
@@ -281,7 +284,6 @@ static int vmw_stdu_update_st(struct vmw_private *dev_priv,
 			      struct vmw_screen_target_display_unit *stdu)
 {
 	struct vmw_stdu_update *cmd;
-	struct drm_crtc *crtc = &stdu->base.crtc;
 
 	if (!stdu->defined) {
 		DRM_ERROR("No screen target defined");
@@ -295,8 +297,9 @@ static int vmw_stdu_update_st(struct vmw_private *dev_priv,
 		return -ENOMEM;
 	}
 
-	vmw_stdu_populate_update(cmd, stdu->base.unit, 0, crtc->mode.hdisplay,
-				 0, crtc->mode.vdisplay);
+	vmw_stdu_populate_update(cmd, stdu->base.unit,
+				 0, stdu->display_width,
+				 0, stdu->display_height);
 
 	vmw_fifo_commit(dev_priv, sizeof(*cmd));
 
@@ -346,6 +349,8 @@ static int vmw_stdu_destroy_st(struct vmw_private *dev_priv,
 		DRM_ERROR("Failed to sync with HW");
 
 	stdu->defined = false;
+	stdu->display_width  = 0;
+	stdu->display_height = 0;
 
 	return ret;
 }
-- 
2.7.4

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

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 2/9] drm/vmwgfx: Skipping fbdev fb pinning for ldu
  2017-03-27 22:17 [0/9] Collection of patches queued up for vmwgfx-next Sinclair Yeh
  2017-03-27 22:17 ` [PATCH 1/9] drm/vmwgfx: Explicityly track screen target width and height Sinclair Yeh
@ 2017-03-27 22:17 ` Sinclair Yeh
  2017-03-27 22:17 ` [PATCH 3/9] drm/vmwgfx: Fix LDU X blank screen until mode change issue Sinclair Yeh
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: Sinclair Yeh @ 2017-03-27 22:17 UTC (permalink / raw)
  To: dri-devel; +Cc: thellstrom

Pinning fbdev's FB at the start of VRAM prevents X from pinning
its FB.  Since for ldu, the fb would be pinned anyway during a
mode set, just skip pinning it in fbdev.

This is not the best solution, but since ldu is not used much
anymore, it seems like a reasonable workaround.

Signed-off-by: Sinclair Yeh <syeh@vmware.com>
Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
---
 drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
index 7d3d5e3..09e120d 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
@@ -451,13 +451,15 @@ static int vmw_fb_kms_detach(struct vmw_fb_par *par,
 	}
 
 	if (par->vmw_bo && detach_bo) {
+		struct vmw_private *vmw_priv = par->vmw_priv;
+
 		if (par->bo_ptr) {
 			ttm_bo_kunmap(&par->map);
 			par->bo_ptr = NULL;
 		}
 		if (unref_bo)
 			vmw_dmabuf_unreference(&par->vmw_bo);
-		else
+		else if (vmw_priv->active_display_unit != vmw_du_legacy)
 			vmw_dmabuf_unpin(par->vmw_priv, par->vmw_bo, false);
 	}
 
@@ -585,18 +587,25 @@ static int vmw_fb_set_par(struct fb_info *info)
 
 		/*
 		 * Pin before mapping. Since we don't know in what placement
-		 * to pin, call into KMS to do it for us.
+		 * to pin, call into KMS to do it for us.  LDU doesn't require
+		 * additional pinning because set_config() would've pinned
+		 * it already
 		 */
-		ret = vfb->pin(vfb);
-		if (ret) {
-			DRM_ERROR("Could not pin the fbdev framebuffer.\n");
-			goto out_unlock;
+		if (vmw_priv->active_display_unit != vmw_du_legacy) {
+			ret = vfb->pin(vfb);
+			if (ret) {
+				DRM_ERROR("Could not pin the fbdev "
+					  "framebuffer.\n");
+				goto out_unlock;
+			}
 		}
 
 		ret = ttm_bo_kmap(&par->vmw_bo->base, 0,
 				  par->vmw_bo->base.num_pages, &par->map);
 		if (ret) {
-			vfb->unpin(vfb);
+			if (vmw_priv->active_display_unit != vmw_du_legacy)
+				vfb->unpin(vfb);
+
 			DRM_ERROR("Could not map the fbdev framebuffer.\n");
 			goto out_unlock;
 		}
-- 
2.7.4

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

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 3/9] drm/vmwgfx: Fix LDU X blank screen until mode change issue
  2017-03-27 22:17 [0/9] Collection of patches queued up for vmwgfx-next Sinclair Yeh
  2017-03-27 22:17 ` [PATCH 1/9] drm/vmwgfx: Explicityly track screen target width and height Sinclair Yeh
  2017-03-27 22:17 ` [PATCH 2/9] drm/vmwgfx: Skipping fbdev fb pinning for ldu Sinclair Yeh
@ 2017-03-27 22:17 ` Sinclair Yeh
  2017-03-27 22:17 ` [PATCH 4/9] drm/vmwgfx: Revert "drm/vmwgfx: Replace numeric parameter like 0444 with macro" Sinclair Yeh
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: Sinclair Yeh @ 2017-03-27 22:17 UTC (permalink / raw)
  To: dri-devel; +Cc: thellstrom

vmw_ldu_crtc_helper_commit() is not called if
drm_atomic_crtc_needs_modeset() decides nothing related to CRTC timing has
changed.

So a better place for this code is in vmw_ldu_primary_plane_atomic_update()
since we will need to update ld->fb every time the FB is updated.

Signed-off-by: Sinclair Yeh <syeh@vmware.com>
Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
---
 drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | 41 +++++++++++++++++++------------------
 1 file changed, 21 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
index 4954f26..fddb0a3 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
@@ -226,24 +226,6 @@ static void vmw_ldu_crtc_helper_prepare(struct drm_crtc *crtc)
  */
 static void vmw_ldu_crtc_helper_commit(struct drm_crtc *crtc)
 {
-	struct vmw_private *dev_priv;
-	struct vmw_legacy_display_unit *ldu;
-	struct vmw_framebuffer *vfb;
-	struct drm_framebuffer *fb;
-
-
-	ldu = vmw_crtc_to_ldu(crtc);
-	dev_priv = vmw_priv(crtc->dev);
-	fb       = crtc->primary->state->fb;
-
-	vfb = (fb) ? vmw_framebuffer_to_vfb(fb) : NULL;
-
-	if (vfb)
-		vmw_ldu_add_active(dev_priv, ldu, vfb);
-	else
-		vmw_ldu_del_active(dev_priv, ldu);
-
-	vmw_ldu_commit_list(dev_priv);
 }
 
 /**
@@ -310,7 +292,7 @@ drm_connector_helper_funcs vmw_ldu_connector_helper_funcs = {
  */
 
 /**
- * vmw_ldu_primary_plane_cleanup_fb - Unpin fb
+ * vmw_ldu_primary_plane_cleanup_fb - Noop
  *
  * @plane:  display plane
  * @old_state: Contains the FB to clean up
@@ -327,7 +309,7 @@ vmw_ldu_primary_plane_cleanup_fb(struct drm_plane *plane,
 
 
 /**
- * vmw_ldu_primary_plane_prepare_fb -
+ * vmw_ldu_primary_plane_prepare_fb - Noop
  *
  * @plane:  display plane
  * @new_state: info on the new plane state, including the FB
@@ -346,6 +328,25 @@ static void
 vmw_ldu_primary_plane_atomic_update(struct drm_plane *plane,
 				    struct drm_plane_state *old_state)
 {
+	struct vmw_private *dev_priv;
+	struct vmw_legacy_display_unit *ldu;
+	struct vmw_framebuffer *vfb;
+	struct drm_framebuffer *fb;
+	struct drm_crtc *crtc = plane->state->crtc ?: old_state->crtc;
+
+
+	ldu = vmw_crtc_to_ldu(crtc);
+	dev_priv = vmw_priv(plane->dev);
+	fb       = plane->state->fb;
+
+	vfb = (fb) ? vmw_framebuffer_to_vfb(fb) : NULL;
+
+	if (vfb)
+		vmw_ldu_add_active(dev_priv, ldu, vfb);
+	else
+		vmw_ldu_del_active(dev_priv, ldu);
+
+	vmw_ldu_commit_list(dev_priv);
 }
 
 
-- 
2.7.4

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

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 4/9] drm/vmwgfx: Revert "drm/vmwgfx: Replace numeric parameter like 0444 with macro"
  2017-03-27 22:17 [0/9] Collection of patches queued up for vmwgfx-next Sinclair Yeh
                   ` (2 preceding siblings ...)
  2017-03-27 22:17 ` [PATCH 3/9] drm/vmwgfx: Fix LDU X blank screen until mode change issue Sinclair Yeh
@ 2017-03-27 22:17 ` Sinclair Yeh
  2017-04-02  6:54   ` Øyvind A. Holm
  2017-03-27 22:17 ` [PATCH 5/9] drm/vmwgfx: Introduce a simple resource type Sinclair Yeh
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 13+ messages in thread
From: Sinclair Yeh @ 2017-03-27 22:17 UTC (permalink / raw)
  To: dri-devel; +Cc: Øyvind A. Holm, thellstrom

From: Øyvind A. Holm <sunny@sunbase.org>

This reverts commit 2d8e60e8b074 ("drm/vmwgfx: Replace numeric
parameter like 0444 with macro")

The commit belongs to the series of 1285 patches sent to LKML on
2016-08-02, it changes the representation of file permissions from the
octal value "0600" to "S_IRUSR | S_IWUSR".

The general consensus was that the changes does not increase
readability, quite the opposite; 0600 is easier to parse mentally than
S_IRUSR | S_IWUSR.

It also causes argument inconsistency, due to commit 04319d89fbec
("drm/vmwgfx: Add an option to change assumed FB bpp") that added
another call to module_param_named() where the permissions are written
as 0600.

Signed-off-by: Øyvind A. Holm <sunny@sunbase.org>
Reviewed-by: Sinclair Yeh <syeh@vmware.com>
---
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index 45d711e..d31dc34 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -241,13 +241,13 @@ static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val,
 			      void *ptr);
 
 MODULE_PARM_DESC(enable_fbdev, "Enable vmwgfx fbdev");
-module_param_named(enable_fbdev, enable_fbdev, int, S_IRUSR | S_IWUSR);
+module_param_named(enable_fbdev, enable_fbdev, int, 0600);
 MODULE_PARM_DESC(force_dma_api, "Force using the DMA API for TTM pages");
-module_param_named(force_dma_api, vmw_force_iommu, int, S_IRUSR | S_IWUSR);
+module_param_named(force_dma_api, vmw_force_iommu, int, 0600);
 MODULE_PARM_DESC(restrict_iommu, "Try to limit IOMMU usage for TTM pages");
-module_param_named(restrict_iommu, vmw_restrict_iommu, int, S_IRUSR | S_IWUSR);
+module_param_named(restrict_iommu, vmw_restrict_iommu, int, 0600);
 MODULE_PARM_DESC(force_coherent, "Force coherent TTM pages");
-module_param_named(force_coherent, vmw_force_coherent, int, S_IRUSR | S_IWUSR);
+module_param_named(force_coherent, vmw_force_coherent, int, 0600);
 MODULE_PARM_DESC(restrict_dma_mask, "Restrict DMA mask to 44 bits with IOMMU");
 module_param_named(restrict_dma_mask, vmw_restrict_dma_mask, int, S_IRUSR | S_IWUSR);
 MODULE_PARM_DESC(assume_16bpp, "Assume 16-bpp when filtering modes");
-- 
2.7.4

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

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 5/9] drm/vmwgfx: Introduce a simple resource type
  2017-03-27 22:17 [0/9] Collection of patches queued up for vmwgfx-next Sinclair Yeh
                   ` (3 preceding siblings ...)
  2017-03-27 22:17 ` [PATCH 4/9] drm/vmwgfx: Revert "drm/vmwgfx: Replace numeric parameter like 0444 with macro" Sinclair Yeh
@ 2017-03-27 22:17 ` Sinclair Yeh
  2017-03-27 22:17 ` [PATCH 6/9] drm/vmwgfx: Re-implement the stream resource as a simple resource Sinclair Yeh
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: Sinclair Yeh @ 2017-03-27 22:17 UTC (permalink / raw)
  To: dri-devel; +Cc: thellstrom

From: Thomas Hellstrom <thellstrom@vmware.com>

The callbacks we need to provide to many resources are very similar, so
provide a simple resource type with a number of helpers for these
callbacks.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Sinclair Yeh <syeh@vmware.com>
---
 drivers/gpu/drm/vmwgfx/Makefile                 |   3 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_resource_priv.h   |  40 ++++
 drivers/gpu/drm/vmwgfx/vmwgfx_simple_resource.c | 256 ++++++++++++++++++++++++
 3 files changed, 298 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/vmwgfx/vmwgfx_simple_resource.c

diff --git a/drivers/gpu/drm/vmwgfx/Makefile b/drivers/gpu/drm/vmwgfx/Makefile
index 473d004..2258908 100644
--- a/drivers/gpu/drm/vmwgfx/Makefile
+++ b/drivers/gpu/drm/vmwgfx/Makefile
@@ -8,6 +8,7 @@ vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_kms.o vmwgfx_drv.o \
 	    vmwgfx_fence.o vmwgfx_dmabuf.o vmwgfx_scrn.o vmwgfx_context.o \
 	    vmwgfx_surface.o vmwgfx_prime.o vmwgfx_mob.o vmwgfx_shader.o \
 	    vmwgfx_cmdbuf_res.o vmwgfx_cmdbuf.o vmwgfx_stdu.o \
-	    vmwgfx_cotable.o vmwgfx_so.o vmwgfx_binding.o vmwgfx_msg.o
+	    vmwgfx_cotable.o vmwgfx_so.o vmwgfx_binding.o vmwgfx_msg.o \
+	    vmwgfx_simple_resource.o
 
 obj-$(CONFIG_DRM_VMWGFX) := vmwgfx.o
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource_priv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_resource_priv.h
index 5994ef6..ac05968 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource_priv.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource_priv.h
@@ -30,6 +30,8 @@
 
 #include "vmwgfx_drv.h"
 
+#define VMW_IDA_ACC_SIZE 128
+
 enum vmw_cmdbuf_res_state {
 	VMW_CMDBUF_RES_COMMITTED,
 	VMW_CMDBUF_RES_ADD,
@@ -83,6 +85,35 @@ struct vmw_res_func {
 			      enum vmw_cmdbuf_res_state state);
 };
 
+/**
+ * struct vmw_simple_resource_func - members and functions common for the
+ * simple resource helpers.
+ * @res_func:  struct vmw_res_func as described above.
+ * @ttm_res_type:  TTM resource type used for handle recognition.
+ * @size:  Size of the simple resource information struct.
+ * @init:  Initialize the simple resource information.
+ * @hw_destroy:  A resource hw_destroy function.
+ * @set_arg_handle:  Set the handle output argument of the ioctl create struct.
+ */
+struct vmw_simple_resource_func {
+	const struct vmw_res_func res_func;
+	int ttm_res_type;
+	size_t size;
+	int (*init)(struct vmw_resource *res, void *data);
+	void (*hw_destroy)(struct vmw_resource *res);
+	void (*set_arg_handle)(void *data, u32 handle);
+};
+
+/**
+ * struct vmw_simple_resource - Kernel only side simple resource
+ * @res: The resource we derive from.
+ * @func: The method and member virtual table.
+ */
+struct vmw_simple_resource {
+	struct vmw_resource res;
+	const struct vmw_simple_resource_func *func;
+};
+
 int vmw_resource_alloc_id(struct vmw_resource *res);
 void vmw_resource_release_id(struct vmw_resource *res);
 int vmw_resource_init(struct vmw_private *dev_priv, struct vmw_resource *res,
@@ -91,4 +122,13 @@ int vmw_resource_init(struct vmw_private *dev_priv, struct vmw_resource *res,
 		      const struct vmw_res_func *func);
 void vmw_resource_activate(struct vmw_resource *res,
 			   void (*hw_destroy) (struct vmw_resource *));
+int
+vmw_simple_resource_create_ioctl(struct drm_device *dev,
+				 void *data,
+				 struct drm_file *file_priv,
+				 const struct vmw_simple_resource_func *func);
+struct vmw_resource *
+vmw_simple_resource_lookup(struct ttm_object_file *tfile,
+			   uint32_t handle,
+			   const struct vmw_simple_resource_func *func);
 #endif
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_simple_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_simple_resource.c
new file mode 100644
index 0000000..051d3b3
--- /dev/null
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_simple_resource.c
@@ -0,0 +1,256 @@
+/**************************************************************************
+ *
+ * Copyright © 2016 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include "vmwgfx_drv.h"
+#include "vmwgfx_resource_priv.h"
+
+/**
+ * struct vmw_user_simple_resource - User-space simple resource struct
+ *
+ * @base: The TTM base object implementing user-space visibility.
+ * @account_size: How much memory was accounted for this object.
+ * @simple: The embedded struct vmw_simple_resource.
+ */
+struct vmw_user_simple_resource {
+	struct ttm_base_object base;
+	size_t account_size;
+	struct vmw_simple_resource simple;
+/*
+ * Nothing to be placed after @simple, since size of @simple is
+ * unknown.
+ */
+};
+
+
+/**
+ * vmw_simple_resource_init - Initialize a simple resource object.
+ *
+ * @dev_priv: Pointer to a struct device private.
+ * @simple: The struct vmw_simple_resource to initialize.
+ * @data: Data passed to the information initialization function.
+ * @res_free: Function pointer to destroy the simple resource.
+ *
+ * Returns:
+ *   0 if succeeded.
+ *   Negative error value if error, in which case the resource will have been
+ * freed.
+ */
+static int vmw_simple_resource_init(struct vmw_private *dev_priv,
+				    struct vmw_simple_resource *simple,
+				    void *data,
+				    void (*res_free)(struct vmw_resource *res))
+{
+	struct vmw_resource *res = &simple->res;
+	int ret;
+
+	ret = vmw_resource_init(dev_priv, res, false, res_free,
+				&simple->func->res_func);
+
+	if (ret) {
+		res_free(res);
+		return ret;
+	}
+
+	ret = simple->func->init(res, data);
+	if (ret) {
+		vmw_resource_unreference(&res);
+		return ret;
+	}
+
+	vmw_resource_activate(&simple->res, simple->func->hw_destroy);
+
+	return 0;
+}
+
+/**
+ * vmw_simple_resource_free - Free a simple resource object.
+ *
+ * @res: The struct vmw_resource member of the simple resource object.
+ *
+ * Frees memory and memory accounting for the object.
+ */
+static void vmw_simple_resource_free(struct vmw_resource *res)
+{
+	struct vmw_user_simple_resource *usimple =
+		container_of(res, struct vmw_user_simple_resource,
+			     simple.res);
+	struct vmw_private *dev_priv = res->dev_priv;
+	size_t size = usimple->account_size;
+
+	ttm_base_object_kfree(usimple, base);
+	ttm_mem_global_free(vmw_mem_glob(dev_priv), size);
+}
+
+/**
+ * vmw_simple_resource_base_release - TTM object release callback
+ *
+ * @p_base: The struct ttm_base_object member of the simple resource object.
+ *
+ * Called when the last reference to the embedded struct ttm_base_object is
+ * gone. Typically results in an object free, unless there are other
+ * references to the embedded struct vmw_resource.
+ */
+static void vmw_simple_resource_base_release(struct ttm_base_object **p_base)
+{
+	struct ttm_base_object *base = *p_base;
+	struct vmw_user_simple_resource *usimple =
+		container_of(base, struct vmw_user_simple_resource, base);
+	struct vmw_resource *res = &usimple->simple.res;
+
+	*p_base = NULL;
+	vmw_resource_unreference(&res);
+}
+
+/**
+ * vmw_simple_resource_create_ioctl - Helper to set up an ioctl function to
+ * create a struct vmw_simple_resource.
+ *
+ * @dev: Pointer to a struct drm device.
+ * @data: Ioctl argument.
+ * @file_priv: Pointer to a struct drm_file identifying the caller.
+ * @func: Pointer to a struct vmw_simple_resource_func identifying the
+ * simple resource type.
+ *
+ * Returns:
+ *   0 if success,
+ *   Negative error value on error.
+ */
+int
+vmw_simple_resource_create_ioctl(struct drm_device *dev, void *data,
+				 struct drm_file *file_priv,
+				 const struct vmw_simple_resource_func *func)
+{
+	struct vmw_private *dev_priv = vmw_priv(dev);
+	struct vmw_user_simple_resource *usimple;
+	struct vmw_resource *res;
+	struct vmw_resource *tmp;
+	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
+	size_t alloc_size;
+	size_t account_size;
+	int ret;
+
+	alloc_size = offsetof(struct vmw_user_simple_resource, simple) +
+	  func->size;
+	account_size = ttm_round_pot(alloc_size) + VMW_IDA_ACC_SIZE;
+
+	ret = ttm_read_lock(&dev_priv->reservation_sem, true);
+	if (ret)
+		return ret;
+
+	ret = ttm_mem_global_alloc(vmw_mem_glob(dev_priv), account_size,
+				   false, true);
+	ttm_read_unlock(&dev_priv->reservation_sem);
+	if (ret) {
+		if (ret != -ERESTARTSYS)
+			DRM_ERROR("Out of graphics memory for %s"
+				  " creation.\n", func->res_func.type_name);
+
+		goto out_ret;
+	}
+
+	usimple = kzalloc(alloc_size, GFP_KERNEL);
+	if (!usimple) {
+		ttm_mem_global_free(vmw_mem_glob(dev_priv),
+				    account_size);
+		ret = -ENOMEM;
+		goto out_ret;
+	}
+
+	usimple->simple.func = func;
+	usimple->account_size = account_size;
+	res = &usimple->simple.res;
+	usimple->base.shareable = false;
+	usimple->base.tfile = NULL;
+
+	/*
+	 * From here on, the destructor takes over resource freeing.
+	 */
+	ret = vmw_simple_resource_init(dev_priv, &usimple->simple,
+				       data, vmw_simple_resource_free);
+	if (ret)
+		goto out_ret;
+
+	tmp = vmw_resource_reference(res);
+	ret = ttm_base_object_init(tfile, &usimple->base, false,
+				   func->ttm_res_type,
+				   &vmw_simple_resource_base_release, NULL);
+
+	if (ret) {
+		vmw_resource_unreference(&tmp);
+		goto out_err;
+	}
+
+	func->set_arg_handle(data, usimple->base.hash.key);
+out_err:
+	vmw_resource_unreference(&res);
+out_ret:
+	return ret;
+}
+
+/**
+ * vmw_simple_resource_lookup - Look up a simple resource from its user-space
+ * handle.
+ *
+ * @tfile: struct ttm_object_file identifying the caller.
+ * @handle: The user-space handle.
+ * @func: The struct vmw_simple_resource_func identifying the simple resource
+ * type.
+ *
+ * Returns: Refcounted pointer to the embedded struct vmw_resource if
+ * successfule. Error pointer otherwise.
+ */
+struct vmw_resource *
+vmw_simple_resource_lookup(struct ttm_object_file *tfile,
+			   uint32_t handle,
+			   const struct vmw_simple_resource_func *func)
+{
+	struct vmw_user_simple_resource *usimple;
+	struct ttm_base_object *base;
+	struct vmw_resource *res;
+
+	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);
+		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);
+		return ERR_PTR(-EINVAL);
+	}
+
+	usimple = container_of(base, typeof(*usimple), base);
+	res = vmw_resource_reference(&usimple->simple.res);
+	ttm_base_object_unref(&base);
+
+	return res;
+}
-- 
2.7.4

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

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 6/9] drm/vmwgfx: Re-implement the stream resource as a simple resource.
  2017-03-27 22:17 [0/9] Collection of patches queued up for vmwgfx-next Sinclair Yeh
                   ` (4 preceding siblings ...)
  2017-03-27 22:17 ` [PATCH 5/9] drm/vmwgfx: Introduce a simple resource type Sinclair Yeh
@ 2017-03-27 22:17 ` Sinclair Yeh
  2017-03-27 22:17 ` [PATCH 7/9] drm/vmwgfx: Define an overlaid handle_close ioctl Sinclair Yeh
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 13+ messages in thread
From: Sinclair Yeh @ 2017-03-27 22:17 UTC (permalink / raw)
  To: dri-devel; +Cc: thellstrom

From: Thomas Hellstrom <thellstrom@vmware.com>

Provide and document a reference implementation.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Sinclair Yeh <syeh@vmware.com>
---
 drivers/gpu/drm/vmwgfx/Makefile          |   2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | 254 -------------------------------
 drivers/gpu/drm/vmwgfx/vmwgfx_va.c       | 168 ++++++++++++++++++++
 3 files changed, 169 insertions(+), 255 deletions(-)
 create mode 100644 drivers/gpu/drm/vmwgfx/vmwgfx_va.c

diff --git a/drivers/gpu/drm/vmwgfx/Makefile b/drivers/gpu/drm/vmwgfx/Makefile
index 2258908..aac17a6 100644
--- a/drivers/gpu/drm/vmwgfx/Makefile
+++ b/drivers/gpu/drm/vmwgfx/Makefile
@@ -9,6 +9,6 @@ vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_kms.o vmwgfx_drv.o \
 	    vmwgfx_surface.o vmwgfx_prime.o vmwgfx_mob.o vmwgfx_shader.o \
 	    vmwgfx_cmdbuf_res.o vmwgfx_cmdbuf.o vmwgfx_stdu.o \
 	    vmwgfx_cotable.o vmwgfx_so.o vmwgfx_binding.o vmwgfx_msg.o \
-	    vmwgfx_simple_resource.o
+	    vmwgfx_simple_resource.o vmwgfx_va.o
 
 obj-$(CONFIG_DRM_VMWGFX) := vmwgfx.o
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
index 65b3f03..ce652c1 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c
@@ -45,31 +45,6 @@ struct vmw_bo_user_rep {
 	uint64_t map_handle;
 };
 
-struct vmw_stream {
-	struct vmw_resource res;
-	uint32_t stream_id;
-};
-
-struct vmw_user_stream {
-	struct ttm_base_object base;
-	struct vmw_stream stream;
-};
-
-
-static uint64_t vmw_user_stream_size;
-
-static const struct vmw_res_func vmw_stream_func = {
-	.res_type = vmw_res_stream,
-	.needs_backup = false,
-	.may_evict = false,
-	.type_name = "video streams",
-	.backup_placement = NULL,
-	.create = NULL,
-	.destroy = NULL,
-	.bind = NULL,
-	.unbind = NULL
-};
-
 static inline struct vmw_dma_buffer *
 vmw_dma_buffer(struct ttm_buffer_object *bo)
 {
@@ -259,24 +234,6 @@ void vmw_resource_activate(struct vmw_resource *res,
 	write_unlock(&dev_priv->resource_lock);
 }
 
-static struct vmw_resource *vmw_resource_lookup(struct vmw_private *dev_priv,
-						struct idr *idr, int id)
-{
-	struct vmw_resource *res;
-
-	read_lock(&dev_priv->resource_lock);
-	res = idr_find(idr, id);
-	if (!res || !res->avail || !kref_get_unless_zero(&res->kref))
-		res = NULL;
-
-	read_unlock(&dev_priv->resource_lock);
-
-	if (unlikely(res == NULL))
-		return NULL;
-
-	return res;
-}
-
 /**
  * vmw_user_resource_lookup_handle - lookup a struct resource from a
  * TTM user-space handle and perform basic type checks
@@ -776,217 +733,6 @@ int vmw_user_dmabuf_reference(struct ttm_object_file *tfile,
 				  TTM_REF_USAGE, NULL);
 }
 
-/*
- * Stream management
- */
-
-static void vmw_stream_destroy(struct vmw_resource *res)
-{
-	struct vmw_private *dev_priv = res->dev_priv;
-	struct vmw_stream *stream;
-	int ret;
-
-	DRM_INFO("%s: unref\n", __func__);
-	stream = container_of(res, struct vmw_stream, res);
-
-	ret = vmw_overlay_unref(dev_priv, stream->stream_id);
-	WARN_ON(ret != 0);
-}
-
-static int vmw_stream_init(struct vmw_private *dev_priv,
-			   struct vmw_stream *stream,
-			   void (*res_free) (struct vmw_resource *res))
-{
-	struct vmw_resource *res = &stream->res;
-	int ret;
-
-	ret = vmw_resource_init(dev_priv, res, false, res_free,
-				&vmw_stream_func);
-
-	if (unlikely(ret != 0)) {
-		if (res_free == NULL)
-			kfree(stream);
-		else
-			res_free(&stream->res);
-		return ret;
-	}
-
-	ret = vmw_overlay_claim(dev_priv, &stream->stream_id);
-	if (ret) {
-		vmw_resource_unreference(&res);
-		return ret;
-	}
-
-	DRM_INFO("%s: claimed\n", __func__);
-
-	vmw_resource_activate(&stream->res, vmw_stream_destroy);
-	return 0;
-}
-
-static void vmw_user_stream_free(struct vmw_resource *res)
-{
-	struct vmw_user_stream *stream =
-	    container_of(res, struct vmw_user_stream, stream.res);
-	struct vmw_private *dev_priv = res->dev_priv;
-
-	ttm_base_object_kfree(stream, base);
-	ttm_mem_global_free(vmw_mem_glob(dev_priv),
-			    vmw_user_stream_size);
-}
-
-/**
- * This function is called when user space has no more references on the
- * base object. It releases the base-object's reference on the resource object.
- */
-
-static void vmw_user_stream_base_release(struct ttm_base_object **p_base)
-{
-	struct ttm_base_object *base = *p_base;
-	struct vmw_user_stream *stream =
-	    container_of(base, struct vmw_user_stream, base);
-	struct vmw_resource *res = &stream->stream.res;
-
-	*p_base = NULL;
-	vmw_resource_unreference(&res);
-}
-
-int vmw_stream_unref_ioctl(struct drm_device *dev, void *data,
-			   struct drm_file *file_priv)
-{
-	struct vmw_private *dev_priv = vmw_priv(dev);
-	struct vmw_resource *res;
-	struct vmw_user_stream *stream;
-	struct drm_vmw_stream_arg *arg = (struct drm_vmw_stream_arg *)data;
-	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
-	struct idr *idr = &dev_priv->res_idr[vmw_res_stream];
-	int ret = 0;
-
-
-	res = vmw_resource_lookup(dev_priv, idr, arg->stream_id);
-	if (unlikely(res == NULL))
-		return -EINVAL;
-
-	if (res->res_free != &vmw_user_stream_free) {
-		ret = -EINVAL;
-		goto out;
-	}
-
-	stream = container_of(res, struct vmw_user_stream, stream.res);
-	if (stream->base.tfile != tfile) {
-		ret = -EINVAL;
-		goto out;
-	}
-
-	ttm_ref_object_base_unref(tfile, stream->base.hash.key, TTM_REF_USAGE);
-out:
-	vmw_resource_unreference(&res);
-	return ret;
-}
-
-int vmw_stream_claim_ioctl(struct drm_device *dev, void *data,
-			   struct drm_file *file_priv)
-{
-	struct vmw_private *dev_priv = vmw_priv(dev);
-	struct vmw_user_stream *stream;
-	struct vmw_resource *res;
-	struct vmw_resource *tmp;
-	struct drm_vmw_stream_arg *arg = (struct drm_vmw_stream_arg *)data;
-	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
-	int ret;
-
-	/*
-	 * Approximate idr memory usage with 128 bytes. It will be limited
-	 * by maximum number_of streams anyway?
-	 */
-
-	if (unlikely(vmw_user_stream_size == 0))
-		vmw_user_stream_size = ttm_round_pot(sizeof(*stream)) + 128;
-
-	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),
-				   vmw_user_stream_size,
-				   false, true);
-	ttm_read_unlock(&dev_priv->reservation_sem);
-	if (unlikely(ret != 0)) {
-		if (ret != -ERESTARTSYS)
-			DRM_ERROR("Out of graphics memory for stream"
-				  " creation.\n");
-
-		goto out_ret;
-	}
-
-	stream = kmalloc(sizeof(*stream), GFP_KERNEL);
-	if (unlikely(stream == NULL)) {
-		ttm_mem_global_free(vmw_mem_glob(dev_priv),
-				    vmw_user_stream_size);
-		ret = -ENOMEM;
-		goto out_ret;
-	}
-
-	res = &stream->stream.res;
-	stream->base.shareable = false;
-	stream->base.tfile = NULL;
-
-	/*
-	 * From here on, the destructor takes over resource freeing.
-	 */
-
-	ret = vmw_stream_init(dev_priv, &stream->stream, vmw_user_stream_free);
-	if (unlikely(ret != 0))
-		goto out_ret;
-
-	tmp = vmw_resource_reference(res);
-	ret = ttm_base_object_init(tfile, &stream->base, false, VMW_RES_STREAM,
-				   &vmw_user_stream_base_release, NULL);
-
-	if (unlikely(ret != 0)) {
-		vmw_resource_unreference(&tmp);
-		goto out_err;
-	}
-
-	arg->stream_id = res->id;
-out_err:
-	vmw_resource_unreference(&res);
-out_ret:
-	return ret;
-}
-
-int vmw_user_stream_lookup(struct vmw_private *dev_priv,
-			   struct ttm_object_file *tfile,
-			   uint32_t *inout_id, struct vmw_resource **out)
-{
-	struct vmw_user_stream *stream;
-	struct vmw_resource *res;
-	int ret;
-
-	res = vmw_resource_lookup(dev_priv, &dev_priv->res_idr[vmw_res_stream],
-				  *inout_id);
-	if (unlikely(res == NULL))
-		return -EINVAL;
-
-	if (res->res_free != &vmw_user_stream_free) {
-		ret = -EINVAL;
-		goto err_ref;
-	}
-
-	stream = container_of(res, struct vmw_user_stream, stream.res);
-	if (stream->base.tfile != tfile) {
-		ret = -EPERM;
-		goto err_ref;
-	}
-
-	*inout_id = stream->stream.stream_id;
-	*out = res;
-	return 0;
-err_ref:
-	vmw_resource_unreference(&res);
-	return ret;
-}
-
-
 /**
  * vmw_dumb_create - Create a dumb kms buffer
  *
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_va.c b/drivers/gpu/drm/vmwgfx/vmwgfx_va.c
new file mode 100644
index 0000000..b4162fd
--- /dev/null
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_va.c
@@ -0,0 +1,168 @@
+/**************************************************************************
+ *
+ * Copyright © 2012-2016 VMware, Inc., Palo Alto, CA., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include "vmwgfx_drv.h"
+#include "vmwgfx_resource_priv.h"
+
+/**
+ * struct vmw_stream - Overlay stream simple resource.
+ * @sres: The simple resource we derive from.
+ * @stream_id: The overlay stream id.
+ */
+struct vmw_stream {
+	struct vmw_simple_resource sres;
+	u32 stream_id;
+};
+
+/**
+ * vmw_stream - Typecast a struct vmw_resource to a struct vmw_stream.
+ * @res: Pointer to the struct vmw_resource.
+ *
+ * Returns: Returns a pointer to the struct vmw_stream.
+ */
+static struct vmw_stream *
+vmw_stream(struct vmw_resource *res)
+{
+	return container_of(res, struct vmw_stream, sres.res);
+}
+
+/***************************************************************************
+ * Simple resource callbacks for struct vmw_stream
+ **************************************************************************/
+static void vmw_stream_hw_destroy(struct vmw_resource *res)
+{
+	struct vmw_private *dev_priv = res->dev_priv;
+	struct vmw_stream *stream = vmw_stream(res);
+	int ret;
+
+	ret = vmw_overlay_unref(dev_priv, stream->stream_id);
+	WARN_ON_ONCE(ret != 0);
+}
+
+static int vmw_stream_init(struct vmw_resource *res, void *data)
+{
+	struct vmw_stream *stream = vmw_stream(res);
+
+	return vmw_overlay_claim(res->dev_priv, &stream->stream_id);
+}
+
+static void vmw_stream_set_arg_handle(void *data, u32 handle)
+{
+	struct drm_vmw_stream_arg *arg = (struct drm_vmw_stream_arg *)data;
+
+	arg->stream_id = handle;
+}
+
+static const struct vmw_simple_resource_func va_stream_func = {
+	.res_func = {
+		.res_type = vmw_res_stream,
+		.needs_backup = false,
+		.may_evict = false,
+		.type_name = "overlay stream",
+		.backup_placement = NULL,
+		.create = NULL,
+		.destroy = NULL,
+		.bind = NULL,
+		.unbind = NULL
+	},
+	.ttm_res_type = VMW_RES_STREAM,
+	.size = sizeof(struct vmw_stream),
+	.init = vmw_stream_init,
+	.hw_destroy = vmw_stream_hw_destroy,
+	.set_arg_handle = vmw_stream_set_arg_handle,
+};
+
+/***************************************************************************
+ * End simple resource callbacks for struct vmw_stream
+ **************************************************************************/
+
+/**
+ * vmw_stream_unref_ioctl - Ioctl to unreference a user-space handle to
+ * a struct vmw_stream.
+ * @dev: Pointer to the drm device.
+ * @data: The ioctl argument
+ * @file_priv: Pointer to a struct drm_file identifying the caller.
+ *
+ * Return:
+ *   0 if successful.
+ *   Negative error value on failure.
+ */
+int vmw_stream_unref_ioctl(struct drm_device *dev, void *data,
+			   struct drm_file *file_priv)
+{
+	struct drm_vmw_stream_arg *arg = (struct drm_vmw_stream_arg *)data;
+
+	return ttm_ref_object_base_unref(vmw_fpriv(file_priv)->tfile,
+					 arg->stream_id, TTM_REF_USAGE);
+}
+
+/**
+ * vmw_stream_claim_ioctl - Ioctl to claim a struct vmw_stream overlay.
+ * @dev: Pointer to the drm device.
+ * @data: The ioctl argument
+ * @file_priv: Pointer to a struct drm_file identifying the caller.
+ *
+ * Return:
+ *   0 if successful.
+ *   Negative error value on failure.
+ */
+int vmw_stream_claim_ioctl(struct drm_device *dev, void *data,
+			   struct drm_file *file_priv)
+{
+	return vmw_simple_resource_create_ioctl(dev, data, file_priv,
+						&va_stream_func);
+}
+
+/**
+ * vmw_user_stream_lookup - Look up a struct vmw_user_stream from a handle.
+ * @dev_priv: Pointer to a struct vmw_private.
+ * @tfile: struct ttm_object_file identifying the caller.
+ * @inout_id: In: The user-space handle. Out: The stream id.
+ * @out: On output contains a refcounted pointer to the embedded
+ * struct vmw_resource.
+ *
+ * Return:
+ *   0 if successful.
+ *   Negative error value on failure.
+ */
+int vmw_user_stream_lookup(struct vmw_private *dev_priv,
+			   struct ttm_object_file *tfile,
+			   uint32_t *inout_id, struct vmw_resource **out)
+{
+	struct vmw_stream *stream;
+	struct vmw_resource *res =
+		vmw_simple_resource_lookup(tfile, *inout_id, &va_stream_func);
+
+	if (IS_ERR(res))
+		return PTR_ERR(res);
+
+	stream = vmw_stream(res);
+	*inout_id = stream->stream_id;
+	*out = res;
+
+	return 0;
+}
-- 
2.7.4

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

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 7/9] drm/vmwgfx: Define an overlaid handle_close ioctl.
  2017-03-27 22:17 [0/9] Collection of patches queued up for vmwgfx-next Sinclair Yeh
                   ` (5 preceding siblings ...)
  2017-03-27 22:17 ` [PATCH 6/9] drm/vmwgfx: Re-implement the stream resource as a simple resource Sinclair Yeh
@ 2017-03-27 22:17 ` Sinclair Yeh
  2017-03-27 22:17 ` [PATCH 8/9] drm/vmwgfx: Support topology greater than texture size Sinclair Yeh
  2017-03-27 22:17 ` [PATCH 9/9] drm/vmwgfx: Properly check display/scanout surface size Sinclair Yeh
  8 siblings, 0 replies; 13+ messages in thread
From: Sinclair Yeh @ 2017-03-27 22:17 UTC (permalink / raw)
  To: dri-devel; +Cc: thellstrom

From: Thomas Hellstrom <thellstrom@vmware.com>

Instead of providing an ioctl for each handle type, provide a single
handle_close ioctl, and reuse the UNREF_DMABUF ioctl.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Sinclair Yeh <syeh@vmware.com>
---
 include/uapi/drm/vmwgfx_drm.h | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/include/uapi/drm/vmwgfx_drm.h b/include/uapi/drm/vmwgfx_drm.h
index d325a41..d9dfde9 100644
--- a/include/uapi/drm/vmwgfx_drm.h
+++ b/include/uapi/drm/vmwgfx_drm.h
@@ -41,6 +41,7 @@ extern "C" {
 #define DRM_VMW_GET_PARAM            0
 #define DRM_VMW_ALLOC_DMABUF         1
 #define DRM_VMW_UNREF_DMABUF         2
+#define DRM_VMW_HANDLE_CLOSE         2
 #define DRM_VMW_CURSOR_BYPASS        3
 /* guarded by DRM_VMW_PARAM_NUM_STREAMS != 0*/
 #define DRM_VMW_CONTROL_STREAM       4
@@ -1092,6 +1093,29 @@ union drm_vmw_extended_context_arg {
 	struct drm_vmw_context_arg rep;
 };
 
+/*************************************************************************/
+/*
+ * DRM_VMW_HANDLE_CLOSE - Close a user-space handle and release its
+ * underlying resource.
+ *
+ * Note that this ioctl is overlaid on the DRM_VMW_UNREF_DMABUF Ioctl.
+ * The ioctl arguments therefore need to be identical in layout.
+ *
+ */
+
+/**
+ * struct drm_vmw_handle_close_arg
+ *
+ * @handle: Handle to close.
+ *
+ * Argument to the DRM_VMW_HANDLE_CLOSE Ioctl.
+ */
+struct drm_vmw_handle_close_arg {
+	__u32 handle;
+	__u32 pad64;
+};
+
+
 #if defined(__cplusplus)
 }
 #endif
-- 
2.7.4

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

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 8/9] drm/vmwgfx: Support topology greater than texture size
  2017-03-27 22:17 [0/9] Collection of patches queued up for vmwgfx-next Sinclair Yeh
                   ` (6 preceding siblings ...)
  2017-03-27 22:17 ` [PATCH 7/9] drm/vmwgfx: Define an overlaid handle_close ioctl Sinclair Yeh
@ 2017-03-27 22:17 ` Sinclair Yeh
  2017-03-27 22:17 ` [PATCH 9/9] drm/vmwgfx: Properly check display/scanout surface size Sinclair Yeh
  8 siblings, 0 replies; 13+ messages in thread
From: Sinclair Yeh @ 2017-03-27 22:17 UTC (permalink / raw)
  To: dri-devel; +Cc: thellstrom

Most of the display servers today use a single surface to represent the
entire desktop even if it's stretched across multiple screens.

For vmwgfx with STDU, the maximum surface size is limited to the
maximum texture size on the host.  On a 2D VM, this limits our
ability to support configurations with more than one 4K monitor.

To get past this limitation, we will now allow using a large DMA buf
as the framebuffer, and take care of blitting contents from this DMA buf
to the display buffer.

Signed-off-by: Sinclair Yeh <syeh@vmware.com>
Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
---
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c  |  64 ++++++++++-
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.h  |   4 +
 drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c | 202 +++++++++++++++++++++++++++++++++++
 3 files changed, 269 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 7104796..881ffd4 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -803,6 +803,11 @@ vmw_du_plane_duplicate_state(struct drm_plane *plane)
 
 	vps->pinned = 0;
 
+	/* Mapping is managed by prepare_fb/cleanup_fb */
+	memset(&vps->guest_map, 0, sizeof(vps->guest_map));
+	memset(&vps->host_map, 0, sizeof(vps->host_map));
+	vps->cpp = 0;
+
 	/* Each ref counted resource needs to be acquired again */
 	if (vps->surf)
 		(void) vmw_surface_reference(vps->surf);
@@ -861,6 +866,17 @@ vmw_du_plane_destroy_state(struct drm_plane *plane,
 	struct vmw_plane_state *vps = vmw_plane_state_to_vps(state);
 
 
+	/* Should have been freed by cleanup_fb */
+	if (vps->guest_map.virtual) {
+		DRM_ERROR("Guest mapping not freed\n");
+		ttm_bo_kunmap(&vps->guest_map);
+	}
+
+	if (vps->host_map.virtual) {
+		DRM_ERROR("Host mapping not freed\n");
+		ttm_bo_kunmap(&vps->host_map);
+	}
+
 	if (vps->surf)
 		vmw_surface_unreference(&vps->surf);
 
@@ -1435,6 +1451,25 @@ static int vmw_kms_new_framebuffer_dmabuf(struct vmw_private *dev_priv,
 	return ret;
 }
 
+
+/**
+ * vmw_kms_srf_ok - check if a surface can be created
+ *
+ * @width: requested width
+ * @height: requested height
+ *
+ * Surfaces need to be less than texture size
+ */
+static bool
+vmw_kms_srf_ok(struct vmw_private *dev_priv, uint32_t width, uint32_t height)
+{
+	if (width  > dev_priv->texture_max_width ||
+	    height > dev_priv->texture_max_height)
+		return false;
+
+	return true;
+}
+
 /**
  * vmw_kms_new_framebuffer - Create a new framebuffer.
  *
@@ -1463,7 +1498,8 @@ vmw_kms_new_framebuffer(struct vmw_private *dev_priv,
 	 * therefore, wrap the DMA buf in a surface so we can use the
 	 * SurfaceCopy command.
 	 */
-	if (dmabuf && only_2d &&
+	if (vmw_kms_srf_ok(dev_priv, mode_cmd->width, mode_cmd->height)  &&
+	    dmabuf && only_2d &&
 	    dev_priv->active_display_unit == vmw_du_screen_target) {
 		ret = vmw_create_dmabuf_proxy(dev_priv->dev, mode_cmd,
 					      dmabuf, &surface);
@@ -1556,6 +1592,16 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev,
 	if (ret)
 		goto err_out;
 
+
+	if (!bo &&
+	    !vmw_kms_srf_ok(dev_priv, mode_cmd->width, mode_cmd->height)) {
+		DRM_ERROR("Surface size cannot exceed %dx%d",
+			dev_priv->texture_max_width,
+			dev_priv->texture_max_height);
+		goto err_out;
+	}
+
+
 	vfb = vmw_kms_new_framebuffer(dev_priv, bo, surface,
 				      !(dev_priv->capabilities & SVGA_CAP_3D),
 				      mode_cmd);
@@ -1602,10 +1648,13 @@ vmw_kms_atomic_check_modeset(struct drm_device *dev,
 {
 	struct drm_crtc_state *crtc_state;
 	struct drm_crtc *crtc;
+	struct vmw_private *dev_priv = vmw_priv(dev);
 	int i, ret;
 
 
 	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		unsigned long requested_bb_mem = 0;
+
 		if (crtc_state->mode.crtc_clock == 0) {
 			/*
 			 * Our virtual device does not have a dot clock,
@@ -1613,6 +1662,19 @@ vmw_kms_atomic_check_modeset(struct drm_device *dev,
 			 */
 			crtc_state->mode.crtc_clock = crtc_state->mode.clock;
 		}
+
+		if (dev_priv->active_display_unit == vmw_du_screen_target) {
+			if (crtc->primary->fb) {
+				int cpp = crtc->primary->fb->pitches[0] /
+					  crtc->primary->fb->width;
+
+				requested_bb_mem += crtc->mode.hdisplay * cpp *
+						    crtc->mode.vdisplay;
+			}
+
+			if (requested_bb_mem > dev_priv->prim_bb_mem)
+				return -EINVAL;
+		}
 	}
 
 	ret = drm_atomic_helper_check_modeset(dev, state);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
index 0016f07..0c4a566 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
@@ -173,6 +173,10 @@ struct vmw_plane_state {
 	unsigned long dmabuf_size;
 
 	int pinned;
+
+	/* For CPU Blit */
+	struct ttm_bo_kmap_obj host_map, guest_map;
+	unsigned int cpp;
 };
 
 
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
index 9e40138..ce1191a 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
@@ -109,6 +109,10 @@ struct vmw_screen_target_display_unit {
 	s32 display_width, display_height;
 
 	bool defined;
+
+	/* For CPU Blit */
+	struct ttm_bo_kmap_obj host_map, guest_map;
+	unsigned int cpp;
 };
 
 
@@ -636,6 +640,129 @@ static void vmw_stdu_dmabuf_fifo_commit(struct vmw_kms_dirty *dirty)
 	ddirty->right = ddirty->bottom = S32_MIN;
 }
 
+
+/**
+ * vmw_stdu_dmabuf_cpu_clip - Callback to encode a CPU blit
+ *
+ * @dirty: The closure structure.
+ *
+ * This function calculates the bounding box for all the incoming clips
+ */
+static void vmw_stdu_dmabuf_cpu_clip(struct vmw_kms_dirty *dirty)
+{
+	struct vmw_stdu_dirty *ddirty =
+		container_of(dirty, struct vmw_stdu_dirty, base);
+
+	dirty->num_hits = 1;
+
+	/* Calculate bounding box */
+	ddirty->left = min_t(s32, ddirty->left, dirty->unit_x1);
+	ddirty->top = min_t(s32, ddirty->top, dirty->unit_y1);
+	ddirty->right = max_t(s32, ddirty->right, dirty->unit_x2);
+	ddirty->bottom = max_t(s32, ddirty->bottom, dirty->unit_y2);
+}
+
+
+/**
+ * vmw_stdu_dmabuf_cpu_commit - Callback to do a CPU blit from DMAbuf
+ *
+ * @dirty: The closure structure.
+ *
+ * For the special case when we cannot create a proxy surface in a
+ * 2D VM, we have to do a CPU blit ourselves.
+ */
+static void vmw_stdu_dmabuf_cpu_commit(struct vmw_kms_dirty *dirty)
+{
+	struct vmw_stdu_dirty *ddirty =
+		container_of(dirty, struct vmw_stdu_dirty, base);
+	struct vmw_screen_target_display_unit *stdu =
+		container_of(dirty->unit, typeof(*stdu), base);
+	s32 width, height;
+	s32 src_pitch, dst_pitch;
+	u8 *src, *dst;
+	bool not_used;
+
+
+	if (!dirty->num_hits)
+		return;
+
+	width = ddirty->right - ddirty->left;
+	height = ddirty->bottom - ddirty->top;
+
+	if (width == 0 || height == 0)
+		return;
+
+
+	/* Assume we are blitting from Host (display_srf) to Guest (dmabuf) */
+	src_pitch = stdu->display_srf->base_size.width * stdu->cpp;
+	src = ttm_kmap_obj_virtual(&stdu->host_map, &not_used);
+	src += dirty->unit_y1 * src_pitch + dirty->unit_x1 * stdu->cpp;
+
+	dst_pitch = ddirty->pitch;
+	dst = ttm_kmap_obj_virtual(&stdu->guest_map, &not_used);
+	dst += dirty->fb_y * dst_pitch + dirty->fb_x * stdu->cpp;
+
+
+	/* Figure out the real direction */
+	if (ddirty->transfer == SVGA3D_WRITE_HOST_VRAM) {
+		u8 *tmp;
+		s32 tmp_pitch;
+
+		tmp = src;
+		tmp_pitch = src_pitch;
+
+		src = dst;
+		src_pitch = dst_pitch;
+
+		dst = tmp;
+		dst_pitch = tmp_pitch;
+	}
+
+	/* CPU Blit */
+	while (height-- > 0) {
+		memcpy(dst, src, width * stdu->cpp);
+		dst += dst_pitch;
+		src += src_pitch;
+	}
+
+	if (ddirty->transfer == SVGA3D_WRITE_HOST_VRAM) {
+		struct vmw_private *dev_priv;
+		struct vmw_stdu_update *cmd;
+		struct drm_clip_rect region;
+		int ret;
+
+		/* We are updating the actual surface, not a proxy */
+		region.x1 = ddirty->left;
+		region.x2 = ddirty->right;
+		region.y1 = ddirty->top;
+		region.y2 = ddirty->bottom;
+		ret = vmw_kms_update_proxy(
+			(struct vmw_resource *) &stdu->display_srf->res,
+			(const struct drm_clip_rect *) &region, 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");
+			goto out_cleanup;
+		}
+
+		vmw_stdu_populate_update(cmd, stdu->base.unit,
+					 ddirty->left, ddirty->right,
+					 ddirty->top, ddirty->bottom);
+
+		vmw_fifo_commit(dev_priv, sizeof(*cmd));
+	}
+
+out_cleanup:
+	ddirty->left = ddirty->top = S32_MAX;
+	ddirty->right = ddirty->bottom = S32_MIN;
+}
+
 /**
  * vmw_kms_stdu_dma - Perform a DMA transfer between a dma-buffer backed
  * framebuffer and the screen target system.
@@ -694,6 +821,13 @@ int vmw_kms_stdu_dma(struct vmw_private *dev_priv,
 	if (to_surface)
 		ddirty.base.fifo_reserve_size += sizeof(struct vmw_stdu_update);
 
+	/* 2D VMs cannot use SVGA_3D_CMD_SURFACE_DMA so do CPU blit instead */
+	if (!(dev_priv->capabilities & SVGA_CAP_3D)) {
+		ddirty.base.fifo_commit = vmw_stdu_dmabuf_cpu_commit;
+		ddirty.base.clip = vmw_stdu_dmabuf_cpu_clip;
+		ddirty.base.fifo_reserve_size = 0;
+	}
+
 	ret = vmw_kms_helper_dirty(dev_priv, vfb, clips, vclips,
 				   0, 0, num_clips, increment, &ddirty.base);
 	vmw_kms_helper_buffer_finish(dev_priv, file_priv, buf, NULL,
@@ -960,12 +1094,19 @@ vmw_stdu_primary_plane_cleanup_fb(struct drm_plane *plane,
 {
 	struct vmw_plane_state *vps = vmw_plane_state_to_vps(old_state);
 
+	if (vps->guest_map.virtual)
+		ttm_bo_kunmap(&vps->guest_map);
+
+	if (vps->host_map.virtual)
+		ttm_bo_kunmap(&vps->host_map);
+
 	if (vps->surf)
 		WARN_ON(!vps->pinned);
 
 	vmw_du_plane_cleanup_fb(plane, old_state);
 
 	vps->content_fb_type = SAME_AS_DISPLAY;
+	vps->cpp = 0;
 }
 
 
@@ -986,6 +1127,7 @@ static int
 vmw_stdu_primary_plane_prepare_fb(struct drm_plane *plane,
 				  struct drm_plane_state *new_state)
 {
+	struct vmw_private *dev_priv = vmw_priv(plane->dev);
 	struct drm_framebuffer *new_fb = new_state->fb;
 	struct vmw_framebuffer *vfb;
 	struct vmw_plane_state *vps = vmw_plane_state_to_vps(new_state);
@@ -1111,8 +1253,54 @@ vmw_stdu_primary_plane_prepare_fb(struct drm_plane *plane,
 	}
 
 	vps->content_fb_type = new_content_type;
+
+	/*
+	 * This should only happen if the DMA buf is too large to create a
+	 * proxy surface for.
+	 * If we are a 2D VM with a DMA buffer then we have to use CPU blit
+	 * so cache these mappings
+	 */
+	if (vps->content_fb_type == SEPARATE_DMA &&
+	    !(dev_priv->capabilities & SVGA_CAP_3D)) {
+
+		struct vmw_framebuffer_dmabuf *new_vfbd;
+
+		new_vfbd = vmw_framebuffer_to_vfbd(new_fb);
+
+		ret = ttm_bo_reserve(&new_vfbd->buffer->base, false, false,
+				     NULL);
+		if (ret)
+			goto out_srf_unpin;
+
+		ret = ttm_bo_kmap(&new_vfbd->buffer->base, 0,
+				  new_vfbd->buffer->base.num_pages,
+				  &vps->guest_map);
+
+		ttm_bo_unreserve(&new_vfbd->buffer->base);
+
+		if (ret) {
+			DRM_ERROR("Failed to map content buffer to CPU\n");
+			goto out_srf_unpin;
+		}
+
+		ret = ttm_bo_kmap(&vps->surf->res.backup->base, 0,
+				  vps->surf->res.backup->base.num_pages,
+				  &vps->host_map);
+		if (ret) {
+			DRM_ERROR("Failed to map display buffer to CPU\n");
+			ttm_bo_kunmap(&vps->guest_map);
+			goto out_srf_unpin;
+		}
+
+		vps->cpp = new_fb->pitches[0] / new_fb->width;
+	}
+
 	return 0;
 
+out_srf_unpin:
+	vmw_resource_unpin(&vps->surf->res);
+	vps->pinned--;
+
 out_srf_unref:
 	vmw_surface_unreference(&vps->surf);
 	return ret;
@@ -1146,6 +1334,9 @@ vmw_stdu_primary_plane_atomic_update(struct drm_plane *plane,
 
 	stdu->display_srf = vps->surf;
 	stdu->content_fb_type = vps->content_fb_type;
+	stdu->cpp = vps->cpp;
+	memcpy(&stdu->guest_map, &vps->guest_map, sizeof(vps->guest_map));
+	memcpy(&stdu->host_map, &vps->host_map, sizeof(vps->host_map));
 
 	if (!stdu->defined)
 		return;
@@ -1411,6 +1602,17 @@ int vmw_kms_stdu_init_display(struct vmw_private *dev_priv)
 
 	dev_priv->active_display_unit = vmw_du_screen_target;
 
+	if (!(dev_priv->capabilities & SVGA_CAP_3D)) {
+		/*
+		 * Given various display aspect ratios, there's no way to
+		 * estimate these using prim_bb_mem.  So just set these to
+		 * something arbitrarily large and we will reject any layout
+		 * that doesn't fit prim_bb_mem later
+		 */
+		dev->mode_config.max_width = 16384;
+		dev->mode_config.max_height = 16384;
+	}
+
 	vmw_kms_create_implicit_placement_property(dev_priv, false);
 
 	for (i = 0; i < VMWGFX_NUM_DISPLAY_UNITS; ++i) {
-- 
2.7.4

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

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH 9/9] drm/vmwgfx: Properly check display/scanout surface size
  2017-03-27 22:17 [0/9] Collection of patches queued up for vmwgfx-next Sinclair Yeh
                   ` (7 preceding siblings ...)
  2017-03-27 22:17 ` [PATCH 8/9] drm/vmwgfx: Support topology greater than texture size Sinclair Yeh
@ 2017-03-27 22:17 ` Sinclair Yeh
  8 siblings, 0 replies; 13+ messages in thread
From: Sinclair Yeh @ 2017-03-27 22:17 UTC (permalink / raw)
  To: dri-devel; +Cc: thellstrom

The scanout surface size is the smaller of max texture size and
max STDU size.

Signed-off-by: Sinclair Yeh <syeh@vmware.com>
Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
---
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c     |  3 +++
 drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c    | 16 +++++++++++++++-
 drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 14 ++++++++++++++
 3 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 881ffd4..9b0bf2c 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -2218,7 +2218,10 @@ int vmw_du_connector_fill_modes(struct drm_connector *connector,
 
 	if (dev_priv->active_display_unit == vmw_du_screen_target) {
 		max_width  = min(max_width,  dev_priv->stdu_max_width);
+		max_width  = min(max_width,  dev_priv->texture_max_width);
+
 		max_height = min(max_height, dev_priv->stdu_max_height);
+		max_height = min(max_height, dev_priv->texture_max_height);
 	}
 
 	/* Add preferred mode */
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
index ce1191a..6ae2042 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
@@ -1602,7 +1602,21 @@ int vmw_kms_stdu_init_display(struct vmw_private *dev_priv)
 
 	dev_priv->active_display_unit = vmw_du_screen_target;
 
-	if (!(dev_priv->capabilities & SVGA_CAP_3D)) {
+	if (dev_priv->capabilities & SVGA_CAP_3D) {
+		/*
+		 * For 3D VMs, display (scanout) buffer size is the smaller of
+		 * max texture and max STDU
+		 */
+		uint32_t max_width, max_height;
+
+		max_width = min(dev_priv->texture_max_width,
+				dev_priv->stdu_max_width);
+		max_height = min(dev_priv->texture_max_height,
+				 dev_priv->stdu_max_height);
+
+		dev->mode_config.max_width = max_width;
+		dev->mode_config.max_height = max_height;
+	} else {
 		/*
 		 * Given various display aspect ratios, there's no way to
 		 * estimate these using prim_bb_mem.  So just set these to
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
index 6abcf82..41b9d20 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c
@@ -1479,10 +1479,24 @@ int vmw_surface_gb_priv_define(struct drm_device *dev,
 	*srf_out = NULL;
 
 	if (for_scanout) {
+		uint32_t max_width, max_height;
+
 		if (!svga3dsurface_is_screen_target_format(format)) {
 			DRM_ERROR("Invalid Screen Target surface format.");
 			return -EINVAL;
 		}
+
+		max_width = min(dev_priv->texture_max_width,
+				dev_priv->stdu_max_width);
+		max_height = min(dev_priv->texture_max_height,
+				 dev_priv->stdu_max_height);
+
+		if (size.width > max_width || size.height > max_height) {
+			DRM_ERROR("%ux%u\n, exeeds max surface size %ux%u",
+				  size.width, size.height,
+				  max_width, max_height);
+			return -EINVAL;
+		}
 	} else {
 		const struct svga3d_surface_desc *desc;
 
-- 
2.7.4

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

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH 4/9] drm/vmwgfx: Revert "drm/vmwgfx: Replace numeric parameter like 0444 with macro"
  2017-03-27 22:17 ` [PATCH 4/9] drm/vmwgfx: Revert "drm/vmwgfx: Replace numeric parameter like 0444 with macro" Sinclair Yeh
@ 2017-04-02  6:54   ` Øyvind A. Holm
  2017-04-03 16:39     ` Sinclair Yeh
  0 siblings, 1 reply; 13+ messages in thread
From: Øyvind A. Holm @ 2017-04-02  6:54 UTC (permalink / raw)
  To: Sinclair Yeh; +Cc: thellstrom, dri-devel


[-- Attachment #1.1: Type: text/plain, Size: 2546 bytes --]

On 2017-03-27 15:17:54, Sinclair Yeh wrote:
> From: Øyvind A. Holm <sunny@sunbase.org>
>
> This reverts commit 2d8e60e8b074 ("drm/vmwgfx: Replace numeric
> parameter like 0444 with macro")
> [...]
> index 45d711e..d31dc34 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
> @@ -241,13 +241,13 @@ static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val,
>  			      void *ptr);
>
>  MODULE_PARM_DESC(enable_fbdev, "Enable vmwgfx fbdev");
> -module_param_named(enable_fbdev, enable_fbdev, int, S_IRUSR | S_IWUSR);
> +module_param_named(enable_fbdev, enable_fbdev, int, 0600);
>  MODULE_PARM_DESC(force_dma_api, "Force using the DMA API for TTM pages");
> -module_param_named(force_dma_api, vmw_force_iommu, int, S_IRUSR | S_IWUSR);
> +module_param_named(force_dma_api, vmw_force_iommu, int, 0600);
>  MODULE_PARM_DESC(restrict_iommu, "Try to limit IOMMU usage for TTM pages");
> -module_param_named(restrict_iommu, vmw_restrict_iommu, int, S_IRUSR | S_IWUSR);
> +module_param_named(restrict_iommu, vmw_restrict_iommu, int, 0600);
>  MODULE_PARM_DESC(force_coherent, "Force coherent TTM pages");
> -module_param_named(force_coherent, vmw_force_coherent, int, S_IRUSR | S_IWUSR);
> +module_param_named(force_coherent, vmw_force_coherent, int, 0600);
>  MODULE_PARM_DESC(restrict_dma_mask, "Restrict DMA mask to 44 bits with IOMMU");
>  module_param_named(restrict_dma_mask, vmw_restrict_dma_mask, int, S_IRUSR | S_IWUSR);
>  MODULE_PARM_DESC(assume_16bpp, "Assume 16-bpp when filtering modes");
> --
> 2.7.4

It seems as something has happened to the patch when applied, the last 
change is gone, it was in my original patch sent to the list. This 
change is missing:

  -module_param_named(restrict_dma_mask, vmw_restrict_dma_mask, int, S_IRUSR | S_IWUSR);
  +module_param_named(restrict_dma_mask, vmw_restrict_dma_mask, int, 0600);

I suppose it's to late to fix this exact commit (50f837371dd9) now 
because it's part of the request-pull mail sent 2017-03-31 16:32:55 
-0700. I can send a new patch created on top of commit 28c954299cd2 
("drm/vmwgfx: Properly check display/scanout surface size") that 
completes this patch, if it's ok.

Regards,
Øyvind

+-| Øyvind A. Holm <sunny@sunbase.org> - N 60.37604° E 5.33339° |-+
| OpenPGP: 0xFB0CBEE894A506E5 - http://www.sunbase.org/pubkey.asc |
| Fingerprint: A006 05D6 E676 B319 55E2  E77E FB0C BEE8 94A5 06E5 |
+------------| 32db7b80-176e-11e7-8de9-db5caa6d21d3 |-------------+

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 181 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

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

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 4/9] drm/vmwgfx: Revert "drm/vmwgfx: Replace numeric parameter like 0444 with macro"
  2017-04-02  6:54   ` Øyvind A. Holm
@ 2017-04-03 16:39     ` Sinclair Yeh
  2017-04-03 20:06       ` [PATCH] drm/vmwgfx: Convert macro to octal representation Øyvind A. Holm
  0 siblings, 1 reply; 13+ messages in thread
From: Sinclair Yeh @ 2017-04-03 16:39 UTC (permalink / raw)
  To: Øyvind A. Holm; +Cc: thellstrom, dri-devel

On Sun, Apr 02, 2017 at 08:54:14AM +0200, Øyvind A. Holm wrote:
> On 2017-03-27 15:17:54, Sinclair Yeh wrote:
> > From: Øyvind A. Holm <sunny@sunbase.org>
> >
> > This reverts commit 2d8e60e8b074 ("drm/vmwgfx: Replace numeric
> > parameter like 0444 with macro")
> > [...]
> > index 45d711e..d31dc34 100644
> > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
> > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
> > @@ -241,13 +241,13 @@ static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val,
> >  			      void *ptr);
> >
> >  MODULE_PARM_DESC(enable_fbdev, "Enable vmwgfx fbdev");
> > -module_param_named(enable_fbdev, enable_fbdev, int, S_IRUSR | S_IWUSR);
> > +module_param_named(enable_fbdev, enable_fbdev, int, 0600);
> >  MODULE_PARM_DESC(force_dma_api, "Force using the DMA API for TTM pages");
> > -module_param_named(force_dma_api, vmw_force_iommu, int, S_IRUSR | S_IWUSR);
> > +module_param_named(force_dma_api, vmw_force_iommu, int, 0600);
> >  MODULE_PARM_DESC(restrict_iommu, "Try to limit IOMMU usage for TTM pages");
> > -module_param_named(restrict_iommu, vmw_restrict_iommu, int, S_IRUSR | S_IWUSR);
> > +module_param_named(restrict_iommu, vmw_restrict_iommu, int, 0600);
> >  MODULE_PARM_DESC(force_coherent, "Force coherent TTM pages");
> > -module_param_named(force_coherent, vmw_force_coherent, int, S_IRUSR | S_IWUSR);
> > +module_param_named(force_coherent, vmw_force_coherent, int, 0600);
> >  MODULE_PARM_DESC(restrict_dma_mask, "Restrict DMA mask to 44 bits with IOMMU");
> >  module_param_named(restrict_dma_mask, vmw_restrict_dma_mask, int, S_IRUSR | S_IWUSR);
> >  MODULE_PARM_DESC(assume_16bpp, "Assume 16-bpp when filtering modes");
> > --
> > 2.7.4
> 
> It seems as something has happened to the patch when applied, the last 
> change is gone, it was in my original patch sent to the list. This 
> change is missing:
> 
>   -module_param_named(restrict_dma_mask, vmw_restrict_dma_mask, int, S_IRUSR | S_IWUSR);
>   +module_param_named(restrict_dma_mask, vmw_restrict_dma_mask, int, 0600);

Hmm... I'll put this as a new patch then.

thanks for letting me know!

Sinclair

> 
> I suppose it's to late to fix this exact commit (50f837371dd9) now 
> because it's part of the request-pull mail sent 2017-03-31 16:32:55 
> -0700. I can send a new patch created on top of commit 28c954299cd2 
> ("drm/vmwgfx: Properly check display/scanout surface size") that 
> completes this patch, if it's ok.
> 
> Regards,
> Øyvind
> 
> +-| Øyvind A. Holm <sunny@sunbase.org> - N 60.37604° E 5.33339° |-+
> | OpenPGP: 0xFB0CBEE894A506E5 - http://www.sunbase.org/pubkey.asc |
> | Fingerprint: A006 05D6 E676 B319 55E2  E77E FB0C BEE8 94A5 06E5 |
> +------------| 32db7b80-176e-11e7-8de9-db5caa6d21d3 |-------------+


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

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH] drm/vmwgfx: Convert macro to octal representation
  2017-04-03 16:39     ` Sinclair Yeh
@ 2017-04-03 20:06       ` Øyvind A. Holm
  0 siblings, 0 replies; 13+ messages in thread
From: Øyvind A. Holm @ 2017-04-03 20:06 UTC (permalink / raw)
  To: Sinclair Yeh
  Cc: VMware Graphics, Thomas Hellstrom, David Airlie, dri-devel,
	linux-kernel, Øyvind A. Holm

Change "S_IRUSR | S_IWUSR" to "0600", it's easier to parse mentally.

This change should be part of commit 50f837371dd9 ("drm/vmwgfx: Revert
"drm/vmwgfx: Replace numeric parameter like 0444 with macro""), but the
patch was truncated somewhere in the patch route, so add the missing
change. Extract from the original commit message:

  commit 50f837371dd9aea5470c06d5d10bc9ca3e8155b6
  Author: Øyvind A. Holm <sunny@sunbase.org>
  Date:   Thu Mar 23 14:54:48 2017 -0700

    drm/vmwgfx: Revert "drm/vmwgfx: Replace numeric parameter like 0444
    with macro"

    This reverts commit 2d8e60e8b074 ("drm/vmwgfx: Replace numeric
    parameter like 0444 with macro")

    The commit belongs to the series of 1285 patches sent to LKML on
    2016-08-02, it changes the representation of file permissions from
    the octal value "0600" to "S_IRUSR | S_IWUSR".

    The general consensus was that the changes does not increase
    readability, quite the opposite; 0600 is easier to parse mentally
    than S_IRUSR | S_IWUSR.

Signed-off-by: Øyvind A. Holm <sunny@sunbase.org>
---

Hi Sinclair,
I created the patch to save you some work, if you haven't done it 
already. Thanks for your time.

Regards,
Øyvind

 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index f6e936d90517..4a641555b960 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -254,7 +254,7 @@ module_param_named(restrict_iommu, vmw_restrict_iommu, int, 0600);
 MODULE_PARM_DESC(force_coherent, "Force coherent TTM pages");
 module_param_named(force_coherent, vmw_force_coherent, int, 0600);
 MODULE_PARM_DESC(restrict_dma_mask, "Restrict DMA mask to 44 bits with IOMMU");
-module_param_named(restrict_dma_mask, vmw_restrict_dma_mask, int, S_IRUSR | S_IWUSR);
+module_param_named(restrict_dma_mask, vmw_restrict_dma_mask, int, 0600);
 MODULE_PARM_DESC(assume_16bpp, "Assume 16-bpp when filtering modes");
 module_param_named(assume_16bpp, vmw_assume_16bpp, int, 0600);
 
-- 
2.12.2.575.gb14f27f91770

^ permalink raw reply related	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2017-04-03 20:30 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-27 22:17 [0/9] Collection of patches queued up for vmwgfx-next Sinclair Yeh
2017-03-27 22:17 ` [PATCH 1/9] drm/vmwgfx: Explicityly track screen target width and height Sinclair Yeh
2017-03-27 22:17 ` [PATCH 2/9] drm/vmwgfx: Skipping fbdev fb pinning for ldu Sinclair Yeh
2017-03-27 22:17 ` [PATCH 3/9] drm/vmwgfx: Fix LDU X blank screen until mode change issue Sinclair Yeh
2017-03-27 22:17 ` [PATCH 4/9] drm/vmwgfx: Revert "drm/vmwgfx: Replace numeric parameter like 0444 with macro" Sinclair Yeh
2017-04-02  6:54   ` Øyvind A. Holm
2017-04-03 16:39     ` Sinclair Yeh
2017-04-03 20:06       ` [PATCH] drm/vmwgfx: Convert macro to octal representation Øyvind A. Holm
2017-03-27 22:17 ` [PATCH 5/9] drm/vmwgfx: Introduce a simple resource type Sinclair Yeh
2017-03-27 22:17 ` [PATCH 6/9] drm/vmwgfx: Re-implement the stream resource as a simple resource Sinclair Yeh
2017-03-27 22:17 ` [PATCH 7/9] drm/vmwgfx: Define an overlaid handle_close ioctl Sinclair Yeh
2017-03-27 22:17 ` [PATCH 8/9] drm/vmwgfx: Support topology greater than texture size Sinclair Yeh
2017-03-27 22:17 ` [PATCH 9/9] drm/vmwgfx: Properly check display/scanout surface size Sinclair Yeh

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.