[Intel-gfx] [PATCH] uxa/glamor: Create glamor pixmap by default.

zhigang.gong at gmail.com zhigang.gong at gmail.com
Wed Jan 11 02:46:45 CET 2012


From: Zhigang Gong <zhigang.gong at linux.intel.com>

As create glamor pixmap by default will get much better performance
by using the textured-drm pixmap, this commit is to make that the
default behaviour when configure to use glamor.

A side effect is that for those glamor pixmaps, they don't have a
valid BO attached to it and thus it fails to get a DRI drawable. This
commit also fixes that problem by copy the fixup_shadow mechanism. I
tested this with mutter, and it seems work fine.

The performance gain to apply this patch is about 20% to 40% with
different workload.

Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>
---
 src/intel_dri.c |   76 +++++++++++++++++++++++++++++++++++++++++++++++++-----
 src/intel_uxa.c |    6 ++++
 2 files changed, 75 insertions(+), 7 deletions(-)

diff --git a/src/intel_dri.c b/src/intel_dri.c
index df3338f..c9444c9 100644
--- a/src/intel_dri.c
+++ b/src/intel_dri.c
@@ -66,6 +66,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #include "dri2.h"
 
+#include "intel_glamor.h"
+
 typedef struct {
 	int refcnt;
 	PixmapPtr pixmap;
@@ -125,6 +127,52 @@ static PixmapPtr get_front_buffer(DrawablePtr drawable)
 	return pixmap;
 }
 
+static PixmapPtr fixup_glamor(DrawablePtr drawable, PixmapPtr pixmap)
+{
+	ScreenPtr screen = drawable->pScreen;
+	PixmapPtr old = get_drawable_pixmap(drawable);
+	struct intel_pixmap *priv = intel_get_pixmap_private(pixmap);
+	GCPtr gc;
+
+	/* With a glamor pixmap, 2D pixmaps are created in texture
+	 * and without a static BO attached to it. To support DRI,
+	 * we need to create a new textured-drm pixmap and
+	 * need to copy the original content to this new textured-drm
+	 * pixmap, and then convert the old pixmap to a coherent
+	 * textured-drm pixmap which has a valid BO attached to it
+	 * and also has a valid texture, thus both glamor and DRI2
+	 * can access it.
+	 *
+	 */
+
+	/* Copy the current contents of the pixmap to the bo. */
+	gc = GetScratchGC(drawable->depth, screen);
+	if (gc) {
+		ValidateGC(&pixmap->drawable, gc);
+		gc->ops->CopyArea(drawable, &pixmap->drawable,
+				  gc,
+				  0, 0,
+				  drawable->width,
+				  drawable->height,
+				  0, 0);
+		FreeScratchGC(gc);
+	}
+
+	intel_set_pixmap_private(pixmap, NULL);
+	screen->DestroyPixmap(pixmap);
+
+	/* And redirect the pixmap to the new bo (for 3D). */
+	intel_set_pixmap_private(old, priv);
+	old->refcnt++;
+
+	if (!intel_glamor_create_textured_pixmap(old)) {
+		FatalError("Failed to get DRI drawable for glamor pixmap.\n");
+	}
+
+	intel_get_screen_private(xf86Screens[screen->myNum])->needs_flush = TRUE;
+	return old;
+}
+
 static PixmapPtr fixup_shadow(DrawablePtr drawable, PixmapPtr pixmap)
 {
 	ScreenPtr screen = drawable->pScreen;
@@ -203,6 +251,7 @@ I830DRI2CreateBuffers(DrawablePtr drawable, unsigned int *attachments,
 	I830DRI2BufferPrivatePtr privates;
 	PixmapPtr pixmap, pDepthPixmap;
 	int i;
+	int is_glamor_pixmap;
 
 	buffers = calloc(count, sizeof *buffers);
 	if (buffers == NULL)
@@ -222,7 +271,10 @@ I830DRI2CreateBuffers(DrawablePtr drawable, unsigned int *attachments,
 			pixmap = pDepthPixmap;
 			pixmap->refcnt++;
 		}
-		if (pixmap == NULL) {
+
+		is_glamor_pixmap = pixmap && (intel_get_pixmap_private(pixmap) == NULL);
+
+		if (pixmap == NULL || is_glamor_pixmap) {
 			unsigned int hint = INTEL_CREATE_PIXMAP_DRI2;
 
 			if (intel->tiling & INTEL_TILING_3D) {
@@ -255,8 +307,12 @@ I830DRI2CreateBuffers(DrawablePtr drawable, unsigned int *attachments,
 				goto unwind;
 			}
 
-			if (attachment == DRI2BufferFrontLeft)
-				pixmap = fixup_shadow(drawable, pixmap);
+			if (attachment == DRI2BufferFrontLeft) {
+				if (!is_glamor_pixmap)
+					pixmap = fixup_shadow(drawable, pixmap);
+				else
+					pixmap = fixup_glamor(drawable, pixmap);
+			}
 		}
 
 		if (attachments[i] == DRI2BufferDepth)
@@ -317,6 +373,7 @@ I830DRI2CreateBuffer(DrawablePtr drawable, unsigned int attachment,
 	DRI2Buffer2Ptr buffer;
 	I830DRI2BufferPrivatePtr privates;
 	PixmapPtr pixmap;
+	int is_glamor_pixmap;
 
 	buffer = calloc(1, sizeof *buffer);
 	if (buffer == NULL)
@@ -330,7 +387,9 @@ I830DRI2CreateBuffer(DrawablePtr drawable, unsigned int attachment,
 	pixmap = NULL;
 	if (attachment == DRI2BufferFrontLeft)
 		pixmap = get_front_buffer(drawable);
-	if (pixmap == NULL) {
+
+	is_glamor_pixmap = pixmap && (intel_get_pixmap_private(pixmap) == NULL);
+	if (pixmap == NULL || is_glamor_pixmap) {
 		unsigned int hint = INTEL_CREATE_PIXMAP_DRI2;
 		int pixmap_width = drawable->width;
 		int pixmap_height = drawable->height;
@@ -400,9 +459,12 @@ I830DRI2CreateBuffer(DrawablePtr drawable, unsigned int attachment,
 			free(buffer);
 			return NULL;
 		}
-
-		if (attachment == DRI2BufferFrontLeft)
-			pixmap = fixup_shadow(drawable, pixmap);
+		if (attachment == DRI2BufferFrontLeft) {
+			if (!is_glamor_pixmap)
+				pixmap = fixup_shadow(drawable, pixmap);
+			else
+				pixmap = fixup_glamor(drawable, pixmap);
+		}
 	}
 
 	buffer->attachment = attachment;
diff --git a/src/intel_uxa.c b/src/intel_uxa.c
index 9d74554..f04a2ef 100644
--- a/src/intel_uxa.c
+++ b/src/intel_uxa.c
@@ -1026,6 +1026,12 @@ intel_uxa_create_pixmap(ScreenPtr screen, int w, int h, int depth,
 	struct intel_pixmap *priv;
 	PixmapPtr pixmap, new_pixmap = NULL;
 
+	if (!(usage & INTEL_CREATE_PIXMAP_DRI2)) {
+		pixmap = intel_glamor_create_pixmap(screen, w, h, depth, usage);
+		if (pixmap)
+			return pixmap;
+	}
+
 	if (w > 32767 || h > 32767)
 		return NullPixmap;
 
-- 
1.7.4.4




More information about the Intel-gfx mailing list