[PATCH 4/5] vmwgfx: Infrastructure for explicit placement

Thomas Hellstrom thellstrom at vmware.com
Wed Nov 2 01:43:11 PDT 2011


Make it possible to use explicit placement
(although not hooked up with a user-space interface yet)
and relax the single framebuffer limit to only apply to implicit placement.

Signed-off-by: Thomas Hellstrom <thellstrom at vmware.com>
Reviewed-by: Jakob Bornecrantz <jakob at vmware.com>
---
 drivers/gpu/drm/vmwgfx/vmwgfx_kms.h  |    1 +
 drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c  |    1 +
 drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c |   52 ++++++++++++++++++---------------
 3 files changed, 30 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
index 815cf99..af8e6e5 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
@@ -102,6 +102,7 @@ struct vmw_display_unit {
 	 */
 	int gui_x;
 	int gui_y;
+	bool is_implicit;
 };
 
 #define vmw_crtc_to_du(x) \
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
index bbfe381..90c5e39 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
@@ -337,6 +337,7 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
 	ldu->base.pref_width = 800;
 	ldu->base.pref_height = 600;
 	ldu->base.pref_mode = NULL;
+	ldu->base.is_implicit = true;
 
 	drm_connector_init(dev, connector, &vmw_legacy_connector_funcs,
 			   DRM_MODE_CONNECTOR_VIRTUAL);
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
index ea65834..4defdcf 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
@@ -36,9 +36,9 @@
 	container_of(x, struct vmw_screen_object_unit, base.connector)
 
 struct vmw_screen_object_display {
-	unsigned num_active;
+	unsigned num_implicit;
 
-	struct vmw_framebuffer *fb;
+	struct vmw_framebuffer *implicit_fb;
 };
 
 /**
@@ -51,7 +51,7 @@ struct vmw_screen_object_unit {
 	struct vmw_dma_buffer *buffer; /**< Backing store buffer */
 
 	bool defined;
-	bool active;
+	bool active_implicit;
 };
 
 static void vmw_sou_destroy(struct vmw_screen_object_unit *sou)
@@ -75,10 +75,10 @@ static void vmw_sou_del_active(struct vmw_private *vmw_priv,
 {
 	struct vmw_screen_object_display *ld = vmw_priv->sou_priv;
 
-	if (sou->active) {
-		if (--(ld->num_active) == 0)
-			ld->fb = NULL;
-		sou->active = false;
+	if (sou->active_implicit) {
+		if (--(ld->num_implicit) == 0)
+			ld->implicit_fb = NULL;
+		sou->active_implicit = false;
 	}
 }
 
@@ -88,12 +88,12 @@ static void vmw_sou_add_active(struct vmw_private *vmw_priv,
 {
 	struct vmw_screen_object_display *ld = vmw_priv->sou_priv;
 
-	BUG_ON(!ld->num_active && ld->fb);
+	BUG_ON(!ld->num_implicit && ld->implicit_fb);
 
-	if (!sou->active) {
-		ld->fb = vfb;
-		sou->active = true;
-		ld->num_active++;
+	if (!sou->active_implicit && sou->base.is_implicit) {
+		ld->implicit_fb = vfb;
+		sou->active_implicit = true;
+		ld->num_implicit++;
 	}
 }
 
@@ -132,8 +132,13 @@ static int vmw_sou_fifo_create(struct vmw_private *dev_priv,
 		(sou->base.unit == 0 ? SVGA_SCREEN_IS_PRIMARY : 0);
 	cmd->obj.size.width = mode->hdisplay;
 	cmd->obj.size.height = mode->vdisplay;
-	cmd->obj.root.x = x;
-	cmd->obj.root.y = y;
+	if (sou->base.is_implicit) {
+		cmd->obj.root.x = x;
+		cmd->obj.root.y = y;
+	} else {
+		cmd->obj.root.x = sou->base.gui_x;
+		cmd->obj.root.y = sou->base.gui_y;
+	}
 
 	/* Ok to assume that buffer is pinned in vram */
 	vmw_bo_get_guest_ptr(&sou->buffer->base, &cmd->obj.backingStore.ptr);
@@ -280,10 +285,11 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set)
 	}
 
 	/* sou only supports one fb active at the time */
-	if (dev_priv->sou_priv->fb && vfb &&
-	    !(dev_priv->sou_priv->num_active == 1 &&
-	      sou->active) &&
-	    dev_priv->sou_priv->fb != vfb) {
+	if (sou->base.is_implicit &&
+	    dev_priv->sou_priv->implicit_fb && vfb &&
+	    !(dev_priv->sou_priv->num_implicit == 1 &&
+	      sou->active_implicit) &&
+	    dev_priv->sou_priv->implicit_fb != vfb) {
 		DRM_ERROR("Multiple framebuffers not supported\n");
 		return -EINVAL;
 	}
@@ -439,12 +445,13 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit)
 	encoder = &sou->base.encoder;
 	connector = &sou->base.connector;
 
-	sou->active = false;
+	sou->active_implicit = false;
 
 	sou->base.pref_active = (unit == 0);
 	sou->base.pref_width = 800;
 	sou->base.pref_height = 600;
 	sou->base.pref_mode = NULL;
+	sou->base.is_implicit = true;
 
 	drm_connector_init(dev, connector, &vmw_legacy_connector_funcs,
 			   DRM_MODE_CONNECTOR_VIRTUAL);
@@ -488,8 +495,8 @@ int vmw_kms_init_screen_object_display(struct vmw_private *dev_priv)
 	if (unlikely(!dev_priv->sou_priv))
 		goto err_no_mem;
 
-	dev_priv->sou_priv->num_active = 0;
-	dev_priv->sou_priv->fb = NULL;
+	dev_priv->sou_priv->num_implicit = 0;
+	dev_priv->sou_priv->implicit_fb = NULL;
 
 	ret = drm_vblank_init(dev, VMWGFX_NUM_DISPLAY_UNITS);
 	if (unlikely(ret != 0))
@@ -524,9 +531,6 @@ int vmw_kms_close_screen_object_display(struct vmw_private *dev_priv)
 
 	drm_vblank_cleanup(dev);
 
-	if (dev_priv->sou_priv->num_active > 0)
-		DRM_ERROR("Still have active outputs when unloading driver");
-
 	kfree(dev_priv->sou_priv);
 
 	return 0;
-- 
1.7.4.4



More information about the dri-devel mailing list