summaryrefslogtreecommitdiff
path: root/dist
diff options
context:
space:
mode:
authorOwain Ainsworth <oga@cvs.openbsd.org>2009-08-06 15:50:03 +0000
committerOwain Ainsworth <oga@cvs.openbsd.org>2009-08-06 15:50:03 +0000
commit63e4a046e3f3b91d71d105db23a14ce674b33b2e (patch)
treeccccb12f9c52927270b8f26555cc04e79a22ff5d /dist
parent384ebc29841e4f83b776274dc52b1b617859106e (diff)
backport some code from mesa current (and 7.5) so that the dri2 protocol
is correctly handled. without fixes to mesa and the ddx, the so-called backwards compat goop that was added just plain does not work and ends up with rendering bullshit.
Diffstat (limited to 'dist')
-rw-r--r--dist/Mesa/include/GL/internal/dri_interface.h39
-rw-r--r--dist/Mesa/src/glx/x11/dri2.c70
-rw-r--r--dist/Mesa/src/glx/x11/dri2.h10
-rw-r--r--dist/Mesa/src/glx/x11/dri2_glx.c139
-rw-r--r--dist/Mesa/src/glx/x11/dri_common.c11
-rw-r--r--dist/Mesa/src/glx/x11/dri_glx.c79
-rw-r--r--dist/Mesa/src/glx/x11/drisw_glx.c4
-rw-r--r--dist/Mesa/src/glx/x11/glxclient.h4
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/intel/intel_buffers.c30
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/intel/intel_context.c179
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/intel/intel_context.h8
-rw-r--r--dist/Mesa/src/mesa/drivers/dri/intel/intel_span.c3
12 files changed, 506 insertions, 70 deletions
diff --git a/dist/Mesa/include/GL/internal/dri_interface.h b/dist/Mesa/include/GL/internal/dri_interface.h
index 09ae940f6..b4716e4b5 100644
--- a/dist/Mesa/include/GL/internal/dri_interface.h
+++ b/dist/Mesa/include/GL/internal/dri_interface.h
@@ -78,6 +78,7 @@ typedef struct __DRIswrastExtensionRec __DRIswrastExtension;
typedef struct __DRIbufferRec __DRIbuffer;
typedef struct __DRIdri2ExtensionRec __DRIdri2Extension;
typedef struct __DRIdri2LoaderExtensionRec __DRIdri2LoaderExtension;
+typedef struct __DRI2flushExtensionRec __DRI2flushExtension;
/*@}*/
@@ -245,6 +246,16 @@ struct __DRItexBufferExtensionRec {
__DRIdrawable *pDraw);
};
+/**
+ * Used by drivers that implement DRI2
+ */
+#define __DRI2_FLUSH "DRI2_Flush"
+#define __DRI2_FLUSH_VERSION 1
+struct __DRI2flushExtensionRec {
+ __DRIextension base;
+ void (*flush)(__DRIdrawable *drawable);
+};
+
/**
* XML document describing the configuration options supported by the
@@ -626,6 +637,7 @@ struct __DRIswrastExtensionRec {
#define __DRI_BUFFER_ACCUM 6
#define __DRI_BUFFER_FAKE_FRONT_LEFT 7
#define __DRI_BUFFER_FAKE_FRONT_RIGHT 8
+#define __DRI_BUFFER_DEPTH_STENCIL 9 /**< Only available with DRI2 1.1 */
struct __DRIbufferRec {
unsigned int attachment;
@@ -636,7 +648,7 @@ struct __DRIbufferRec {
};
#define __DRI_DRI2_LOADER "DRI_DRI2Loader"
-#define __DRI_DRI2_LOADER_VERSION 2
+#define __DRI_DRI2_LOADER_VERSION 3
struct __DRIdri2LoaderExtensionRec {
__DRIextension base;
@@ -657,6 +669,31 @@ struct __DRIdri2LoaderExtensionRec {
* into __DRIdri2ExtensionRec::createNewDrawable
*/
void (*flushFrontBuffer)(__DRIdrawable *driDrawable, void *loaderPrivate);
+
+
+ /**
+ * Get list of buffers from the server
+ *
+ * Gets a list of buffer for the specified set of attachments. Unlike
+ * \c ::getBuffers, this function takes a list of attachments paired with
+ * opaque \c unsigned \c int value describing the format of the buffer.
+ * It is the responsibility of the caller to know what the service that
+ * allocates the buffers will expect to receive for the format.
+ *
+ * \param driDrawable Drawable whose buffers are being queried.
+ * \param width Output where the width of the buffers is stored.
+ * \param height Output where the height of the buffers is stored.
+ * \param attachments List of pairs of attachment ID and opaque format
+ * requested for the drawable.
+ * \param count Number of attachment / format pairs stored in
+ * \c attachments.
+ * \param loaderPrivate Loader's private data that was previously passed
+ * into __DRIdri2ExtensionRec::createNewDrawable.
+ */
+ __DRIbuffer *(*getBuffersWithFormat)(__DRIdrawable *driDrawable,
+ int *width, int *height,
+ unsigned int *attachments, int count,
+ int *out_count, void *loaderPrivate);
};
/**
diff --git a/dist/Mesa/src/glx/x11/dri2.c b/dist/Mesa/src/glx/x11/dri2.c
index f967432b9..ebb298592 100644
--- a/dist/Mesa/src/glx/x11/dri2.c
+++ b/dist/Mesa/src/glx/x11/dri2.c
@@ -39,6 +39,16 @@
#include "xf86drm.h"
#include "dri2.h"
+/* Allow the build to work with an older versions of dri2proto.h and
+ * dri2tokens.h.
+ */
+#if DRI2_MINOR < 1
+#undef DRI2_MINOR
+#define DRI2_MINOR 1
+#define X_DRI2GetBuffersWithFormat 7
+#endif
+
+
static char dri2ExtensionName[] = DRI2_NAME;
static XExtensionInfo *dri2Info;
static XEXT_GENERATE_CLOSE_DISPLAY (DRI2CloseDisplay, dri2Info)
@@ -276,6 +286,66 @@ DRI2Buffer *DRI2GetBuffers(Display *dpy, XID drawable,
return buffers;
}
+
+DRI2Buffer *DRI2GetBuffersWithFormat(Display *dpy, XID drawable,
+ int *width, int *height,
+ unsigned int *attachments, int count,
+ int *outCount)
+{
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+ xDRI2GetBuffersReply rep;
+ xDRI2GetBuffersReq *req;
+ DRI2Buffer *buffers;
+ xDRI2Buffer repBuffer;
+ CARD32 *p;
+ int i;
+
+ XextCheckExtension (dpy, info, dri2ExtensionName, False);
+
+ LockDisplay(dpy);
+ GetReqExtra(DRI2GetBuffers, count * (4 * 2), req);
+ req->reqType = info->codes->major_opcode;
+ req->dri2ReqType = X_DRI2GetBuffersWithFormat;
+ req->drawable = drawable;
+ req->count = count;
+ p = (CARD32 *) &req[1];
+ for (i = 0; i < (count * 2); i++)
+ p[i] = attachments[i];
+
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return NULL;
+ }
+
+ *width = rep.width;
+ *height = rep.height;
+ *outCount = rep.count;
+
+ buffers = Xmalloc(rep.count * sizeof buffers[0]);
+ if (buffers == NULL) {
+ _XEatData(dpy, rep.count * sizeof repBuffer);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return NULL;
+ }
+
+ for (i = 0; i < rep.count; i++) {
+ _XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer);
+ buffers[i].attachment = repBuffer.attachment;
+ buffers[i].name = repBuffer.name;
+ buffers[i].pitch = repBuffer.pitch;
+ buffers[i].cpp = repBuffer.cpp;
+ buffers[i].flags = repBuffer.flags;
+ }
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return buffers;
+}
+
+
void DRI2CopyRegion(Display *dpy, XID drawable, XserverRegion region,
CARD32 dest, CARD32 src)
{
diff --git a/dist/Mesa/src/glx/x11/dri2.h b/dist/Mesa/src/glx/x11/dri2.h
index 356c6bcb5..b0e61f80d 100644
--- a/dist/Mesa/src/glx/x11/dri2.h
+++ b/dist/Mesa/src/glx/x11/dri2.h
@@ -63,6 +63,16 @@ DRI2GetBuffers(Display *dpy, XID drawable,
unsigned int *attachments, int count,
int *outCount);
+/**
+ * \note
+ * This function is only supported with DRI2 version 1.1 or later.
+ */
+extern DRI2Buffer *
+DRI2GetBuffersWithFormat(Display *dpy, XID drawable,
+ int *width, int *height,
+ unsigned int *attachments, int count,
+ int *outCount);
+
extern void
DRI2CopyRegion(Display *dpy, XID drawable, XserverRegion region,
CARD32 dest, CARD32 src);
diff --git a/dist/Mesa/src/glx/x11/dri2_glx.c b/dist/Mesa/src/glx/x11/dri2_glx.c
index c97f9816d..f4865aecb 100644
--- a/dist/Mesa/src/glx/x11/dri2_glx.c
+++ b/dist/Mesa/src/glx/x11/dri2_glx.c
@@ -47,6 +47,9 @@
#include "dri2.h"
#include "dri_common.h"
+#undef DRI2_MINOR
+#define DRI2_MINOR 1
+
typedef struct __GLXDRIdisplayPrivateRec __GLXDRIdisplayPrivate;
typedef struct __GLXDRIcontextPrivateRec __GLXDRIcontextPrivate;
typedef struct __GLXDRIdrawablePrivateRec __GLXDRIdrawablePrivate;
@@ -77,6 +80,8 @@ struct __GLXDRIdrawablePrivateRec {
int have_fake_front;
};
+static void dri2WaitX(__GLXDRIdrawable *pdraw);
+
static void dri2DestroyContext(__GLXDRIcontext *context,
__GLXscreenConfigs *psc, Display *dpy)
{
@@ -202,10 +207,21 @@ static void dri2CopySubBuffer(__GLXDRIdrawable *pdraw,
xrect.width = width;
xrect.height = height;
+#ifdef __DRI2_FLUSH
+ if (pdraw->psc->f)
+ (*pdraw->psc->f->flush)(pdraw->driDrawable);
+#endif
+
region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1);
+ /* should get a fence ID back from here at some point */
DRI2CopyRegion(pdraw->psc->dpy, pdraw->drawable, region,
DRI2BufferFrontLeft, DRI2BufferBackLeft);
XFixesDestroyRegion(pdraw->psc->dpy, region);
+
+ /* Refresh the fake front (if present) after we just damaged the real
+ * front.
+ */
+ dri2WaitX(pdraw);
}
static void dri2SwapBuffers(__GLXDRIdrawable *pdraw)
@@ -230,6 +246,11 @@ static void dri2WaitX(__GLXDRIdrawable *pdraw)
xrect.width = priv->width;
xrect.height = priv->height;
+#ifdef __DRI2_FLUSH
+ if (pdraw->psc->f)
+ (*pdraw->psc->f->flush)(pdraw->driDrawable);
+#endif
+
region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1);
DRI2CopyRegion(pdraw->psc->dpy, pdraw->drawable, region,
DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
@@ -250,6 +271,11 @@ static void dri2WaitGL(__GLXDRIdrawable *pdraw)
xrect.width = priv->width;
xrect.height = priv->height;
+#ifdef __DRI2_FLUSH
+ if (pdraw->psc->f)
+ (*pdraw->psc->f->flush)(pdraw->driDrawable);
+#endif
+
region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1);
DRI2CopyRegion(pdraw->psc->dpy, pdraw->drawable, region,
DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
@@ -273,30 +299,25 @@ static void dri2DestroyScreen(__GLXscreenConfigs *psc)
psc->__driScreen = NULL;
}
-static __DRIbuffer *
-dri2GetBuffers(__DRIdrawable *driDrawable,
- int *width, int *height,
- unsigned int *attachments, int count,
- int *out_count, void *loaderPrivate)
+/**
+ * Process list of buffer received from the server
+ *
+ * Processes the list of buffers received in a reply from the server to either
+ * \c DRI2GetBuffers or \c DRI2GetBuffersWithFormat.
+ */
+static void
+process_buffers(__GLXDRIdrawablePrivate *pdraw, DRI2Buffer *buffers,
+ unsigned count)
{
- __GLXDRIdrawablePrivate *pdraw = loaderPrivate;
- DRI2Buffer *buffers;
int i;
- buffers = DRI2GetBuffers(pdraw->base.psc->dpy, pdraw->base.xDrawable,
- width, height, attachments, count, out_count);
- if (buffers == NULL)
- return NULL;
-
- pdraw->width = *width;
- pdraw->height = *height;
- pdraw->bufferCount = *out_count;
+ pdraw->bufferCount = count;
pdraw->have_fake_front = 0;
pdraw->have_back = 0;
/* This assumes the DRI2 buffer attachment tokens matches the
* __DRIbuffer tokens. */
- for (i = 0; i < *out_count; i++) {
+ for (i = 0; i < count; i++) {
pdraw->buffers[i].attachment = buffers[i].attachment;
pdraw->buffers[i].name = buffers[i].name;
pdraw->buffers[i].pitch = buffers[i].pitch;
@@ -308,6 +329,51 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
pdraw->have_back = 1;
}
+}
+
+static __DRIbuffer *
+dri2GetBuffers(__DRIdrawable *driDrawable,
+ int *width, int *height,
+ unsigned int *attachments, int count,
+ int *out_count, void *loaderPrivate)
+{
+ __GLXDRIdrawablePrivate *pdraw = loaderPrivate;
+ DRI2Buffer *buffers;
+
+ buffers = DRI2GetBuffers(pdraw->base.psc->dpy, pdraw->base.xDrawable,
+ width, height, attachments, count, out_count);
+ if (buffers == NULL)
+ return NULL;
+
+ pdraw->width = *width;
+ pdraw->height = *height;
+ process_buffers(pdraw, buffers, *out_count);
+
+ Xfree(buffers);
+
+ return pdraw->buffers;
+}
+
+static __DRIbuffer *
+dri2GetBuffersWithFormat(__DRIdrawable *driDrawable,
+ int *width, int *height,
+ unsigned int *attachments, int count,
+ int *out_count, void *loaderPrivate)
+{
+ __GLXDRIdrawablePrivate *pdraw = loaderPrivate;
+ DRI2Buffer *buffers;
+
+ buffers = DRI2GetBuffersWithFormat(pdraw->base.psc->dpy,
+ pdraw->base.xDrawable,
+ width, height, attachments,
+ count, out_count);
+ if (buffers == NULL)
+ return NULL;
+
+ pdraw->width = *width;
+ pdraw->height = *height;
+ process_buffers(pdraw, buffers, *out_count);
+
Xfree(buffers);
return pdraw->buffers;
@@ -316,7 +382,15 @@ dri2GetBuffers(__DRIdrawable *driDrawable,
static const __DRIdri2LoaderExtension dri2LoaderExtension = {
{ __DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION },
dri2GetBuffers,
- dri2FlushFrontBuffer
+ dri2FlushFrontBuffer,
+ dri2GetBuffersWithFormat,
+};
+
+static const __DRIdri2LoaderExtension dri2LoaderExtension_old = {
+ { __DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION },
+ dri2GetBuffers,
+ dri2FlushFrontBuffer,
+ NULL,
};
static const __DRIextension *loader_extensions[] = {
@@ -325,11 +399,19 @@ static const __DRIextension *loader_extensions[] = {
NULL
};
+static const __DRIextension *loader_extensions_old[] = {
+ &dri2LoaderExtension_old.base,
+ &systemTimeExtension.base,
+ NULL
+};
+
static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen,
__GLXdisplayPrivate *priv)
{
const __DRIconfig **driver_configs;
const __DRIextension **extensions;
+ const __GLXDRIdisplayPrivate *const pdp = (__GLXDRIdisplayPrivate *)
+ priv->dri2Display;
__GLXDRIscreen *psp;
char *driverName, *deviceName;
drm_magic_t magic;
@@ -347,8 +429,10 @@ static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen,
return NULL;
psc->driver = driOpenDriver(driverName);
- if (psc->driver == NULL)
+ if (psc->driver == NULL) {
+ ErrorMessageF("driver pointer missing\n");
goto handle_error;
+ }
extensions = dlsym(psc->driver, __DRI_DRIVER_EXTENSIONS);
if (extensions == NULL) {
@@ -374,15 +458,26 @@ static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen,
return NULL;
}
- if (drmGetMagic(psc->fd, &magic))
+ if (drmGetMagic(psc->fd, &magic)) {
+ ErrorMessageF("failed to get magic\n");
return NULL;
+ }
- if (!DRI2Authenticate(psc->dpy, RootWindow(psc->dpy, screen), magic))
+ if (!DRI2Authenticate(psc->dpy, RootWindow(psc->dpy, screen), magic)) {
+ ErrorMessageF("failed to authenticate magic %d\n", magic);
return NULL;
+ }
+ /* If the server does not support the protocol for
+ * DRI2GetBuffersWithFormat, don't supply that interface to the driver.
+ */
psc->__driScreen =
- psc->dri2->createNewScreen(screen, psc->fd,
- loader_extensions, &driver_configs, psc);
+ psc->dri2->createNewScreen(screen, psc->fd,
+ ((pdp->driMinor < 1)
+ ? loader_extensions_old
+ : loader_extensions),
+ &driver_configs, psc);
+
if (psc->__driScreen == NULL) {
ErrorMessageF("failed to create dri screen\n");
return NULL;
diff --git a/dist/Mesa/src/glx/x11/dri_common.c b/dist/Mesa/src/glx/x11/dri_common.c
index 4fda649e5..6de411111 100644
--- a/dist/Mesa/src/glx/x11/dri_common.c
+++ b/dist/Mesa/src/glx/x11/dri_common.c
@@ -345,7 +345,9 @@ driBindExtensions(__GLXscreenConfigs *psc, int dri2)
#endif
#ifdef __DRI_SWAP_CONTROL
- if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0) {
+ /* No DRI2 support for swap_control at the moment, since SwapBuffers
+ * is done by the X server */
+ if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0 && !dri2) {
psc->swapControl = (__DRIswapControlExtension *) extensions[i];
__glXEnableDirectExtension(psc, "GLX_SGI_swap_control");
__glXEnableDirectExtension(psc, "GLX_MESA_swap_control");
@@ -392,6 +394,13 @@ driBindExtensions(__GLXscreenConfigs *psc, int dri2)
}
#endif
+#ifdef __DRI2_FLUSH
+ if ((strcmp(extensions[i]->name, __DRI2_FLUSH) == 0) && dri2) {
+ psc->f = (__DRI2flushExtension *) extensions[i];
+ /* internal driver extension, no GL extension exposed */
+ }
+#endif
+
/* Ignore unknown extensions */
}
}
diff --git a/dist/Mesa/src/glx/x11/dri_glx.c b/dist/Mesa/src/glx/x11/dri_glx.c
index 372d9d9fc..ac2eb0534 100644
--- a/dist/Mesa/src/glx/x11/dri_glx.c
+++ b/dist/Mesa/src/glx/x11/dri_glx.c
@@ -40,6 +40,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "glxclient.h"
#include "glcontextmodes.h"
#include "xf86dri.h"
+#include "dri2.h"
#include "sarea.h"
#include <dlfcn.h>
#include <sys/types.h>
@@ -75,32 +76,45 @@ struct __GLXDRIcontextPrivateRec {
*/
static Bool driGetDriverName(Display *dpy, int scrNum, char **driverName)
{
- int directCapable;
- Bool b;
- int driverMajor, driverMinor, driverPatch;
+ int directCapable;
+ Bool b;
+ int event, error;
+ int driverMajor, driverMinor, driverPatch;
- *driverName = NULL;
+ *driverName = NULL;
- if (!XF86DRIQueryDirectRenderingCapable(dpy, scrNum, &directCapable)) {
- ErrorMessageF("XF86DRIQueryDirectRenderingCapable failed\n");
- return False;
- }
- if (!directCapable) {
- ErrorMessageF("XF86DRIQueryDirectRenderingCapable returned false\n");
- return False;
- }
+ if (XF86DRIQueryExtension(dpy, &event, &error)) { /* DRI1 */
+ if (!XF86DRIQueryDirectRenderingCapable(dpy, scrNum, &directCapable)) {
+ ErrorMessageF("XF86DRIQueryDirectRenderingCapable failed\n");
+ return False;
+ }
+ if (!directCapable) {
+ ErrorMessageF("XF86DRIQueryDirectRenderingCapable returned false\n");
+ return False;
+ }
- b = XF86DRIGetClientDriverName(dpy, scrNum, &driverMajor, &driverMinor,
- &driverPatch, driverName);
- if (!b) {
- ErrorMessageF("Cannot determine driver name for screen %d\n", scrNum);
- return False;
- }
+ b = XF86DRIGetClientDriverName(dpy, scrNum, &driverMajor, &driverMinor,
+ &driverPatch, driverName);
+ if (!b) {
+ ErrorMessageF("Cannot determine driver name for screen %d\n", scrNum);
+ return False;
+ }
+
+ InfoMessageF("XF86DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n",
+ driverMajor, driverMinor, driverPatch, *driverName, scrNum);
- InfoMessageF("XF86DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n",
- driverMajor, driverMinor, driverPatch, *driverName, scrNum);
+ return True;
+ } else if (DRI2QueryExtension(dpy, &event, &error)) { /* DRI2 */
+ char *dev;
+ Bool ret = DRI2Connect(dpy, RootWindow(dpy, scrNum), driverName, &dev);
- return True;
+ if (ret)
+ Xfree(dev);
+
+ return ret;
+ }
+
+ return False;
}
/*
@@ -291,6 +305,7 @@ CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc,
drm_handle_t hFB;
int junk;
const __DRIconfig **driver_configs;
+ __GLcontextModes *visual;
/* DRI protocol version. */
dri_version.major = driDpy->driMajor;
@@ -403,6 +418,28 @@ CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc,
psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs);
psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs);
+ /* Visuals with depth != screen depth are subject to automatic compositing
+ * in the X server, so DRI1 can't render to them properly. Mark them as
+ * non-conformant to prevent apps from picking them up accidentally.
+ */
+ for (visual = psc->visuals; visual; visual = visual->next) {
+ XVisualInfo template;
+ XVisualInfo *visuals;
+ int num_visuals;
+ long mask;
+
+ template.visualid = visual->visualID;
+ mask = VisualIDMask;
+ visuals = XGetVisualInfo(dpy, mask, &template, &num_visuals);
+
+ if (visuals) {
+ if (num_visuals > 0 && visuals->depth != DefaultDepth(dpy, scrn))
+ visual->visualRating = GLX_NON_CONFORMANT_CONFIG;
+
+ XFree(visuals);
+ }
+ }
+
return psp;
handle_error:
diff --git a/dist/Mesa/src/glx/x11/drisw_glx.c b/dist/Mesa/src/glx/x11/drisw_glx.c
index 5e3d763cf..1c229dde9 100644
--- a/dist/Mesa/src/glx/x11/drisw_glx.c
+++ b/dist/Mesa/src/glx/x11/drisw_glx.c
@@ -401,10 +401,14 @@ driCreateScreen(__GLXscreenConfigs * psc, int screen,
psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs);
psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs);
+ free(driver_configs);
+
psp->destroyScreen = driDestroyScreen;
psp->createContext = driCreateContext;
psp->createDrawable = driCreateDrawable;
psp->swapBuffers = driSwapBuffers;
+ psp->waitX = NULL;
+ psp->waitGL = NULL;
return psp;
diff --git a/dist/Mesa/src/glx/x11/glxclient.h b/dist/Mesa/src/glx/x11/glxclient.h
index d03746d11..3c493b448 100644
--- a/dist/Mesa/src/glx/x11/glxclient.h
+++ b/dist/Mesa/src/glx/x11/glxclient.h
@@ -519,6 +519,10 @@ struct __GLXscreenConfigsRec {
const __DRItexBufferExtension *texBuffer;
#endif
+#ifdef __DRI2_FLUSH
+ const __DRI2flushExtension *f;
+#endif
+
#endif
/**
diff --git a/dist/Mesa/src/mesa/drivers/dri/intel/intel_buffers.c b/dist/Mesa/src/mesa/drivers/dri/intel/intel_buffers.c
index 1dc72980e..342edf711 100644
--- a/dist/Mesa/src/mesa/drivers/dri/intel/intel_buffers.c
+++ b/dist/Mesa/src/mesa/drivers/dri/intel/intel_buffers.c
@@ -332,8 +332,19 @@ intelDrawBuffer(GLcontext * ctx, GLenum mode)
{
if ((ctx->DrawBuffer != NULL) && (ctx->DrawBuffer->Name == 0)) {
struct intel_context *const intel = intel_context(ctx);
+ const GLboolean was_front_buffer_rendering =
+ intel->is_front_buffer_rendering;
- intel->is_front_buffer_rendering = (mode == GL_FRONT_LEFT);
+ intel->is_front_buffer_rendering = (mode == GL_FRONT_LEFT)
+ || (mode == GL_FRONT);
+
+ /* 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 && intel->is_front_buffer_rendering) {
+ intel_update_renderbuffers(intel->driContext,
+ intel->driContext->driDrawablePriv);
+ }
}
intel_draw_buffer(ctx, ctx->DrawBuffer);
@@ -343,6 +354,23 @@ intelDrawBuffer(GLcontext * ctx, GLenum mode)
static void
intelReadBuffer(GLcontext * ctx, GLenum mode)
{
+ if ((ctx->DrawBuffer != NULL) && (ctx->DrawBuffer->Name == 0)) {
+ struct intel_context *const intel = intel_context(ctx);
+ const GLboolean was_front_buffer_reading =
+ intel->is_front_buffer_reading;
+
+ intel->is_front_buffer_reading = (mode == GL_FRONT_LEFT)
+ || (mode == GL_FRONT);
+
+ /* If we weren't front-buffer reading before but we are now, make sure
+ * that the front-buffer has actually been allocated.
+ */
+ if (!was_front_buffer_reading && intel->is_front_buffer_reading) {
+ intel_update_renderbuffers(intel->driContext,
+ intel->driContext->driDrawablePriv);
+ }
+ }
+
if (ctx->ReadBuffer == ctx->DrawBuffer) {
/* This will update FBO completeness status.
* A framebuffer will be incomplete if the GL_READ_BUFFER setting
diff --git a/dist/Mesa/src/mesa/drivers/dri/intel/intel_context.c b/dist/Mesa/src/mesa/drivers/dri/intel/intel_context.c
index ecaf6b45b..90544d454 100644
--- a/dist/Mesa/src/mesa/drivers/dri/intel/intel_context.c
+++ b/dist/Mesa/src/mesa/drivers/dri/intel/intel_context.c
@@ -25,12 +25,12 @@
*
**************************************************************************/
-
#include "main/glheader.h"
#include "main/context.h"
#include "main/matrix.h"
#include "main/simple_list.h"
#include "main/extensions.h"
+#include "main/arrayobj.h"
#include "main/framebuffer.h"
#include "main/imports.h"
#include "main/points.h"
@@ -66,6 +66,7 @@
#include "vblank.h"
#include "utils.h"
#include "xmlpool.h" /* for symbolic values of enum-type options */
+
#ifndef INTEL_DEBUG
int INTEL_DEBUG = (0);
#endif
@@ -100,6 +101,9 @@ int INTEL_DEBUG = (0);
#define DRIVER_DATE "20090418 2009Q1"
#define DRIVER_DATE_GEM "GEM " DRIVER_DATE
+
+static void intel_flush(GLcontext *ctx, GLboolean needs_mi_flush);
+
static const GLubyte *
intelGetString(GLcontext * ctx, GLenum name)
{
@@ -203,6 +207,24 @@ intelGetString(GLcontext * ctx, GLenum name)
}
}
+static unsigned
+intel_bits_per_pixel(const struct intel_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
intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
{
@@ -210,7 +232,7 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
struct intel_renderbuffer *rb;
struct intel_region *region, *depth_region;
struct intel_context *intel = context->driverPrivate;
- __DRIbuffer *buffers;
+ __DRIbuffer *buffers = NULL;
__DRIscreen *screen;
int i, count;
unsigned int attachments[10];
@@ -222,22 +244,65 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
screen = intel->intelScreen->driScrnPriv;
- i = 0;
- if (intel_fb->color_rb[0])
- attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
- if (intel_fb->color_rb[1])
- attachments[i++] = __DRI_BUFFER_BACK_LEFT;
- if (intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH))
- attachments[i++] = __DRI_BUFFER_DEPTH;
- if (intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL))
- attachments[i++] = __DRI_BUFFER_STENCIL;
-
- buffers = (*screen->dri2.loader->getBuffers)(drawable,
- &drawable->w,
- &drawable->h,
- attachments, i,
- &count,
- drawable->loaderPrivate);
+ if (screen->dri2.loader
+ && (screen->dri2.loader->base.version > 2)
+ && (screen->dri2.loader->getBuffersWithFormat != NULL)) {
+ struct intel_renderbuffer *depth_rb;
+ struct intel_renderbuffer *stencil_rb;
+
+ i = 0;
+ if ((intel->is_front_buffer_rendering ||
+ intel->is_front_buffer_reading ||
+ !intel_fb->color_rb[1])
+ && intel_fb->color_rb[0]) {
+ attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
+ attachments[i++] = intel_bits_per_pixel(intel_fb->color_rb[0]);
+ }
+
+ if (intel_fb->color_rb[1]) {
+ attachments[i++] = __DRI_BUFFER_BACK_LEFT;
+ attachments[i++] = intel_bits_per_pixel(intel_fb->color_rb[1]);
+ }
+
+ depth_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH);
+ stencil_rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
+
+ if ((depth_rb != NULL) && (stencil_rb != NULL)) {
+ attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
+ attachments[i++] = intel_bits_per_pixel(depth_rb);
+ } else if (depth_rb != NULL) {
+ attachments[i++] = __DRI_BUFFER_DEPTH;
+ attachments[i++] = intel_bits_per_pixel(depth_rb);
+ } else if (stencil_rb != NULL) {
+ attachments[i++] = __DRI_BUFFER_STENCIL;
+ attachments[i++] = intel_bits_per_pixel(stencil_rb);
+ }
+
+ buffers =
+ (*screen->dri2.loader->getBuffersWithFormat)(drawable,
+ &drawable->w,
+ &drawable->h,
+ attachments, i / 2,
+ &count,
+ drawable->loaderPrivate);
+ } else if (screen->dri2.loader) {
+ i = 0;
+ if (intel_fb->color_rb[0])
+ attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
+ if (intel_fb->color_rb[1])
+ attachments[i++] = __DRI_BUFFER_BACK_LEFT;
+ if (intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH))
+ attachments[i++] = __DRI_BUFFER_DEPTH;
+ if (intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL))
+ attachments[i++] = __DRI_BUFFER_STENCIL;
+
+ buffers = (*screen->dri2.loader->getBuffers)(drawable,
+ &drawable->w,
+ &drawable->h,
+ attachments, i,
+ &count,
+ drawable->loaderPrivate);
+ }
if (buffers == NULL)
return;
@@ -280,6 +345,11 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
region_name = "dri2 depth buffer";
break;
+ case __DRI_BUFFER_DEPTH_STENCIL:
+ rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH);
+ region_name = "dri2 depth / stencil buffer";
+ break;
+
case __DRI_BUFFER_STENCIL:
rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
region_name = "dri2 stencil buffer";
@@ -326,6 +396,23 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
intel_renderbuffer_set_region(rb, region);
intel_region_release(&region);
+
+ if (buffers[i].attachment == __DRI_BUFFER_DEPTH_STENCIL) {
+ rb = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
+ if (rb != NULL) {
+ struct intel_region *stencil_region = NULL;
+
+ if (rb->region) {
+ dri_bo_flink(rb->region->buffer, &name);
+ if (name == buffers[i].name)
+ continue;
+ }
+
+ intel_region_reference(&stencil_region, region);
+ intel_renderbuffer_set_region(rb, stencil_region);
+ intel_region_release(&stencil_region);
+ }
+ }
}
driUpdateFramebufferSize(&intel->ctx, drawable);
@@ -534,8 +621,8 @@ intel_flush(GLcontext *ctx, GLboolean needs_mi_flush)
if ((ctx->DrawBuffer->Name == 0) && intel->front_buffer_dirty) {
__DRIscreen *const screen = intel->intelScreen->driScrnPriv;
- if (screen->dri2.loader
- && (screen->dri2.loader->base.version >= 2)
+ if (screen->dri2.loader &&
+ (screen->dri2.loader->base.version >= 2)
&& (screen->dri2.loader->flushFrontBuffer != NULL)) {
(*screen->dri2.loader->flushFrontBuffer)(intel->driDrawable,
intel->driDrawable->loaderPrivate);
@@ -578,7 +665,7 @@ intelFinish(GLcontext * ctx)
irb = intel_renderbuffer(fb->_ColorDrawBuffers[i]);
- if (irb->region)
+ if (irb && irb->region)
dri_bo_wait_rendering(irb->region->buffer);
}
if (fb->_DepthBuffer) {
@@ -704,6 +791,13 @@ intelInitContext(struct intel_context *intel,
_mesa_init_point(ctx);
ctx->Const.MaxColorAttachments = 4; /* XXX FBO: review this */
+ if (IS_965(intelScreen->deviceID)) {
+ if (MAX_WIDTH > 8192)
+ ctx->Const.MaxRenderbufferSize = 8192;
+ } else {
+ if (MAX_WIDTH > 2048)
+ ctx->Const.MaxRenderbufferSize = 2048;
+ }
/* Initialize the software rasterizer and helper modules. */
_swrast_CreateContext(ctx);
@@ -821,13 +915,50 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv)
intel->prim.vb_bo = NULL;
if (release_texture_heaps) {
- /* This share group is about to go away, free our private
- * texture object data.
+ /* Nothing is currently done here to free texture heaps;
+ * but we're not using the texture heap utilities, so I
+ * rather think we shouldn't. I've taken a look, and can't
+ * find any private texture data hanging around anywhere, but
+ * I'm not yet certain there isn't any at all...
*/
- if (INTEL_DEBUG & DEBUG_TEXTURE)
+ /* if (INTEL_DEBUG & DEBUG_TEXTURE)
fprintf(stderr, "do something to free texture heaps\n");
+ */
}
+ /* XXX In intelMakeCurrent() below, the context's static regions are
+ * referenced inside the frame buffer; it's listed as a hack,
+ * with a comment of "XXX FBO temporary fix-ups!", but
+ * as long as it's there, we should release the regions here.
+ * The do/while loop around the block is used to allow the
+ * "continue" statements inside the block to exit the block,
+ * to avoid many layers of "if" constructs.
+ */
+ do {
+ __DRIdrawablePrivate * driDrawPriv = intel->driDrawable;
+ struct intel_framebuffer *intel_fb;
+ struct intel_renderbuffer *irbDepth, *irbStencil;
+ if (!driDrawPriv) {
+ /* We're already detached from the drawable; exit this block. */
+ continue;
+ }
+ intel_fb = (struct intel_framebuffer *) driDrawPriv->driverPrivate;
+ if (!intel_fb) {
+ /* The frame buffer is already gone; exit this block. */
+ continue;
+ }
+ irbDepth = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH);
+ irbStencil = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
+
+ /* Usually, the stencil buffer is the same as the depth buffer;
+ * but they're handled separately in MakeCurrent, so we'll
+ * handle them separately here.
+ */
+ if (irbStencil && irbStencil->region == intel->depth_region) {
+ intel_renderbuffer_set_region(irbStencil, NULL);
+ }
+ } while (0);
+
intel_region_release(&intel->front_region);
intel_region_release(&intel->back_region);
intel_region_release(&intel->depth_region);
diff --git a/dist/Mesa/src/mesa/drivers/dri/intel/intel_context.h b/dist/Mesa/src/mesa/drivers/dri/intel/intel_context.h
index 8f87d5680..294ee3122 100644
--- a/dist/Mesa/src/mesa/drivers/dri/intel/intel_context.h
+++ b/dist/Mesa/src/mesa/drivers/dri/intel/intel_context.h
@@ -282,6 +282,14 @@ struct intel_context
* easily.
*/
GLboolean is_front_buffer_rendering;
+ /**
+ * Track whether front-buffer is the current read target.
+ *
+ * This is closely associated with is_front_buffer_rendering, but may
+ * be set separately. The DRI2 fake front buffer must be referenced
+ * either way.
+ */
+ GLboolean is_front_buffer_reading;
drm_clip_rect_t fboRect; /**< cliprect for FBO rendering */
diff --git a/dist/Mesa/src/mesa/drivers/dri/intel/intel_span.c b/dist/Mesa/src/mesa/drivers/dri/intel/intel_span.c
index d9315043e..3206724d5 100644
--- a/dist/Mesa/src/mesa/drivers/dri/intel/intel_span.c
+++ b/dist/Mesa/src/mesa/drivers/dri/intel/intel_span.c
@@ -688,12 +688,15 @@ intel_set_span_functions(struct intel_context *intel,
struct intel_renderbuffer *irb = (struct intel_renderbuffer *) rb;
uint32_t tiling;
+#ifndef __OpenBSD__ /* openbsd uses fenced gtt writes for tiles p{read,write} */
/* If in GEM mode, we need to do the tile address swizzling ourselves,
* instead of the fence registers handling it.
*/
+
if (intel->ttm)
tiling = irb->region->tiling;
else
+#endif
tiling = I915_TILING_NONE;
if (rb->_ActualFormat == GL_RGB5) {