[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