I have copied the changes from intel (to radeon) regarding
DRI2GetBuffersWithFormat. Patches for the ddx and mesa are attached. It
requires the xserver patch here
http://lists.x.org/archives/xorg-devel/2009-April/000779.html, as otherwise
I am getting white borders with compiz.
Together with the previous patches I sent, they should make radeon and dri2
work with master xserver. My test (compiz and glxgears) with new mesa, ddx,
but old xserver and dri2proto seemed to work fine as well (with the
exception of openarena locking up, but that was also happening with an older
server and none of my patches).
It needs 2 commits from master than radeon-rewrite doesn't have:
532716049249b4b8905ead7127c9aa2bcfc3f67e
7a95e4dd7d8377c964fe2ea79acb93fe612d8d0f
On Sat, Apr 25, 2009 at 11:48 AM, Joel Bosveld <joel.bosv...@gmail.com>wrote:
> This fixes rendering when using dri2 (so, that means, radeon-rewrite and
> radeon-gem-cs) and a near-master xserver (the front-buffer changes). It is
> mostly just copied from the changes to intel.
>
> One patch is for mesa, and the other for the ddx:
>
> From 9e028a11b69361f82a3d578a2a3c14b3d7fc15fd Mon Sep 17 00:00:00 2001
> From: Joel Bosveld <joel.bosv...@gmail.com>
> Date: Sat, 25 Apr 2009 08:20:03 +0800
> Subject: [PATCH] radeon: fix front-buffer rendering
>
> ---
> src/mesa/drivers/dri/radeon/radeon_common.c | 27
> ++++++++++++++++++++
> .../drivers/dri/radeon/radeon_common_context.c | 4 +++
> .../drivers/dri/radeon/radeon_common_context.h | 16 +++++++++++
> 3 files changed, 47 insertions(+), 0 deletions(-)
>
> diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c
> b/src/mesa/drivers/dri/radeon/radeon_common.c
> index dc281ee..9e5ea9d 100644
> --- a/src/mesa/drivers/dri/radeon/radeon_common.c
> +++ b/src/mesa/drivers/dri/radeon/radeon_common.c
> @@ -677,6 +677,7 @@ void radeon_draw_buffer(GLcontext *ctx, struct
> gl_framebuffer *fb)
> if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) {
> rrbColor =
> radeon_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
> radeon->front_cliprects = GL_TRUE;
> + radeon->front_buffer_dirty = GL_TRUE;
> } else {
> rrbColor =
> radeon_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
> radeon->front_cliprects = GL_FALSE;
> @@ -792,6 +793,12 @@ void radeonDrawBuffer( GLcontext *ctx, GLenum mode )
> if (RADEON_DEBUG & DEBUG_DRI)
> fprintf(stderr, "%s %s\n", __FUNCTION__,
> _mesa_lookup_enum_by_nr( mode ));
> +
> + if (ctx->DrawBuffer->Name == 0) {
> + radeonContextPtr radeon = RADEON_CONTEXT(ctx);
> +
> + radeon->is_front_buffer_rendering = (mode == GL_FRONT_LEFT);
> + }
>
> radeon_draw_buffer(ctx, ctx->DrawBuffer);
> }
> @@ -1005,6 +1012,26 @@ void radeonFlush(GLcontext *ctx)
>
> if (radeon->cmdbuf.cs->cdw)
> rcommonFlushCmdBuf(radeon, __FUNCTION__);
> +
> + if ((ctx->DrawBuffer->Name == 0) && radeon->front_buffer_dirty) {
> + __DRIscreen *const screen = radeon->radeonScreen->driScreen;
> +
> + if (screen->dri2.loader && (screen->dri2.loader->base.version >=
> 2)
> + && (screen->dri2.loader->flushFrontBuffer != NULL)) {
> + (*screen->dri2.loader->flushFrontBuffer)(radeon->dri.drawable,
> + radeon->dri.drawable->loaderPrivate);
> +
> + /* Only clear the dirty bit if front-buffer rendering is no
> longer
> + * enabled. This is done so that the dirty bit can only be
> set in
> + * glDrawBuffer. Otherwise the dirty bit would have to be set
> at
> + * each of N places that do rendering. This has worse
> performances,
> + * but it is much easier to get correct.
> + */
> + if (radeon->is_front_buffer_rendering) {
> + radeon->front_buffer_dirty = GL_FALSE;
> + }
> + }
> + }
> }
>
> /* Make sure all commands have been sent to the hardware and have
> diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.c
> b/src/mesa/drivers/dri/radeon/radeon_common_context.c
> index ba74c97..cfdf52c 100644
> --- a/src/mesa/drivers/dri/radeon/radeon_common_context.c
> +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.c
> @@ -464,6 +464,10 @@ radeon_update_renderbuffers(__DRIcontext *context,
> __DRIdrawable *drawable)
> rb = draw->color_rb[0];
> regname = "dri2 front buffer";
> break;
> + case __DRI_BUFFER_FAKE_FRONT_LEFT:
> + rb = draw->color_rb[0];
> + regname = "dri2 fake front buffer";
> + break;
> case __DRI_BUFFER_BACK_LEFT:
> rb = draw->color_rb[1];
> regname = "dri2 back buffer";
> diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h
> b/src/mesa/drivers/dri/radeon/radeon_common_context.h
> index d32e5af..0307c63 100644
> --- a/src/mesa/drivers/dri/radeon/radeon_common_context.h
> +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h
> @@ -462,6 +462,22 @@ struct radeon_context {
> GLboolean constant_cliprect; /* use for FBO or DRI2 rendering */
> GLboolean front_cliprects;
>
> + /**
> + * Set if rendering has occured to the drawable's front buffer.
> + *
> + * This is used in the DRI2 case to detect that glFlush should also
> copy
> + * the contents of the fake front buffer to the real front buffer.
> + */
> + GLboolean front_buffer_dirty;
> +
> + /**
> + * Track whether front-buffer rendering is currently enabled
> + *
> + * A separate flag is used to track this in order to support MRT more
> + * easily.
> + */
> + GLboolean is_front_buffer_rendering;
> +
> struct {
> struct gl_fragment_program *bitmap_fp;
> struct gl_vertex_program *passthrough_vp;
> --
> 1.6.0.3
>
>
>
> --------
>
> From 10ecf4e4bb3bb70938f3e414a16280e6835c0af2 Mon Sep 17 00:00:00 2001
> From: Joel Bosveld <joel.bosv...@gmail.com>
> Date: Sat, 25 Apr 2009 10:53:59 +0800
> Subject: [PATCH] radeon: fix front-buffer rendering
>
> ---
> src/radeon_dri2.c | 15 +++++++++++----
> 1 files changed, 11 insertions(+), 4 deletions(-)
>
> diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
> index eb15ff2..1497454 100644
> --- a/src/radeon_dri2.c
> +++ b/src/radeon_dri2.c
> @@ -42,6 +42,7 @@
>
> struct dri2_buffer_priv {
> PixmapPtr pixmap;
> + unsigned int attachment;
> };
>
>
> @@ -105,6 +106,7 @@ radeon_dri2_create_buffers(DrawablePtr drawable,
> buffers[i].driverPrivate = &privates[i];
> buffers[i].flags = 0; /* not tiled */
> privates[i].pixmap = pixmap;
> + privates[i].attachment = attachments[i];
> }
> return buffers;
> }
> @@ -134,10 +136,15 @@ radeon_dri2_copy_region(DrawablePtr drawable,
> DRI2BufferPtr dest_buffer,
> DRI2BufferPtr src_buffer)
> {
> - struct dri2_buffer_priv *private = src_buffer->driverPrivate;
> + struct dri2_buffer_priv *srcPrivate = src_buffer->driverPrivate;
> + struct dri2_buffer_priv *dstPrivate = dest_buffer->driverPrivate;
> ScreenPtr pScreen = drawable->pScreen;
> ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
> - PixmapPtr pixmap = private->pixmap;
> + PixmapPtr pSrcPixmap = (srcPrivate->attachment == DRI2BufferFrontLeft)
> + ? (PixmapPtr) drawable : srcPrivate->pixmap;
> + PixmapPtr pDstPixmap = (dstPrivate->attachment == DRI2BufferFrontLeft)
> + ? (PixmapPtr) drawable : dstPrivate->pixmap;
> +
> RegionPtr copy_clip;
> GCPtr gc;
>
> @@ -145,8 +152,8 @@ radeon_dri2_copy_region(DrawablePtr drawable,
> copy_clip = REGION_CREATE(pScreen, NULL, 0);
> REGION_COPY(pScreen, copy_clip, region);
> (*gc->funcs->ChangeClip) (gc, CT_REGION, copy_clip, 0);
> - ValidateGC(drawable, gc);
> - (*gc->ops->CopyArea)(&pixmap->drawable, drawable, gc,
> + ValidateGC(&pDstPixmap->drawable, gc);
> + (*gc->ops->CopyArea)(&pSrcPixmap->drawable, &pDstPixmap->drawable, gc,
> 0, 0, drawable->width, drawable->height, 0, 0);
> FreeScratchGC(gc);
> RADEONCPReleaseIndirect(pScrn);
> --
> 1.6.0.3
>
>
From 59c48c570bce54afbe4ce1ce5145eb538c6b3dfa Mon Sep 17 00:00:00 2001
From: Joel Bosveld <joel.bosv...@gmail.com>
Date: Fri, 1 May 2009 00:13:45 +0800
Subject: [PATCH] radeon: If the SDK supports it, use the DRI2GetBuffersWithFormat interfaces
---
src/radeon_dri2.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 121 insertions(+), 1 deletions(-)
diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c
index 1497454..04936e9 100644
--- a/src/radeon_dri2.c
+++ b/src/radeon_dri2.c
@@ -38,6 +38,16 @@
#include "radeon_dri2.h"
#include "radeon_version.h"
+#include "dri2.h"
+
+#ifdef DRI2
+#if DRI2INFOREC_VERSION >= 1
+#define USE_DRI2_1_1_0
+#endif
+
+extern XF86ModuleData dri2ModuleData;
+#endif
+
#ifdef DRI2
struct dri2_buffer_priv {
@@ -45,6 +55,7 @@ struct dri2_buffer_priv {
unsigned int attachment;
};
+#ifndef USE_DRI2_1_1_0
static DRI2BufferPtr
radeon_dri2_create_buffers(DrawablePtr drawable,
@@ -111,6 +122,70 @@ radeon_dri2_create_buffers(DrawablePtr drawable,
return buffers;
}
+#else
+
+static DRI2BufferPtr
+radeon_dri2_create_buffer(DrawablePtr drawable,
+ unsigned int attachment,
+ unsigned int format)
+{
+ ScreenPtr pScreen = drawable->pScreen;
+ DRI2BufferPtr buffers;
+ struct dri2_buffer_priv *privates;
+ PixmapPtr pixmap;
+ struct radeon_exa_pixmap_priv *driver_priv;
+ int r;
+
+ buffers = xcalloc(1, sizeof *buffers);
+ if (buffers == NULL) {
+ return NULL;
+ }
+ privates = xcalloc(1, sizeof(struct dri2_buffer_priv));
+ if (privates == NULL) {
+ xfree(buffers);
+ return NULL;
+ }
+
+ if (attachment == DRI2BufferFrontLeft) {
+ if (drawable->type == DRAWABLE_PIXMAP) {
+ pixmap = (Pixmap*)drawable;
+ } else {
+ pixmap = (*pScreen->GetWindowPixmap)((WindowPtr)drawable);
+ }
+ pixmap->refcnt++;
+ } else {
+ pixmap = (*pScreen->CreatePixmap)(pScreen,
+ drawable->width,
+ drawable->height,
+ (format != 0)?format:drawable->depth,
+ 0);
+ }
+
+ driver_priv = exaGetPixmapDriverPrivate(pixmap);
+ r = radeon_bo_gem_name_buffer(driver_priv->bo, &buffers->name);
+ if (r) {
+ /* FIXME: cleanup */
+ fprintf(stderr, "flink error: %d %s\n", r, strerror(r));
+ xfree(buffers);
+ xfree(privates);
+ return NULL;
+ }
+ buffers->attachment = attachment;
+ buffers->pitch = pixmap->devKind;
+ buffers->cpp = pixmap->drawable.bitsPerPixel / 8;
+ buffers->driverPrivate = privates;
+ buffers->format = format;
+ buffers->flags = 0; /* not tiled */
+ privates->pixmap = pixmap;
+ privates->attachment = attachment;
+
+ return buffers;
+}
+
+#endif
+
+#ifndef USE_DRI2_1_1_0
+
static void
radeon_dri2_destroy_buffers(DrawablePtr drawable,
DRI2BufferPtr buffers,
@@ -130,6 +205,25 @@ radeon_dri2_destroy_buffers(DrawablePtr drawable,
}
}
+#else
+
+static void
+radeon_dri2_destroy_buffer(DrawablePtr drawable,
+ DRI2BufferPtr buffer)
+{
+ if(buffer) {
+ struct dri2_buffer_priv *private = buffer->driverPrivate;
+ ScreenPtr pScreen = drawable->pScreen;
+
+ (*pScreen->DestroyPixmap)(private->pixmap);
+
+ xfree(private);
+ xfree(buffer);
+ }
+}
+
+#endif
+
static void
radeon_dri2_copy_region(DrawablePtr drawable,
RegionPtr region,
@@ -170,12 +264,28 @@ radeon_dri2_screen_init(ScreenPtr pScreen)
char *tmp_bus_id;
int cmp;
int i;
+#ifdef USE_DRI2_1_1_0
+ int dri2_major = 1;
+ int dri2_minor = 0;
+#endif
if (!info->useEXA) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "DRI2 requires EXA\n");
return FALSE;
}
+#ifdef USE_DRI2_1_1_0
+ if (xf86LoaderCheckSymbol("DRI2Version")) {
+ DRI2Version(& dri2_major, & dri2_minor);
+ }
+
+ if (dri2_minor < 1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "DRI2 requires DRI2 module version 1.1.0 or later\n");
+ return FALSE;
+ }
+#endif
+
/* The whole drmOpen thing is a fiasco and we need to find a way
* back to just using open(2). For now, however, lets just make
* things worse with even more ad hoc directory walking code to
@@ -214,9 +324,19 @@ radeon_dri2_screen_init(ScreenPtr pScreen)
}
dri2_info.fd = info->dri2.drm_fd;
dri2_info.deviceName = info->dri2.device_name;
- dri2_info.version = 1;
+
+#ifdef USE_DRI2_1_1_0
+ dri2_info.version = 2;
+ dri2_info.CreateBuffers = NULL;
+ dri2_info.DestroyBuffers = NULL;
+ dri2_info.CreateBuffer = radeon_dri2_create_buffer;
+ dri2_info.DestroyBuffer = radeon_dri2_destroy_buffer;
+#else
+ dri2_info.version = 1;
dri2_info.CreateBuffers = radeon_dri2_create_buffers;
dri2_info.DestroyBuffers = radeon_dri2_destroy_buffers;
+#endif
+
dri2_info.CopyRegion = radeon_dri2_copy_region;
info->dri2.enabled = DRI2ScreenInit(pScreen, &dri2_info);
return info->dri2.enabled;
--
1.6.0.3
From 7d7acff9cf50850118046c21a19f0ee59e4fb774 Mon Sep 17 00:00:00 2001
From: Joel Bosveld <joel.bosv...@gmail.com>
Date: Thu, 30 Apr 2009 23:34:40 +0800
Subject: [PATCH] radeon / DRI2: When available, use DRI2GetBuffersWithFormat
---
src/mesa/drivers/dri/radeon/radeon_common.c | 11 ++
.../drivers/dri/radeon/radeon_common_context.c | 111 +++++++++++++++++---
2 files changed, 106 insertions(+), 16 deletions(-)
diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c
index 326c584..0ca5006 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common.c
+++ b/src/mesa/drivers/dri/radeon/radeon_common.c
@@ -797,7 +797,18 @@ void radeonDrawBuffer( GLcontext *ctx, GLenum mode )
if (ctx->DrawBuffer->Name == 0) {
radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+ const GLboolean was_front_buffer_rendering =
+ radeon->is_front_buffer_rendering;
+
radeon->is_front_buffer_rendering = (mode == GL_FRONT_LEFT);
+
+ /* If we weren't front-buffer rendering before but we are now, make sure
+ * that the front-buffer has actually been allocated.
+ */
+ if (!was_front_buffer_rendering && radeon->is_front_buffer_rendering) {
+ radeon_update_renderbuffers(radeon->dri.context,
+ radeon->dri.context->driDrawablePriv);
+ }
}
radeon_draw_buffer(ctx, ctx->DrawBuffer);
diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.c b/src/mesa/drivers/dri/radeon/radeon_common_context.c
index cfdf52c..d4c6555 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common_context.c
+++ b/src/mesa/drivers/dri/radeon/radeon_common_context.c
@@ -404,6 +404,23 @@ radeon_make_renderbuffer_current(radeonContextPtr radeon,
}
}
+static unsigned
+radeon_bits_per_pixel(const struct radeon_renderbuffer *rb)
+{
+ switch (rb->base._ActualFormat) {
+ case GL_RGB5:
+ case GL_DEPTH_COMPONENT16:
+ return 16;
+ case GL_RGB8:
+ case GL_RGBA8:
+ case GL_DEPTH_COMPONENT24:
+ case GL_DEPTH24_STENCIL8_EXT:
+ case GL_STENCIL_INDEX8_EXT:
+ return 32;
+ default:
+ return 0;
+ }
+}
void
radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
@@ -424,22 +441,63 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
draw = drawable->driverPrivate;
screen = context->driScreenPriv;
radeon = (radeonContextPtr) context->driverPrivate;
- i = 0;
- if (draw->color_rb[0])
- attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
- if (draw->color_rb[1])
- attachments[i++] = __DRI_BUFFER_BACK_LEFT;
- if (radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH))
- attachments[i++] = __DRI_BUFFER_DEPTH;
- if (radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL))
- attachments[i++] = __DRI_BUFFER_STENCIL;
+
+ if ((screen->dri2.loader->base.version > 2)
+ && (screen->dri2.loader->getBuffersWithFormat != NULL)) {
+ struct radeon_renderbuffer *depth_rb;
+ struct radeon_renderbuffer *stencil_rb;
+
+ i = 0;
+ if ((radeon->is_front_buffer_rendering || !draw->color_rb[1])
+ && draw->color_rb[0]) {
+ attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
+ attachments[i++] = radeon_bits_per_pixel(draw->color_rb[0]);
+ }
+
+ if (draw->color_rb[1]) {
+ attachments[i++] = __DRI_BUFFER_BACK_LEFT;
+ attachments[i++] = radeon_bits_per_pixel(draw->color_rb[1]);
+ }
+
+ depth_rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH);
+ stencil_rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL);
+
+ if ((depth_rb != NULL) && (stencil_rb != NULL)) {
+ attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
+ attachments[i++] = radeon_bits_per_pixel(depth_rb);
+ } else if (depth_rb != NULL) {
+ attachments[i++] = __DRI_BUFFER_DEPTH;
+ attachments[i++] = radeon_bits_per_pixel(depth_rb);
+ } else if (stencil_rb != NULL) {
+ attachments[i++] = __DRI_BUFFER_STENCIL;
+ attachments[i++] = radeon_bits_per_pixel(stencil_rb);
+ }
+
+ buffers = (*screen->dri2.loader->getBuffersWithFormat)(drawable,
+ &drawable->w,
+ &drawable->h,
+ attachments, i / 2,
+ &count,
+ drawable->loaderPrivate);
+ } else {
+ i = 0;
+ if (draw->color_rb[0])
+ attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
+ if (draw->color_rb[1])
+ attachments[i++] = __DRI_BUFFER_BACK_LEFT;
+ if (radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH))
+ attachments[i++] = __DRI_BUFFER_DEPTH;
+ if (radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL))
+ attachments[i++] = __DRI_BUFFER_STENCIL;
- buffers = (*screen->dri2.loader->getBuffers)(drawable,
- &drawable->w,
- &drawable->h,
- attachments, i,
- &count,
- drawable->loaderPrivate);
+ buffers = (*screen->dri2.loader->getBuffers)(drawable,
+ &drawable->w,
+ &drawable->h,
+ attachments, i,
+ &count,
+ drawable->loaderPrivate);
+ }
+
if (buffers == NULL)
return;
@@ -476,6 +534,10 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH);
regname = "dri2 depth buffer";
break;
+ case __DRI_BUFFER_DEPTH_STENCIL:
+ rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH);
+ regname = "dri2 depth / stencil buffer";
+ break;
case __DRI_BUFFER_STENCIL:
rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL);
regname = "dri2 stencil buffer";
@@ -537,7 +599,24 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
radeon_renderbuffer_set_bo(rb, bo);
radeon_bo_unref(bo);
-
+
+ if (buffers[i].attachment == __DRI_BUFFER_DEPTH_STENCIL) {
+ rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL);
+ if (rb != NULL) {
+ struct radeon_bo *stencil_bo = NULL;
+
+ if (rb->bo) {
+ uint32_t name = radeon_gem_name_bo(rb->bo);
+ if (name == buffers[i].name)
+ continue;
+ }
+
+ stencil_bo = bo;
+ radeon_bo_ref(stencil_bo);
+ radeon_renderbuffer_set_bo(rb, stencil_bo);
+ radeon_bo_unref(stencil_bo);
+ }
+ }
}
driUpdateFramebufferSize(radeon->glCtx, drawable);
--
1.6.0.3
------------------------------------------------------------------------------
Register Now & Save for Velocity, the Web Performance & Operations
Conference from O'Reilly Media. Velocity features a full day of
expert-led, hands-on workshops and two days of sessions from industry
leaders in dedicated Performance & Operations tracks. Use code vel09scf
and Save an extra 15% before 5/3. http://p.sf.net/sfu/velocityconf
--
_______________________________________________
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel