summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/common')
-rw-r--r--src/mesa/drivers/dri/common/dri_util.c1036
-rw-r--r--src/mesa/drivers/dri/common/dri_util.h319
-rw-r--r--src/mesa/drivers/dri/common/drirenderbuffer.c2
-rw-r--r--src/mesa/drivers/dri/common/spantmp2.h2
-rw-r--r--src/mesa/drivers/dri/common/utils.c309
-rw-r--r--src/mesa/drivers/dri/common/utils.h41
-rw-r--r--src/mesa/drivers/dri/common/vblank.c159
-rw-r--r--src/mesa/drivers/dri/common/vblank.h16
-rw-r--r--src/mesa/drivers/dri/common/xmlconfig.c26
9 files changed, 860 insertions, 1050 deletions
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
index 2013125efe..fff79c36ad 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -55,19 +55,39 @@
#include "dri_util.h"
#include "drm_sarea.h"
-#include "utils.h"
#ifndef GLX_OML_sync_control
-typedef GLboolean ( * PFNGLXGETMSCRATEOMLPROC) (__DRIdrawable *drawable, int32_t *numerator, int32_t *denominator);
+typedef GLboolean ( * PFNGLXGETMSCRATEOMLPROC) (__DRInativeDisplay *dpy, __DRIid drawable, int32_t *numerator, int32_t *denominator);
#endif
+/* This pointer *must* be set by the driver's __driCreateNewScreen funciton!
+ */
+const __DRIinterfaceMethods * dri_interface = NULL;
+
/**
- * This is just a token extension used to signal that the driver
- * supports setting a read drawable.
+ * This is used in a couple of places that call \c driCreateNewDrawable.
*/
-const __DRIextension driReadDrawableExtension = {
- __DRI_READ_DRAWABLE, __DRI_READ_DRAWABLE_VERSION
-};
+static const int empty_attribute_list[1] = { None };
+
+
+/**
+ * Cached copy of the internal API version used by libGL and the client-side
+ * DRI driver.
+ */
+static int api_ver = 0;
+
+/* forward declarations */
+static int driQueryFrameTracking( __DRInativeDisplay *dpy, void *priv,
+ int64_t *sbc, int64_t *missedFrames,
+ float *lastMissedUsage, float *usage );
+
+static void *driCreateNewDrawable(__DRInativeDisplay *dpy,
+ const __GLcontextModes *modes,
+ __DRIid draw, __DRIdrawable *pdraw,
+ int renderType, const int *attrs);
+
+static void driDestroyDrawable(__DRInativeDisplay *dpy, void *drawablePrivate);
+
/**
* Print message to \c stderr if the \c LIBGL_DEBUG environment variable
@@ -91,19 +111,64 @@ __driUtilMessage(const char *f, ...)
}
}
-GLint
-driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 )
+
+/*****************************************************************/
+/** \name Drawable list management */
+/*****************************************************************/
+/*@{*/
+
+static GLboolean __driAddDrawable(void *drawHash, __DRIdrawable *pdraw)
{
- if (rect2.x1 > rect1.x1) rect1.x1 = rect2.x1;
- if (rect2.x2 < rect1.x2) rect1.x2 = rect2.x2;
- if (rect2.y1 > rect1.y1) rect1.y1 = rect2.y1;
- if (rect2.y2 < rect1.y2) rect1.y2 = rect2.y2;
+ __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)pdraw->private;
- if (rect1.x1 > rect1.x2 || rect1.y1 > rect1.y2) return 0;
+ if (drmHashInsert(drawHash, pdp->draw, pdraw))
+ return GL_FALSE;
- return (rect1.x2 - rect1.x1) * (rect1.y2 - rect1.y1);
+ return GL_TRUE;
+}
+
+static __DRIdrawable *__driFindDrawable(void *drawHash, __DRIid draw)
+{
+ int retcode;
+ __DRIdrawable *pdraw;
+
+ retcode = drmHashLookup(drawHash, draw, (void *)&pdraw);
+ if (retcode)
+ return NULL;
+
+ return pdraw;
+}
+
+
+/**
+ * Find drawables in the local hash that have been destroyed on the
+ * server.
+ *
+ * \param drawHash Hash-table containing all known drawables.
+ */
+static void __driGarbageCollectDrawables(void *drawHash)
+{
+ __DRIid draw;
+ __DRInativeDisplay *dpy;
+ __DRIdrawable *pdraw;
+
+ if (drmHashFirst(drawHash, &draw, (void *)&pdraw) == 1) {
+ do {
+ __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *)pdraw->private;
+ dpy = pdp->driScreenPriv->display;
+ if (! (*dri_interface->windowExists)(dpy, draw)) {
+ /* Destroy the local drawable data, if the drawable no
+ longer exists in the Xserver */
+ (*pdraw->destroyDrawable)(dpy, pdraw->private);
+ _mesa_free(pdraw);
+ }
+ } while (drmHashNext(drawHash, &draw, (void *)&pdraw) == 1);
+ }
}
+/*@}*/
+
+
/*****************************************************************/
/** \name Context (un)binding functions */
/*****************************************************************/
@@ -112,7 +177,10 @@ driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 )
/**
* Unbind context.
*
- * \param scrn the screen.
+ * \param dpy the display handle.
+ * \param scrn the screen number.
+ * \param draw drawable.
+ * \param read Current reading drawable.
* \param gc context.
*
* \return \c GL_TRUE on success, or \c GL_FALSE on failure.
@@ -125,27 +193,56 @@ driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 )
* While casting the opaque private pointers associated with the parameters
* into their respective real types it also assures they are not \c NULL.
*/
-static int driUnbindContext(__DRIcontext *pcp)
+static GLboolean driUnbindContext(__DRInativeDisplay *dpy, int scrn,
+ __DRIid draw, __DRIid read,
+ __DRIcontext *ctx)
{
- __DRIscreen *psp;
- __DRIdrawable *pdp;
- __DRIdrawable *prp;
+ __DRIscreen *pDRIScreen;
+ __DRIdrawable *pdraw;
+ __DRIdrawable *pread;
+ __DRIcontextPrivate *pcp;
+ __DRIscreenPrivate *psp;
+ __DRIdrawablePrivate *pdp;
+ __DRIdrawablePrivate *prp;
/*
** Assume error checking is done properly in glXMakeCurrent before
** calling driUnbindContext.
*/
- if (pcp == NULL)
- return GL_FALSE;
+ if (ctx == NULL || draw == None || read == None) {
+ /* ERROR!!! */
+ return GL_FALSE;
+ }
+
+ pDRIScreen = (*dri_interface->getScreen)(dpy, scrn);
+ if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) {
+ /* ERROR!!! */
+ return GL_FALSE;
+ }
+
+ psp = (__DRIscreenPrivate *)pDRIScreen->private;
+ pcp = (__DRIcontextPrivate *)ctx->private;
+
+ pdraw = __driFindDrawable(psp->drawHash, draw);
+ if (!pdraw) {
+ /* ERROR!!! */
+ return GL_FALSE;
+ }
+ pdp = (__DRIdrawablePrivate *)pdraw->private;
+
+ pread = __driFindDrawable(psp->drawHash, read);
+ if (!pread) {
+ /* ERROR!!! */
+ return GL_FALSE;
+ }
+ prp = (__DRIdrawablePrivate *)pread->private;
- psp = pcp->driScreenPriv;
- pdp = pcp->driDrawablePriv;
- prp = pcp->driReadablePriv;
/* Let driver unbind drawable from context */
(*psp->DriverAPI.UnbindContext)(pcp);
+
if (pdp->refcount == 0) {
/* ERROR!!! */
return GL_FALSE;
@@ -162,6 +259,12 @@ static int driUnbindContext(__DRIcontext *pcp)
prp->refcount--;
}
+ /* destroy the drawables if they no longer exist on the server */
+ if ((pdp->refcount == 0) || (prp->refcount == 0)) {
+ /* probably shouldn't need the collector here,
+ as we know the affected drawables (or could there be others?) */
+ __driGarbageCollectDrawables(pdp->driScreenPriv->drawHash);
+ }
/* XXX this is disabled so that if we call SwapBuffers on an unbound
* window we can determine the last context bound to the window and
@@ -181,20 +284,72 @@ static int driUnbindContext(__DRIcontext *pcp)
* This function takes both a read buffer and a draw buffer. This is needed
* for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent
* function.
+ *
+ * \bug This function calls \c driCreateNewDrawable in two places with the
+ * \c renderType hard-coded to \c GLX_WINDOW_BIT. Some checking might
+ * be needed in those places when support for pbuffers and / or pixmaps
+ * is added. Is it safe to assume that the drawable is a window?
*/
-static int driBindContext(__DRIcontext *pcp,
- __DRIdrawable *pdp,
- __DRIdrawable *prp)
+static GLboolean DoBindContext(__DRInativeDisplay *dpy,
+ __DRIid draw, __DRIid read,
+ __DRIcontext *ctx, const __GLcontextModes * modes,
+ __DRIscreenPrivate *psp)
{
- __DRIscreenPrivate *psp = pcp->driScreenPriv;
+ __DRIdrawable *pdraw;
+ __DRIdrawablePrivate *pdp;
+ __DRIdrawable *pread;
+ __DRIdrawablePrivate *prp;
+ __DRIcontextPrivate * const pcp = ctx->private;
+
+
+ /* Find the _DRIdrawable which corresponds to the writing drawable. */
+ pdraw = __driFindDrawable(psp->drawHash, draw);
+ if (!pdraw) {
+ /* Allocate a new drawable */
+ pdraw = (__DRIdrawable *)_mesa_malloc(sizeof(__DRIdrawable));
+ if (!pdraw) {
+ /* ERROR!!! */
+ return GL_FALSE;
+ }
- /*
- ** Assume error checking is done properly in glXMakeCurrent before
- ** calling driBindContext.
- */
+ /* Create a new drawable */
+ driCreateNewDrawable(dpy, modes, draw, pdraw, GLX_WINDOW_BIT,
+ empty_attribute_list);
+ if (!pdraw->private) {
+ /* ERROR!!! */
+ _mesa_free(pdraw);
+ return GL_FALSE;
+ }
- if (pcp == NULL || pdp == None || prp == None)
- return GL_FALSE;
+ }
+ pdp = (__DRIdrawablePrivate *) pdraw->private;
+
+ /* Find the _DRIdrawable which corresponds to the reading drawable. */
+ if (read == draw) {
+ /* read buffer == draw buffer */
+ prp = pdp;
+ }
+ else {
+ pread = __driFindDrawable(psp->drawHash, read);
+ if (!pread) {
+ /* Allocate a new drawable */
+ pread = (__DRIdrawable *)_mesa_malloc(sizeof(__DRIdrawable));
+ if (!pread) {
+ /* ERROR!!! */
+ return GL_FALSE;
+ }
+
+ /* Create a new drawable */
+ driCreateNewDrawable(dpy, modes, read, pread, GLX_WINDOW_BIT,
+ empty_attribute_list);
+ if (!pread->private) {
+ /* ERROR!!! */
+ _mesa_free(pread);
+ return GL_FALSE;
+ }
+ }
+ prp = (__DRIdrawablePrivate *) pread->private;
+ }
/* Bind the drawable to the context */
pcp->driDrawablePriv = pdp;
@@ -209,22 +364,16 @@ static int driBindContext(__DRIcontext *pcp,
** Now that we have a context associated with this drawable, we can
** initialize the drawable information if has not been done before.
*/
+ if (!pdp->pStamp || *pdp->pStamp != pdp->lastStamp) {
+ DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
+ __driUtilUpdateDrawableInfo(pdp);
+ DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
+ }
- if (psp->dri2.enabled) {
- __driParseEvents(pcp, pdp);
- __driParseEvents(pcp, prp);
- } else {
- if (!pdp->pStamp || *pdp->pStamp != pdp->lastStamp) {
- DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
- __driUtilUpdateDrawableInfo(pdp);
- DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
- }
-
- if ((pdp != prp) && (!prp->pStamp || *prp->pStamp != prp->lastStamp)) {
- DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
- __driUtilUpdateDrawableInfo(prp);
- DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
- }
+ if ((pdp != prp) && (!prp->pStamp || *prp->pStamp != prp->lastStamp)) {
+ DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
+ __driUtilUpdateDrawableInfo(prp);
+ DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
}
/* Call device-specific MakeCurrent */
@@ -233,6 +382,37 @@ static int driBindContext(__DRIcontext *pcp,
return GL_TRUE;
}
+
+/**
+ * This function takes both a read buffer and a draw buffer. This is needed
+ * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent
+ * function.
+ */
+static GLboolean driBindContext(__DRInativeDisplay *dpy, int scrn,
+ __DRIid draw, __DRIid read,
+ __DRIcontext * ctx)
+{
+ __DRIscreen *pDRIScreen;
+
+ /*
+ ** Assume error checking is done properly in glXMakeCurrent before
+ ** calling driBindContext.
+ */
+
+ if (ctx == NULL || draw == None || read == None) {
+ /* ERROR!!! */
+ return GL_FALSE;
+ }
+
+ pDRIScreen = (*dri_interface->getScreen)(dpy, scrn);
+ if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) {
+ /* ERROR!!! */
+ return GL_FALSE;
+ }
+
+ return DoBindContext( dpy, draw, read, ctx, ctx->mode,
+ (__DRIscreenPrivate *)pDRIScreen->private );
+}
/*@}*/
@@ -256,7 +436,7 @@ static int driBindContext(__DRIcontext *pcp,
void
__driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)
{
- __DRIscreenPrivate *psp = pdp->driScreenPriv;
+ __DRIscreenPrivate *psp;
__DRIcontextPrivate *pcp = pdp->driContextPriv;
if (!pcp
@@ -267,6 +447,15 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)
*/
}
+ psp = pdp->driScreenPriv;
+ if (!psp) {
+ /* ERROR!!! */
+ _mesa_problem(NULL, "Warning! Possible infinite loop due to bug "
+ "in file %s, line %d\n",
+ __FILE__, __LINE__);
+ return;
+ }
+
if (pdp->pClipRects) {
_mesa_free(pdp->pClipRects);
pdp->pClipRects = NULL;
@@ -279,15 +468,15 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)
DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
- if (! (*psp->getDrawableInfo->getDrawableInfo)(pdp,
+ if (!__driFindDrawable(psp->drawHash, pdp->draw) ||
+ ! (*dri_interface->getDrawableInfo)(pdp->display, pdp->screen, pdp->draw,
&pdp->index, &pdp->lastStamp,
&pdp->x, &pdp->y, &pdp->w, &pdp->h,
&pdp->numClipRects, &pdp->pClipRects,
&pdp->backX,
&pdp->backY,
&pdp->numBackClipRects,
- &pdp->pBackClipRects,
- pdp->loaderPrivate)) {
+ &pdp->pBackClipRects )) {
/* Error -- eg the window may have been destroyed. Keep going
* with no cliprects.
*/
@@ -304,138 +493,6 @@ __driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)
}
-int
-__driParseEvents(__DRIcontextPrivate *pcp, __DRIdrawablePrivate *pdp)
-{
- __DRIscreenPrivate *psp = pcp->driScreenPriv;
- __DRIDrawableConfigEvent *dc, *last_dc;
- __DRIBufferAttachEvent *ba, *last_ba;
- unsigned int tail, mask, *p, end, total, size, changed;
- unsigned char *data;
- size_t rect_size;
-
- /* Check for wraparound. */
- if (psp->dri2.buffer->prealloc - pdp->dri2.tail > psp->dri2.buffer->size) {
- /* If prealloc overlaps into what we just parsed, the
- * server overwrote it and we have to reset our tail
- * pointer. */
- DRM_UNLOCK(psp->fd, psp->lock, pcp->hHWContext);
- (*psp->dri2.loader->reemitDrawableInfo)(pdp, &pdp->dri2.tail,
- pdp->loaderPrivate);
- DRM_LIGHT_LOCK(psp->fd, psp->lock, pcp->hHWContext);
- }
-
- total = psp->dri2.buffer->head - pdp->dri2.tail;
- mask = psp->dri2.buffer->size - 1;
- end = psp->dri2.buffer->head;
- data = psp->dri2.buffer->data;
-
- changed = 0;
- last_dc = NULL;
- last_ba = NULL;
-
- for (tail = pdp->dri2.tail; tail != end; tail += size) {
- p = (unsigned int *) (data + (tail & mask));
- size = DRI2_EVENT_SIZE(*p);
- if (size > total || (tail & mask) + size > psp->dri2.buffer->size) {
- /* illegal data, bail out. */
- fprintf(stderr, "illegal event size\n");
- break;
- }
-
- switch (DRI2_EVENT_TYPE(*p)) {
- case DRI2_EVENT_DRAWABLE_CONFIG:
- dc = (__DRIDrawableConfigEvent *) p;
- if (dc->drawable == pdp->dri2.drawable_id)
- last_dc = dc;
- break;
-
- case DRI2_EVENT_BUFFER_ATTACH:
- ba = (__DRIBufferAttachEvent *) p;
- if (ba->drawable == pdp->dri2.drawable_id &&
- ba->buffer.attachment == DRI_DRAWABLE_BUFFER_FRONT_LEFT)
- last_ba = ba;
- break;
- }
- }
-
- if (last_dc) {
- if (pdp->w != last_dc->width || pdp->h != last_dc->height)
- changed = 1;
-
- pdp->x = last_dc->x;
- pdp->y = last_dc->y;
- pdp->w = last_dc->width;
- pdp->h = last_dc->height;
-
- pdp->backX = 0;
- pdp->backY = 0;
- pdp->numBackClipRects = 1;
- pdp->pBackClipRects[0].x1 = 0;
- pdp->pBackClipRects[0].y1 = 0;
- pdp->pBackClipRects[0].x2 = pdp->w;
- pdp->pBackClipRects[0].y2 = pdp->h;
-
- pdp->numClipRects = last_dc->num_rects;
- _mesa_free(pdp->pClipRects);
- rect_size = last_dc->num_rects * sizeof last_dc->rects[0];
- pdp->pClipRects = _mesa_malloc(rect_size);
- memcpy(pdp->pClipRects, last_dc->rects, rect_size);
- }
-
- /* We only care about the most recent drawable config. */
- if (last_dc && changed)
- (*psp->DriverAPI.HandleDrawableConfig)(pdp, pcp, last_dc);
-
- /* Front buffer attachments are special, they typically mean that
- * we're rendering to a redirected window (or a child window of a
- * redirected window) and that it got resized. Resizing the root
- * window on randr events is a special case of this. Other causes
- * may be a window transitioning between redirected and
- * non-redirected, or a window getting reparented between parents
- * with different window pixmaps (eg two redirected windows).
- * These events are special in that the X server allocates the
- * buffer and that the buffer may be shared by other child
- * windows. When our window share the window pixmap with its
- * parent, drawable config events doesn't affect the front buffer.
- * We only care about the last such event in the buffer; in fact,
- * older events will refer to invalid buffer objects.*/
- if (last_ba)
- (*psp->DriverAPI.HandleBufferAttach)(pdp, pcp, last_ba);
-
- /* If there was a drawable config event in the buffer and it
- * changed the size of the window, all buffer auxillary buffer
- * attachments prior to that are invalid (as opposed to the front
- * buffer case discussed above). In that case we can start
- * looking for buffer attachment after the last drawable config
- * event. If there is no drawable config event in this batch of
- * events, we have to assume that the last batch might have had
- * one and process all buffer attach events.*/
- if (last_dc && changed)
- tail = (unsigned char *) last_dc - data;
- else
- tail = pdp->dri2.tail;
-
- for ( ; tail != end; tail += size) {
- ba = (__DRIBufferAttachEvent *) (data + (tail & mask));
- size = DRI2_EVENT_SIZE(ba->event_header);
-
- if (DRI2_EVENT_TYPE(ba->event_header) != DRI2_EVENT_BUFFER_ATTACH)
- continue;
- if (ba->drawable != pdp->dri2.drawable_id)
- continue;
- if (last_ba == ba)
- continue;
-
- (*psp->DriverAPI.HandleBufferAttach)(pdp, pcp, ba);
- changed = 1;
- }
-
- pdp->dri2.tail = tail;
-
- return changed || last_ba;
-}
-
/*@}*/
/*****************************************************************/
@@ -443,33 +500,10 @@ __driParseEvents(__DRIcontextPrivate *pcp, __DRIdrawablePrivate *pdp)
/*****************************************************************/
/*@{*/
-static void driReportDamage(__DRIdrawable *pdp,
- struct drm_clip_rect *pClipRects, int numClipRects)
-{
- __DRIscreen *psp = pdp->driScreenPriv;
-
- /* Check that we actually have the new damage report method */
- if (psp->dri2.enabled) {
- (*psp->dri2.loader->postDamage)(pdp,
- pClipRects,
- numClipRects,
- pdp->loaderPrivate);
- } else if (psp->damage) {
- /* Report the damage. Currently, all our drivers draw
- * directly to the front buffer, so we report the damage there
- * rather than to the backing storein (if any).
- */
- (*psp->damage->reportDamage)(pdp,
- pdp->x, pdp->y,
- pClipRects, numClipRects,
- GL_TRUE, pdp->loaderPrivate);
- }
-}
-
-
/**
* Swap buffers.
*
+ * \param dpy the display handle.
* \param drawablePrivate opaque pointer to the per-drawable private info.
*
* \internal
@@ -477,28 +511,74 @@ static void driReportDamage(__DRIdrawable *pdp,
*
* Is called directly from glXSwapBuffers().
*/
-static void driSwapBuffers(__DRIdrawable *dPriv)
+static void driSwapBuffers( __DRInativeDisplay *dpy, void *drawablePrivate )
+{
+ __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate;
+ drm_clip_rect_t rect;
+
+ dPriv->swapBuffers(dPriv);
+
+ /* Check that we actually have the new damage report method */
+ if (api_ver < 20070105 || dri_interface->reportDamage == NULL)
+ return;
+
+ /* Assume it's affecting the whole drawable for now */
+ rect.x1 = 0;
+ rect.y1 = 0;
+ rect.x2 = rect.x1 + dPriv->w;
+ rect.y2 = rect.y1 + dPriv->h;
+
+ /* Report the damage. Currently, all our drivers draw directly to the
+ * front buffer, so we report the damage there rather than to the backing
+ * store (if any).
+ */
+ (*dri_interface->reportDamage)(dpy, dPriv->screen, dPriv->draw,
+ dPriv->x, dPriv->y,
+ &rect, 1, GL_TRUE);
+}
+
+/**
+ * Called directly from a number of higher-level GLX functions.
+ */
+static int driGetMSC( void *screenPrivate, int64_t *msc )
+{
+ __DRIscreenPrivate *sPriv = (__DRIscreenPrivate *) screenPrivate;
+
+ return sPriv->DriverAPI.GetMSC( sPriv, msc );
+}
+
+/**
+ * Called directly from a number of higher-level GLX functions.
+ */
+static int driGetSBC( __DRInativeDisplay *dpy, void *drawablePrivate, int64_t *sbc )
{
- __DRIscreen *psp = dPriv->driScreenPriv;
+ __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate;
+ __DRIswapInfo sInfo;
+ int status;
- if (!dPriv->numClipRects)
- return;
- psp->DriverAPI.SwapBuffers(dPriv);
+ status = dPriv->driScreenPriv->DriverAPI.GetSwapInfo( dPriv, & sInfo );
+ *sbc = sInfo.swap_count;
- driReportDamage(dPriv, dPriv->pClipRects, dPriv->numClipRects);
+ return status;
}
-static int driDrawableGetMSC( __DRIscreen *sPriv, __DRIdrawable *dPriv,
- int64_t *msc )
+static int driWaitForSBC( __DRInativeDisplay * dpy, void *drawablePriv,
+ int64_t target_sbc,
+ int64_t * msc, int64_t * sbc )
{
- return sPriv->DriverAPI.GetDrawableMSC(sPriv, dPriv, msc);
+ __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv;
+
+ return dPriv->driScreenPriv->DriverAPI.WaitForSBC( dPriv, target_sbc,
+ msc, sbc );
}
-static int driWaitForMSC(__DRIdrawable *dPriv, int64_t target_msc,
- int64_t divisor, int64_t remainder,
- int64_t * msc, int64_t * sbc)
+static int driWaitForMSC( __DRInativeDisplay * dpy, void *drawablePriv,
+ int64_t target_msc,
+ int64_t divisor, int64_t remainder,
+ int64_t * msc, int64_t * sbc )
{
+ __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv;
__DRIswapInfo sInfo;
int status;
@@ -520,70 +600,63 @@ static int driWaitForMSC(__DRIdrawable *dPriv, int64_t target_msc,
return status;
}
-const __DRImediaStreamCounterExtension driMediaStreamCounterExtension = {
- { __DRI_MEDIA_STREAM_COUNTER, __DRI_MEDIA_STREAM_COUNTER_VERSION },
- driWaitForMSC,
- driDrawableGetMSC,
-};
-
-static void driCopySubBuffer(__DRIdrawable *dPriv,
- int x, int y, int w, int h)
+static int64_t driSwapBuffersMSC( __DRInativeDisplay * dpy, void *drawablePriv,
+ int64_t target_msc,
+ int64_t divisor, int64_t remainder )
{
- drm_clip_rect_t rect;
+ __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePriv;
- dPriv->driScreenPriv->DriverAPI.CopySubBuffer(dPriv, x, y, w, h);
-
- rect.x1 = x;
- rect.y1 = dPriv->h - y - h;
- rect.x2 = x + w;
- rect.y2 = rect.y1 + h;
- driReportDamage(dPriv, &rect, 1);
+ return dPriv->driScreenPriv->DriverAPI.SwapBuffersMSC( dPriv, target_msc,
+ divisor,
+ remainder );
}
-const __DRIcopySubBufferExtension driCopySubBufferExtension = {
- { __DRI_COPY_SUB_BUFFER, __DRI_COPY_SUB_BUFFER_VERSION },
- driCopySubBuffer
-};
-
-static void driSetSwapInterval(__DRIdrawable *dPriv, unsigned int interval)
-{
- dPriv->swap_interval = interval;
-}
-
-static unsigned int driGetSwapInterval(__DRIdrawable *dPriv)
+static void driCopySubBuffer( __DRInativeDisplay *dpy, void *drawablePrivate,
+ int x, int y, int w, int h)
{
- return dPriv->swap_interval;
+ __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate;
+ dPriv->driScreenPriv->DriverAPI.CopySubBuffer(dPriv, x, y, w, h);
+ (void) dpy;
}
-const __DRIswapControlExtension driSwapControlExtension = {
- { __DRI_SWAP_CONTROL, __DRI_SWAP_CONTROL_VERSION },
- driSetSwapInterval,
- driGetSwapInterval
-};
-
-
/**
* This is called via __DRIscreenRec's createNewDrawable pointer.
*/
-static __DRIdrawable *
-driCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config,
- drm_drawable_t hwDrawable, int renderType,
- const int *attrs, void *data)
+static void *driCreateNewDrawable(__DRInativeDisplay *dpy,
+ const __GLcontextModes *modes,
+ __DRIid draw,
+ __DRIdrawable *pdraw,
+ int renderType,
+ const int *attrs)
{
- __DRIdrawable *pdp;
+ __DRIscreen * const pDRIScreen = (*dri_interface->getScreen)(dpy, modes->screen);
+ __DRIscreenPrivate *psp;
+ __DRIdrawablePrivate *pdp;
+
+
+ pdraw->private = NULL;
/* Since pbuffers are not yet supported, no drawable attributes are
* supported either.
*/
(void) attrs;
- pdp = _mesa_malloc(sizeof *pdp);
+ if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) {
+ return NULL;
+ }
+
+ pdp = (__DRIdrawablePrivate *)_mesa_malloc(sizeof(__DRIdrawablePrivate));
if (!pdp) {
return NULL;
}
- pdp->loaderPrivate = data;
- pdp->hHWDrawable = hwDrawable;
+ if (!(*dri_interface->createDrawable)(dpy, modes->screen, draw, &pdp->hHWDrawable)) {
+ _mesa_free(pdp);
+ return NULL;
+ }
+
+ pdp->draw = draw;
+ pdp->pdraw = pdraw;
pdp->refcount = 0;
pdp->pStamp = NULL;
pdp->lastStamp = 0;
@@ -596,55 +669,80 @@ driCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config,
pdp->numBackClipRects = 0;
pdp->pClipRects = NULL;
pdp->pBackClipRects = NULL;
- pdp->vblSeq = 0;
- pdp->vblFlags = 0;
+ pdp->display = dpy;
+ pdp->screen = modes->screen;
+ psp = (__DRIscreenPrivate *)pDRIScreen->private;
pdp->driScreenPriv = psp;
pdp->driContextPriv = &psp->dummyContextPriv;
- if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, &config->modes,
+ if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, modes,
renderType == GLX_PIXMAP_BIT)) {
+ (void)(*dri_interface->destroyDrawable)(dpy, modes->screen, pdp->draw);
_mesa_free(pdp);
return NULL;
}
- pdp->msc_base = 0;
+ pdraw->private = pdp;
+ pdraw->destroyDrawable = driDestroyDrawable;
+ pdraw->swapBuffers = driSwapBuffers; /* called by glXSwapBuffers() */
+
+ pdraw->getSBC = driGetSBC;
+ pdraw->waitForSBC = driWaitForSBC;
+ pdraw->waitForMSC = driWaitForMSC;
+ pdraw->swapBuffersMSC = driSwapBuffersMSC;
+ pdraw->frameTracking = NULL;
+ pdraw->queryFrameTracking = driQueryFrameTracking;
+
+ if (driCompareGLXAPIVersion (20060314) >= 0)
+ pdraw->copySubBuffer = driCopySubBuffer;
/* This special default value is replaced with the configured
* default value when the drawable is first bound to a direct
* rendering context.
*/
- pdp->swap_interval = (unsigned)-1;
+ pdraw->swap_interval = (unsigned)-1;
+
+ pdp->swapBuffers = psp->DriverAPI.SwapBuffers;
- return pdp;
+ /* Add pdraw to drawable list */
+ if (!__driAddDrawable(psp->drawHash, pdraw)) {
+ /* ERROR!!! */
+ (*pdraw->destroyDrawable)(dpy, pdp);
+ _mesa_free(pdp);
+ pdp = NULL;
+ pdraw->private = NULL;
+ }
+
+ return (void *) pdp;
}
static __DRIdrawable *
-dri2CreateNewDrawable(__DRIscreen *screen, const __DRIconfig *config,
- unsigned int drawable_id, unsigned int head, void *data)
+driGetDrawable(__DRInativeDisplay *dpy, __DRIid draw, void *screenPrivate)
{
- __DRIdrawable *pdraw;
-
- pdraw = driCreateNewDrawable(screen, config, 0, 0, NULL, data);
- if (!pdraw)
- return NULL;
+ __DRIscreenPrivate *psp = (__DRIscreenPrivate *) screenPrivate;
- pdraw->dri2.drawable_id = drawable_id;
- pdraw->dri2.tail = head;
- pdraw->pBackClipRects = _mesa_malloc(sizeof *pdraw->pBackClipRects);
-
- return pdraw;
+ /*
+ ** Make sure this routine returns NULL if the drawable is not bound
+ ** to a direct rendering context!
+ */
+ return __driFindDrawable(psp->drawHash, draw);
}
-
static void
-driDestroyDrawable(__DRIdrawable *pdp)
+driDestroyDrawable(__DRInativeDisplay *dpy, void *drawablePrivate)
{
+ __DRIdrawablePrivate *pdp = (__DRIdrawablePrivate *) drawablePrivate;
__DRIscreenPrivate *psp;
+ int scrn;
if (pdp) {
psp = pdp->driScreenPriv;
+ scrn = psp->myNum;
(*psp->DriverAPI.DestroyBuffer)(pdp);
+ if ((*dri_interface->windowExists)(dpy, pdp->draw))
+ (void)(*dri_interface->destroyDrawable)(dpy, scrn, pdp->draw);
+ drmHashDelete(psp->drawHash, pdp->draw);
if (pdp->pClipRects) {
_mesa_free(pdp->pClipRects);
pdp->pClipRects = NULL;
@@ -668,6 +766,8 @@ driDestroyDrawable(__DRIdrawable *pdp)
/**
* Destroy the per-context private information.
*
+ * \param dpy the display handle.
+ * \param scrn the screen number.
* \param contextPrivate opaque pointer to the per-drawable private info.
*
* \internal
@@ -675,10 +775,14 @@ driDestroyDrawable(__DRIdrawable *pdp)
* drmDestroyContext(), and finally frees \p contextPrivate.
*/
static void
-driDestroyContext(__DRIcontext *pcp)
+driDestroyContext(__DRInativeDisplay *dpy, int scrn, void *contextPrivate)
{
+ __DRIcontextPrivate *pcp = (__DRIcontextPrivate *) contextPrivate;
+
if (pcp) {
(*pcp->driScreenPriv->DriverAPI.DestroyContext)(pcp);
+ __driGarbageCollectDrawables(pcp->driScreenPriv->drawHash);
+ (void) (*dri_interface->destroyContext)(dpy, scrn, pcp->contextID);
_mesa_free(pcp);
}
}
@@ -691,7 +795,7 @@ driDestroyContext(__DRIcontext *pcp)
* \param modes Mode used to create the new context.
* \param render_type Type of rendering target. \c GLX_RGBA is the only
* type likely to ever be supported for direct-rendering.
- * \param shared The shared context dependent methods or \c NULL if
+ * \param sharedPrivate The shared context dependent methods or \c NULL if
* non-existent.
* \param pctx DRI context to receive the context dependent methods.
*
@@ -705,18 +809,36 @@ driDestroyContext(__DRIcontext *pcp)
* context.
*
*/
-static __DRIcontext *
-driCreateNewContext(__DRIscreen *psp, const __DRIconfig *config,
- int render_type, __DRIcontext *shared,
- drm_context_t hwContext, void *data)
+static void *
+driCreateNewContext(__DRInativeDisplay *dpy, const __GLcontextModes *modes,
+ int render_type, void *sharedPrivate, __DRIcontext *pctx)
{
- __DRIcontext *pcp;
- void * const shareCtx = (shared != NULL) ? shared->driverPrivate : NULL;
+ __DRIscreen *pDRIScreen;
+ __DRIcontextPrivate *pcp;
+ __DRIcontextPrivate *pshare = (__DRIcontextPrivate *) sharedPrivate;
+ __DRIscreenPrivate *psp;
+ void * const shareCtx = (pshare != NULL) ? pshare->driverPrivate : NULL;
- pcp = _mesa_malloc(sizeof *pcp);
- if (!pcp)
+ pDRIScreen = (*dri_interface->getScreen)(dpy, modes->screen);
+ if ( (pDRIScreen == NULL) || (pDRIScreen->private == NULL) ) {
+ /* ERROR!!! */
return NULL;
+ }
+
+ psp = (__DRIscreenPrivate *)pDRIScreen->private;
+ pcp = (__DRIcontextPrivate *)_mesa_malloc(sizeof(__DRIcontextPrivate));
+ if (!pcp) {
+ return NULL;
+ }
+
+ if (! (*dri_interface->createContext)(dpy, modes->screen, modes->fbconfigID,
+ &pcp->contextID, &pcp->hHWContext)) {
+ _mesa_free(pcp);
+ return NULL;
+ }
+
+ pcp->display = dpy;
pcp->driScreenPriv = psp;
pcp->driDrawablePriv = NULL;
@@ -724,7 +846,8 @@ driCreateNewContext(__DRIscreen *psp, const __DRIconfig *config,
* context.
*/
- if (!psp->dri2.enabled && !psp->dummyContextPriv.driScreenPriv) {
+ if (!psp->dummyContextPriv.driScreenPriv) {
+ psp->dummyContextPriv.contextID = 0;
psp->dummyContextPriv.hHWContext = psp->pSAREA->dummy_context;
psp->dummyContextPriv.driScreenPriv = psp;
psp->dummyContextPriv.driDrawablePriv = NULL;
@@ -732,40 +855,21 @@ driCreateNewContext(__DRIscreen *psp, const __DRIconfig *config,
/* No other fields should be used! */
}
- pcp->hHWContext = hwContext;
+ pctx->destroyContext = driDestroyContext;
+ pctx->bindContext = driBindContext;
+ pctx->unbindContext = driUnbindContext;
- if ( !(*psp->DriverAPI.CreateContext)(&config->modes, pcp, shareCtx) ) {
+ if ( !(*psp->DriverAPI.CreateContext)(modes, pcp, shareCtx) ) {
+ (void) (*dri_interface->destroyContext)(dpy, modes->screen,
+ pcp->contextID);
_mesa_free(pcp);
return NULL;
}
- return pcp;
-}
-
-static __DRIcontext *
-dri2CreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
- __DRIcontext *shared, void *data)
-{
- drm_context_t hwContext;
- DRM_CAS_RESULT(ret);
-
- /* DRI2 doesn't use kernel with context IDs, we just need an ID that's
- * different from the kernel context ID to make drmLock() happy. */
+ __driGarbageCollectDrawables(pcp->driScreenPriv->drawHash);
- do {
- hwContext = screen->dri2.lock->next_id;
- DRM_CAS(&screen->dri2.lock->next_id, hwContext, hwContext + 1, ret);
- } while (ret);
-
- return driCreateNewContext(screen, config, 0, shared, hwContext, data);
-}
-
-static int
-driCopyContext(__DRIcontext *dest, __DRIcontext *src, unsigned long mask)
-{
- return GL_FALSE;
+ return pcp;
}
-
/*@}*/
@@ -785,8 +889,10 @@ driCopyContext(__DRIcontext *dest, __DRIcontext *src, unsigned long mask)
* This function calls __DriverAPIRec::DestroyScreen on \p screenPrivate, calls
* drmClose(), and finally frees \p screenPrivate.
*/
-static void driDestroyScreen(__DRIscreen *psp)
+static void driDestroyScreen(__DRInativeDisplay *dpy, int scrn, void *screenPrivate)
{
+ __DRIscreenPrivate *psp = (__DRIscreenPrivate *) screenPrivate;
+
if (psp) {
/* No interaction with the X-server is possible at this point. This
* routine is called after XCloseDisplay, so there is no protocol
@@ -796,44 +902,26 @@ static void driDestroyScreen(__DRIscreen *psp)
if (psp->DriverAPI.DestroyScreen)
(*psp->DriverAPI.DestroyScreen)(psp);
- if (psp->dri2.enabled) {
- drmBOUnmap(psp->fd, &psp->dri2.sareaBO);
- drmBOUnreference(psp->fd, &psp->dri2.sareaBO);
- } else {
- (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX);
- (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize);
- (void)drmCloseOnce(psp->fd);
+ (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX);
+ (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize);
+ _mesa_free(psp->pDevPriv);
+ (void)drmCloseOnce(psp->fd);
+ if ( psp->modes != NULL ) {
+ (*dri_interface->destroyContextModes)( psp->modes );
}
+ assert(psp->drawHash);
+ drmHashDestroy(psp->drawHash);
+
_mesa_free(psp);
}
}
-static void
-setupLoaderExtensions(__DRIscreen *psp,
- const __DRIextension **extensions)
-{
- int i;
-
- for (i = 0; extensions[i]; i++) {
- if (strcmp(extensions[i]->name, __DRI_GET_DRAWABLE_INFO) == 0)
- psp->getDrawableInfo = (__DRIgetDrawableInfoExtension *) extensions[i];
- if (strcmp(extensions[i]->name, __DRI_DAMAGE) == 0)
- psp->damage = (__DRIdamageExtension *) extensions[i];
- if (strcmp(extensions[i]->name, __DRI_SYSTEM_TIME) == 0)
- psp->systemTime = (__DRIsystemTimeExtension *) extensions[i];
- if (strcmp(extensions[i]->name, __DRI_LOADER) == 0)
- psp->dri2.loader = (__DRIloaderExtension *) extensions[i];
- }
-}
/**
- * This is the bootstrap function for the driver. libGL supplies all of the
- * requisite information about the system, and the driver initializes itself.
- * This routine also fills in the linked list pointed to by \c driver_modes
- * with the \c __GLcontextModes that the driver can support for windows or
- * pbuffers.
+ * Utility function used to create a new driver-private screen structure.
*
+ * \param dpy Display pointer
* \param scrn Index of the screen
* \param psc DRI screen data (not driver private)
* \param modes Linked list of known display modes. This list is, at a
@@ -854,29 +942,44 @@ setupLoaderExtensions(__DRIscreen *psp,
* driver and libGL.
* \param driverAPI Driver API functions used by other routines in dri_util.c.
*
- * \note There is no need to check the minimum API version in this
- * function. Since the name of this function is versioned, it is
- * impossible for a loader that is too old to even load this driver.
+ * \note
+ * There is no need to check the minimum API version in this function. Since
+ * the \c __driCreateNewScreen function is versioned, it is impossible for a
+ * loader that is too old to even load this driver.
*/
-static __DRIscreen *
-driCreateNewScreen(int scrn,
- const __DRIversion *ddx_version,
- const __DRIversion *dri_version,
- const __DRIversion *drm_version,
- const __DRIframebuffer *frame_buffer,
- drmAddress pSAREA, int fd,
- const __DRIextension **extensions,
- const __DRIconfig ***driver_modes,
- void *loaderPrivate)
+__DRIscreenPrivate *
+__driUtilCreateNewScreen(__DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
+ __GLcontextModes * modes,
+ const __DRIversion * ddx_version,
+ const __DRIversion * dri_version,
+ const __DRIversion * drm_version,
+ const __DRIframebuffer * frame_buffer,
+ drm_sarea_t *pSAREA,
+ int fd,
+ int internal_api_version,
+ const struct __DriverAPIRec *driverAPI)
{
- static const __DRIextension *emptyExtensionList[] = { NULL };
- __DRIscreen *psp;
+ __DRIscreenPrivate *psp;
+
+
+ api_ver = internal_api_version;
+
+ psp = (__DRIscreenPrivate *)_mesa_malloc(sizeof(__DRIscreenPrivate));
+ if (!psp) {
+ return NULL;
+ }
- psp = _mesa_malloc(sizeof *psp);
- if (!psp)
+ /* Create the hash table */
+ psp->drawHash = drmHashCreate();
+ if ( psp->drawHash == NULL ) {
+ _mesa_free( psp );
return NULL;
+ }
- setupLoaderExtensions(psp, extensions);
+ psp->display = dpy;
+ psp->myNum = scrn;
+ psp->psc = psc;
+ psp->modes = modes;
/*
** NOT_DONE: This is used by the X server to detect when the client
@@ -885,12 +988,20 @@ driCreateNewScreen(int scrn,
*/
psp->drawLockID = 1;
- psp->drm_version = *drm_version;
- psp->ddx_version = *ddx_version;
- psp->dri_version = *dri_version;
+ psp->drmMajor = drm_version->major;
+ psp->drmMinor = drm_version->minor;
+ psp->drmPatch = drm_version->patch;
+ psp->ddxMajor = ddx_version->major;
+ psp->ddxMinor = ddx_version->minor;
+ psp->ddxPatch = ddx_version->patch;
+ psp->driMajor = dri_version->major;
+ psp->driMinor = dri_version->minor;
+ psp->driPatch = dri_version->patch;
+
+ /* install driver's callback functions */
+ memcpy( &psp->DriverAPI, driverAPI, sizeof(struct __DriverAPIRec) );
psp->pSAREA = pSAREA;
- psp->lock = (drmLock *) &psp->pSAREA->lock;
psp->pFB = frame_buffer->base;
psp->fbSize = frame_buffer->size;
@@ -901,10 +1012,7 @@ driCreateNewScreen(int scrn,
psp->pDevPriv = frame_buffer->dev_priv;
psp->fbBPP = psp->fbStride * 8 / frame_buffer->width;
- psp->extensions = emptyExtensionList;
psp->fd = fd;
- psp->myNum = scrn;
- psp->dri2.enabled = GL_FALSE;
/*
** Do not init dummy context here; actual initialization will be
@@ -913,143 +1021,63 @@ driCreateNewScreen(int scrn,
*/
psp->dummyContextPriv.driScreenPriv = NULL;
- psp->DriverAPI = driDriverAPI;
-
- *driver_modes = driDriverAPI.InitScreen(psp);
- if (*driver_modes == NULL) {
- _mesa_free(psp);
- return NULL;
- }
-
- return psp;
-}
-
-
-static __DRIscreen *
-dri2CreateNewScreen(int scrn, int fd, unsigned int sarea_handle,
- const __DRIextension **extensions,
- const __DRIconfig ***driver_configs, void *data)
-{
- static const __DRIextension *emptyExtensionList[] = { NULL };
- __DRIscreen *psp;
- unsigned int *p;
- drmVersionPtr version;
-
- if (driDriverAPI.InitScreen2 == NULL)
- return NULL;
-
- psp = _mesa_malloc(sizeof(*psp));
- if (!psp)
- return NULL;
-
- setupLoaderExtensions(psp, extensions);
-
- version = drmGetVersion(fd);
- if (version) {
- psp->drm_version.major = version->version_major;
- psp->drm_version.minor = version->version_minor;
- psp->drm_version.patch = version->version_patchlevel;
- drmFreeVersion(version);
- }
-
- psp->extensions = emptyExtensionList;
- psp->fd = fd;
- psp->myNum = scrn;
- psp->dri2.enabled = GL_TRUE;
-
- if (drmBOReference(psp->fd, sarea_handle, &psp->dri2.sareaBO)) {
- fprintf(stderr, "Failed to reference DRI2 sarea BO\n");
- _mesa_free(psp);
- return NULL;
- }
-
- if (drmBOMap(psp->fd, &psp->dri2.sareaBO,
- DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &psp->dri2.sarea)) {
- drmBOUnreference(psp->fd, &psp->dri2.sareaBO);
- _mesa_free(psp);
- return NULL;
- }
-
- p = psp->dri2.sarea;
- while (DRI2_SAREA_BLOCK_TYPE(*p)) {
- switch (DRI2_SAREA_BLOCK_TYPE(*p)) {
- case DRI2_SAREA_BLOCK_LOCK:
- psp->dri2.lock = (__DRILock *) p;
- break;
- case DRI2_SAREA_BLOCK_EVENT_BUFFER:
- psp->dri2.buffer = (__DRIEventBuffer *) p;
- break;
- }
- p = DRI2_SAREA_BLOCK_NEXT(p);
- }
+ psc->destroyScreen = driDestroyScreen;
+ psc->createNewDrawable = driCreateNewDrawable;
+ psc->getDrawable = driGetDrawable;
+ psc->getMSC = driGetMSC;
+ psc->createNewContext = driCreateNewContext;
- psp->lock = (drmLock *) &psp->dri2.lock->lock;
+ if (internal_api_version >= 20070121)
+ psc->setTexOffset = psp->DriverAPI.setTexOffset;
- psp->DriverAPI = driDriverAPI;
- *driver_configs = driDriverAPI.InitScreen2(psp);
- if (*driver_configs == NULL) {
- drmBOUnmap(psp->fd, &psp->dri2.sareaBO);
- drmBOUnreference(psp->fd, &psp->dri2.sareaBO);
- _mesa_free(psp);
+ if ( (psp->DriverAPI.InitDriver != NULL)
+ && !(*psp->DriverAPI.InitDriver)(psp) ) {
+ _mesa_free( psp );
return NULL;
}
- psp->DriverAPI = driDriverAPI;
return psp;
}
-static const __DRIextension **driGetExtensions(__DRIscreen *psp)
-{
- return psp->extensions;
-}
-
-const __DRIlegacyExtension driLegacyExtension = {
- { __DRI_LEGACY, __DRI_LEGACY_VERSION },
- driCreateNewScreen,
- driCreateNewDrawable,
- driCreateNewContext
-};
-
-const __DRIcoreExtension driCoreExtension = {
- { __DRI_CORE, __DRI_CORE_VERSION },
- dri2CreateNewScreen,
- driDestroyScreen,
- driGetExtensions,
- driGetConfigAttrib,
- driIndexConfigAttrib,
- dri2CreateNewDrawable,
- driDestroyDrawable,
- driSwapBuffers,
- dri2CreateNewContext,
- driCopyContext,
- driDestroyContext,
- driBindContext,
- driUnbindContext
-};
-
-/* This is the table of extensions that the loader will dlsym() for. */
-PUBLIC const __DRIextension *__driDriverExtensions[] = {
- &driCoreExtension.base,
- &driLegacyExtension.base,
- NULL
-};
-static int
-driFrameTracking(__DRIdrawable *drawable, GLboolean enable)
+/**
+ * Compare the current GLX API version with a driver supplied required version.
+ *
+ * The minimum required version is compared with the API version exported by
+ * the \c __glXGetInternalVersion function (in libGL.so).
+ *
+ * \param required_version Minimum required internal GLX API version.
+ * \return A tri-value return, as from strcmp is returned. A value less
+ * than, equal to, or greater than zero will be returned if the
+ * internal GLX API version is less than, equal to, or greater
+ * than \c required_version.
+ *
+ * \sa __glXGetInternalVersion().
+ */
+int driCompareGLXAPIVersion( GLint required_version )
{
- return GLX_BAD_CONTEXT;
+ if ( api_ver > required_version ) {
+ return 1;
+ }
+ else if ( api_ver == required_version ) {
+ return 0;
+ }
+
+ return -1;
}
+
static int
-driQueryFrameTracking(__DRIdrawable *dpriv,
- int64_t * sbc, int64_t * missedFrames,
- float * lastMissedUsage, float * usage)
+driQueryFrameTracking( __DRInativeDisplay * dpy, void * priv,
+ int64_t * sbc, int64_t * missedFrames,
+ float * lastMissedUsage, float * usage )
{
__DRIswapInfo sInfo;
int status;
int64_t ust;
- __DRIscreenPrivate *psp = dpriv->driScreenPriv;
+ __DRIdrawablePrivate * dpriv = (__DRIdrawablePrivate *) priv;
+
status = dpriv->driScreenPriv->DriverAPI.GetSwapInfo( dpriv, & sInfo );
if ( status == 0 ) {
@@ -1057,18 +1085,13 @@ driQueryFrameTracking(__DRIdrawable *dpriv,
*missedFrames = sInfo.swap_missed_count;
*lastMissedUsage = sInfo.swap_missed_usage;
- (*psp->systemTime->getUST)( & ust );
+ (*dri_interface->getUST)( & ust );
*usage = driCalculateSwapUsage( dpriv, sInfo.swap_ust, ust );
}
return status;
}
-const __DRIframeTrackingExtension driFrameTrackingExtension = {
- { __DRI_FRAME_TRACKING, __DRI_FRAME_TRACKING_VERSION },
- driFrameTracking,
- driQueryFrameTracking
-};
/**
* Calculate amount of swap interval used between GLX buffer swaps.
@@ -1106,10 +1129,11 @@ driCalculateSwapUsage( __DRIdrawablePrivate *dPriv, int64_t last_swap_ust,
int32_t d;
int interval;
float usage = 1.0;
- __DRIscreenPrivate *psp = dPriv->driScreenPriv;
- if ( (*psp->systemTime->getMSCRate)(dPriv, &n, &d, dPriv->loaderPrivate) ) {
- interval = (dPriv->swap_interval != 0) ? dPriv->swap_interval : 1;
+
+ if ( (*dri_interface->getMSCRate)( dPriv->display, dPriv->draw, &n, &d ) ) {
+ interval = (dPriv->pdraw->swap_interval != 0)
+ ? dPriv->pdraw->swap_interval : 1;
/* We want to calculate
diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h
index f2bc456307..027cb7f461 100644
--- a/src/mesa/drivers/dri/common/dri_util.h
+++ b/src/mesa/drivers/dri/common/dri_util.h
@@ -1,24 +1,3 @@
-/**
- * \file dri_util.h
- * DRI utility functions definitions.
- *
- * This module acts as glue between GLX and the actual hardware driver. A DRI
- * driver doesn't really \e have to use any of this - it's optional. But, some
- * useful stuff is done here that otherwise would have to be duplicated in most
- * drivers.
- *
- * Basically, these utility functions take care of some of the dirty details of
- * screen initialization, context creation, context binding, DRM setup, etc.
- *
- * These functions are compiled into each DRI driver so libGL.so knows nothing
- * about them.
- *
- * \sa dri_util.c.
- *
- * \author Kevin E. Martin <kevin@precisioninsight.com>
- * \author Brian Paul <brian@precisioninsight.com>
- */
-
/*
* Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
* All Rights Reserved.
@@ -44,37 +23,46 @@
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
+/**
+ * \file dri_util.h
+ * DRI utility functions definitions.
+ *
+ * This module acts as glue between GLX and the actual hardware driver. A DRI
+ * driver doesn't really \e have to use any of this - it's optional. But, some
+ * useful stuff is done here that otherwise would have to be duplicated in most
+ * drivers.
+ *
+ * Basically, these utility functions take care of some of the dirty details of
+ * screen initialization, context creation, context binding, DRM setup, etc.
+ *
+ * These functions are compiled into each DRI driver so libGL.so knows nothing
+ * about them.
+ *
+ * \sa dri_util.c.
+ *
+ * \author Kevin E. Martin <kevin@precisioninsight.com>
+ * \author Brian Paul <brian@precisioninsight.com>
+ */
#ifndef _DRI_UTIL_H_
#define _DRI_UTIL_H_
#include <GL/gl.h>
-#include <drm.h>
-#include <drm_sarea.h>
-#include <xf86drm.h>
+#include "drm.h"
+#include "drm_sarea.h"
+#include "xf86drm.h"
#include "GL/internal/glcore.h"
#include "GL/internal/dri_interface.h"
-#include "GL/internal/dri_sarea.h"
#define GLX_BAD_CONTEXT 5
+typedef struct __DRIdisplayPrivateRec __DRIdisplayPrivate;
+typedef struct __DRIscreenPrivateRec __DRIscreenPrivate;
+typedef struct __DRIcontextPrivateRec __DRIcontextPrivate;
+typedef struct __DRIdrawablePrivateRec __DRIdrawablePrivate;
typedef struct __DRIswapInfoRec __DRIswapInfo;
+typedef struct __DRIutilversionRec2 __DRIutilversion2;
-/* Typedefs to avoid rewriting the world. */
-typedef struct __DRIscreenRec __DRIscreenPrivate;
-typedef struct __DRIdrawableRec __DRIdrawablePrivate;
-typedef struct __DRIcontextRec __DRIcontextPrivate;
-
-/**
- * Extensions.
- */
-extern const __DRIlegacyExtension driLegacyExtension;
-extern const __DRIcoreExtension driCoreExtension;
-extern const __DRIextension driReadDrawableExtension;
-extern const __DRIcopySubBufferExtension driCopySubBufferExtension;
-extern const __DRIswapControlExtension driSwapControlExtension;
-extern const __DRIframeTrackingExtension driFrameTrackingExtension;
-extern const __DRImediaStreamCounterExtension driMediaStreamCounterExtension;
/**
* Used by DRI_VALIDATE_DRAWABLE_INFO
@@ -90,7 +78,7 @@ extern const __DRImediaStreamCounterExtension driMediaStreamCounterExtension;
/**
* Utility macro to validate the drawable information.
*
- * See __DRIdrawable::pStamp and __DRIdrawable::lastStamp.
+ * See __DRIdrawablePrivate::pStamp and __DRIdrawablePrivate::lastStamp.
*/
#define DRI_VALIDATE_DRAWABLE_INFO(psp, pdp) \
do { \
@@ -119,103 +107,94 @@ do { \
* this structure.
*/
struct __DriverAPIRec {
- const __DRIconfig **(*InitScreen) (__DRIscreen * priv);
-
+ /**
+ * Driver initialization callback
+ */
+ GLboolean (*InitDriver)(__DRIscreenPrivate *driScrnPriv);
+
/**
* Screen destruction callback
*/
- void (*DestroyScreen)(__DRIscreen *driScrnPriv);
+ void (*DestroyScreen)(__DRIscreenPrivate *driScrnPriv);
/**
* Context creation callback
*/
GLboolean (*CreateContext)(const __GLcontextModes *glVis,
- __DRIcontext *driContextPriv,
+ __DRIcontextPrivate *driContextPriv,
void *sharedContextPrivate);
/**
* Context destruction callback
*/
- void (*DestroyContext)(__DRIcontext *driContextPriv);
+ void (*DestroyContext)(__DRIcontextPrivate *driContextPriv);
/**
* Buffer (drawable) creation callback
*/
- GLboolean (*CreateBuffer)(__DRIscreen *driScrnPriv,
- __DRIdrawable *driDrawPriv,
+ GLboolean (*CreateBuffer)(__DRIscreenPrivate *driScrnPriv,
+ __DRIdrawablePrivate *driDrawPriv,
const __GLcontextModes *glVis,
GLboolean pixmapBuffer);
/**
* Buffer (drawable) destruction callback
*/
- void (*DestroyBuffer)(__DRIdrawable *driDrawPriv);
+ void (*DestroyBuffer)(__DRIdrawablePrivate *driDrawPriv);
/**
* Buffer swapping callback
*/
- void (*SwapBuffers)(__DRIdrawable *driDrawPriv);
+ void (*SwapBuffers)(__DRIdrawablePrivate *driDrawPriv);
/**
* Context activation callback
*/
- GLboolean (*MakeCurrent)(__DRIcontext *driContextPriv,
- __DRIdrawable *driDrawPriv,
- __DRIdrawable *driReadPriv);
+ GLboolean (*MakeCurrent)(__DRIcontextPrivate *driContextPriv,
+ __DRIdrawablePrivate *driDrawPriv,
+ __DRIdrawablePrivate *driReadPriv);
/**
* Context unbinding callback
*/
- GLboolean (*UnbindContext)(__DRIcontext *driContextPriv);
+ GLboolean (*UnbindContext)(__DRIcontextPrivate *driContextPriv);
/**
* Retrieves statistics about buffer swap operations. Required if
* GLX_OML_sync_control or GLX_MESA_swap_frame_usage is supported.
*/
- int (*GetSwapInfo)( __DRIdrawable *dPriv, __DRIswapInfo * sInfo );
+ int (*GetSwapInfo)( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo );
+
+ /**
+ * Required if GLX_SGI_video_sync or GLX_OML_sync_control is
+ * supported.
+ */
+ int (*GetMSC)( __DRIscreenPrivate * priv, int64_t * count );
/**
* These are required if GLX_OML_sync_control is supported.
*/
/*@{*/
- int (*WaitForMSC)( __DRIdrawable *priv, int64_t target_msc,
+ int (*WaitForMSC)( __DRIdrawablePrivate *priv, int64_t target_msc,
int64_t divisor, int64_t remainder,
int64_t * msc );
- int (*WaitForSBC)( __DRIdrawable *priv, int64_t target_sbc,
+ int (*WaitForSBC)( __DRIdrawablePrivate *priv, int64_t target_sbc,
int64_t * msc, int64_t * sbc );
- int64_t (*SwapBuffersMSC)( __DRIdrawable *priv, int64_t target_msc,
+ int64_t (*SwapBuffersMSC)( __DRIdrawablePrivate *priv, int64_t target_msc,
int64_t divisor, int64_t remainder );
/*@}*/
- void (*CopySubBuffer)(__DRIdrawable *driDrawPriv,
+ void (*CopySubBuffer)(__DRIdrawablePrivate *driDrawPriv,
int x, int y, int w, int h);
/**
- * New version of GetMSC so we can pass drawable data to the low
- * level DRM driver (e.g. pipe info). Required if
- * GLX_SGI_video_sync or GLX_OML_sync_control is supported.
+ * See corresponding field in \c __DRIscreenRec.
*/
- int (*GetDrawableMSC) ( __DRIscreen * priv,
- __DRIdrawable *drawablePrivate,
- int64_t *count);
-
-
-
- /* DRI2 Entry points */
- const __DRIconfig **(*InitScreen2) (__DRIscreen * priv);
- void (*HandleDrawableConfig)(__DRIdrawable *dPriv,
- __DRIcontext *pcp,
- __DRIDrawableConfigEvent *event);
-
- void (*HandleBufferAttach)(__DRIdrawable *dPriv,
- __DRIcontext *pcp,
- __DRIBufferAttachEvent *ba);
-
+ void (*setTexOffset)(__DRIcontext *pDRICtx, GLint texname,
+ unsigned long long offset, GLint depth, GLuint pitch);
};
-extern const struct __DriverAPIRec driDriverAPI;
-
struct __DRIswapInfoRec {
/**
@@ -251,7 +230,7 @@ struct __DRIswapInfoRec {
/**
* Per-drawable private DRI driver information.
*/
-struct __DRIdrawableRec {
+struct __DRIdrawablePrivateRec {
/**
* Kernel drawable handle
*/
@@ -265,10 +244,10 @@ struct __DRIdrawableRec {
void *driverPrivate;
/**
- * Private data from the loader. We just hold on to it and pass
- * it back when calling into loader provided functions.
+ * X's drawable ID associated with this private drawable.
*/
- void *loaderPrivate;
+ __DRIid draw;
+ __DRIdrawable *pdraw;
/**
* Reference count for number of context's currently bound to this
@@ -293,7 +272,7 @@ struct __DRIdrawableRec {
/**
* Last value of the stamp.
*
- * If this differs from the value stored at __DRIdrawable::pStamp,
+ * If this differs from the value stored at __DRIdrawablePrivate::pStamp,
* then the drawable information has been modified by the X server, and the
* drawable information (below) should be retrieved from the X server.
*/
@@ -327,56 +306,41 @@ struct __DRIdrawableRec {
/*@}*/
/**
- * \name Vertical blank tracking information
- * Used for waiting on vertical blank events.
- */
- /*@{*/
- unsigned int vblSeq;
- unsigned int vblFlags;
- /*@}*/
-
- /**
- * \name Monotonic MSC tracking
- *
- * Low level driver is responsible for updating msc_base and
- * vblSeq values so that higher level code can calculate
- * a new msc value or msc target for a WaitMSC call. The new value
- * will be:
- * msc = msc_base + get_vblank_count() - vblank_base;
- *
- * And for waiting on a value, core code will use:
- * actual_target = target_msc - msc_base + vblank_base;
+ * Pointer to context to which this drawable is currently bound.
*/
- /*@{*/
- int64_t vblank_base;
- int64_t msc_base;
- /*@}*/
+ __DRIcontextPrivate *driContextPriv;
/**
- * Pointer to context to which this drawable is currently bound.
+ * Pointer to screen on which this drawable was created.
*/
- __DRIcontext *driContextPriv;
+ __DRIscreenPrivate *driScreenPriv;
/**
- * Pointer to screen on which this drawable was created.
+ * \name Display and screen information.
+ *
+ * Basically just need these for when the locking code needs to call
+ * \c __driUtilUpdateDrawableInfo.
*/
- __DRIscreen *driScreenPriv;
+ /*@{*/
+ __DRInativeDisplay *display;
+ int screen;
+ /*@}*/
/**
- * Controls swap interval as used by GLX_SGI_swap_control and
- * GLX_MESA_swap_control.
+ * Called via glXSwapBuffers().
*/
- unsigned int swap_interval;
- struct {
- unsigned int tail;
- unsigned int drawable_id;
- } dri2;
+ void (*swapBuffers)( __DRIdrawablePrivate *dPriv );
};
/**
* Per-context private driver information.
*/
-struct __DRIcontextRec {
+struct __DRIcontextPrivateRec {
+ /**
+ * Kernel context handle used to access the device lock.
+ */
+ __DRIid contextID;
+
/**
* Kernel context handle used to access the device lock.
*/
@@ -388,30 +352,35 @@ struct __DRIcontextRec {
void *driverPrivate;
/**
- * Pointer back to the \c __DRIcontext that contains this structure.
+ * This context's display pointer.
*/
- __DRIcontext *pctx;
+ __DRInativeDisplay *display;
/**
* Pointer to drawable currently bound to this context for drawing.
*/
- __DRIdrawable *driDrawablePriv;
+ __DRIdrawablePrivate *driDrawablePriv;
/**
* Pointer to drawable currently bound to this context for reading.
*/
- __DRIdrawable *driReadablePriv;
+ __DRIdrawablePrivate *driReadablePriv;
/**
* Pointer to screen on which this context was created.
*/
- __DRIscreen *driScreenPriv;
+ __DRIscreenPrivate *driScreenPriv;
};
/**
* Per-screen private driver information.
*/
-struct __DRIscreenRec {
+struct __DRIscreenPrivateRec {
+ /**
+ * Display for this screen
+ */
+ __DRInativeDisplay *display;
+
/**
* Current screen's number
*/
@@ -422,21 +391,38 @@ struct __DRIscreenRec {
*/
struct __DriverAPIRec DriverAPI;
- const __DRIextension **extensions;
/**
+ * \name DDX version
* DDX / 2D driver version information.
+ * \todo Replace these fields with a \c __DRIversionRec.
*/
- __DRIversion ddx_version;
+ /*@{*/
+ int ddxMajor;
+ int ddxMinor;
+ int ddxPatch;
+ /*@}*/
/**
+ * \name DRI version
* DRI X extension version information.
+ * \todo Replace these fields with a \c __DRIversionRec.
*/
- __DRIversion dri_version;
+ /*@{*/
+ int driMajor;
+ int driMinor;
+ int driPatch;
+ /*@}*/
/**
+ * \name DRM version
* DRM (kernel module) version information.
+ * \todo Replace these fields with a \c __DRIversionRec.
*/
- __DRIversion drm_version;
+ /*@{*/
+ int drmMajor;
+ int drmMinor;
+ int drmPatch;
+ /*@}*/
/**
* ID used when the client sets the drawable lock.
@@ -499,7 +485,12 @@ struct __DRIscreenRec {
* context is created when the first "real" context is created on this
* screen.
*/
- __DRIcontext dummyContextPriv;
+ __DRIcontextPrivate dummyContextPriv;
+
+ /**
+ * Hash table to hold the drawable information for this screen.
+ */
+ void *drawHash;
/**
* Device-dependent private information (not stored in the SAREA).
@@ -509,45 +500,65 @@ struct __DRIscreenRec {
void *private;
/**
+ * GLX visuals / FBConfigs for this screen. These are stored as a
+ * linked list.
+ *
+ * \note
+ * This field is \b only used in conjunction with the old interfaces. If
+ * the new interfaces are used, this field will be set to \c NULL and will
+ * not be dereferenced.
+ */
+ __GLcontextModes *modes;
+
+ /**
* Pointer back to the \c __DRIscreen that contains this structure.
*/
+
__DRIscreen *psc;
+};
- /* Extensions provided by the loader. */
- const __DRIgetDrawableInfoExtension *getDrawableInfo;
- const __DRIsystemTimeExtension *systemTime;
- const __DRIdamageExtension *damage;
-
- struct {
- /* Flag to indicate that this is a DRI2 screen. Many of the above
- * fields will not be valid or initializaed in that case. */
- int enabled;
- drmBO sareaBO;
- void *sarea;
- __DRIEventBuffer *buffer;
- __DRILock *lock;
- __DRIloaderExtension *loader;
- } dri2;
-
- /* The lock actually in use, old sarea or DRI2 */
- drmLock *lock;
+
+/**
+ * Used to store a version which includes a major range instead of a single
+ * major version number.
+ */
+struct __DRIutilversionRec2 {
+ int major_min; /** min allowed Major version number. */
+ int major_max; /** max allowed Major version number. */
+ int minor; /**< Minor version number. */
+ int patch; /**< Patch-level. */
};
+
extern void
__driUtilMessage(const char *f, ...);
extern void
-__driUtilUpdateDrawableInfo(__DRIdrawable *pdp);
+__driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp);
+
+
+extern __DRIscreenPrivate * __driUtilCreateNewScreen( __DRInativeDisplay *dpy,
+ int scrn, __DRIscreen *psc, __GLcontextModes * modes,
+ const __DRIversion * ddx_version, const __DRIversion * dri_version,
+ const __DRIversion * drm_version, const __DRIframebuffer * frame_buffer,
+ drm_sarea_t *pSAREA, int fd, int internal_api_version,
+ const struct __DriverAPIRec *driverAPI );
+/* Test the version of the internal GLX API. Returns a value like strcmp. */
extern int
-__driParseEvents(__DRIcontext *psp, __DRIdrawable *pdp);
+driCompareGLXAPIVersion( GLint required_version );
extern float
-driCalculateSwapUsage( __DRIdrawable *dPriv,
+driCalculateSwapUsage( __DRIdrawablePrivate *dPriv,
int64_t last_swap_ust, int64_t current_ust );
-extern GLint
-driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 );
+/**
+ * Pointer to the \c __DRIinterfaceMethods passed to the driver by the loader.
+ *
+ * This pointer is set in the driver's \c __driCreateNewScreen function and
+ * is defined in dri_util.c.
+ */
+extern const __DRIinterfaceMethods * dri_interface;
#endif /* _DRI_UTIL_H_ */
diff --git a/src/mesa/drivers/dri/common/drirenderbuffer.c b/src/mesa/drivers/dri/common/drirenderbuffer.c
index d36af3e5be..d34da53479 100644
--- a/src/mesa/drivers/dri/common/drirenderbuffer.c
+++ b/src/mesa/drivers/dri/common/drirenderbuffer.c
@@ -209,6 +209,8 @@ driUpdateFramebufferSize(GLcontext *ctx, const __DRIdrawablePrivate *dPriv)
struct gl_framebuffer *fb = (struct gl_framebuffer *) dPriv->driverPrivate;
if (fb && (dPriv->w != fb->Width || dPriv->h != fb->Height)) {
ctx->Driver.ResizeBuffers(ctx, fb, dPriv->w, dPriv->h);
+ /* if the driver needs the hw lock for ResizeBuffers, the drawable
+ might have changed again by now */
assert(fb->Width == dPriv->w);
assert(fb->Height == dPriv->h);
}
diff --git a/src/mesa/drivers/dri/common/spantmp2.h b/src/mesa/drivers/dri/common/spantmp2.h
index 53f5f846a0..50f3cf5581 100644
--- a/src/mesa/drivers/dri/common/spantmp2.h
+++ b/src/mesa/drivers/dri/common/spantmp2.h
@@ -114,7 +114,7 @@
do { \
GLuint p = *(volatile GLuint *) GET_PTR(_x, _y); \
__asm__ __volatile__( "bswap %0; rorl $8, %0" \
- : "=r" (p) : "0" (p) ); \
+ : "=r" (p) : "r" (p) ); \
((GLuint *)rgba)[0] = p; \
} while (0)
# elif defined( MESA_BIG_ENDIAN )
diff --git a/src/mesa/drivers/dri/common/utils.c b/src/mesa/drivers/dri/common/utils.c
index 7fbe0d855d..6a189e7285 100644
--- a/src/mesa/drivers/dri/common/utils.c
+++ b/src/mesa/drivers/dri/common/utils.c
@@ -419,6 +419,21 @@ driCheckDriDdxDrmVersions2(const char * driver_name,
drmActual, drmExpected);
}
+
+
+GLint
+driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 )
+{
+ if (rect2.x1 > rect1.x1) rect1.x1 = rect2.x1;
+ if (rect2.x2 < rect1.x2) rect1.x2 = rect2.x2;
+ if (rect2.y1 > rect1.y1) rect1.y1 = rect2.y1;
+ if (rect2.y2 < rect1.y2) rect1.y2 = rect2.y2;
+
+ if (rect1.x1 > rect1.x2 || rect1.y1 > rect1.y2) return 0;
+
+ return (rect1.x2 - rect1.x1) * (rect1.y2 - rect1.y1);
+}
+
GLboolean driClipRectToFramebuffer( const GLframebuffer *buffer,
GLint *x, GLint *y,
GLsizei *width, GLsizei *height )
@@ -452,6 +467,8 @@ GLboolean driClipRectToFramebuffer( const GLframebuffer *buffer,
return GL_TRUE;
}
+
+
/**
* Creates a set of \c __GLcontextModes that a driver will expose.
*
@@ -519,99 +536,86 @@ GLboolean driClipRectToFramebuffer( const GLframebuffer *buffer,
* \c GL_UNSIGNED_3BYTE_8_8_8, \c GL_4FLOAT_32_32_32_32,
* \c GL_4HALF_16_16_16_16, etc. We can cross that bridge when we come to it.
*/
-__DRIconfig **
-driCreateConfigs(GLenum fb_format, GLenum fb_type,
- const u_int8_t * depth_bits, const u_int8_t * stencil_bits,
- unsigned num_depth_stencil_bits,
- const GLenum * db_modes, unsigned num_db_modes)
+GLboolean
+driFillInModes( __GLcontextModes ** ptr_to_modes,
+ GLenum fb_format, GLenum fb_type,
+ const u_int8_t * depth_bits, const u_int8_t * stencil_bits,
+ unsigned num_depth_stencil_bits,
+ const GLenum * db_modes, unsigned num_db_modes,
+ int visType )
{
- static const u_int8_t bits_table[4][4] = {
+ static const u_int8_t bits_table[3][4] = {
/* R G B A */
- { 3, 3, 2, 0 }, /* Any GL_UNSIGNED_BYTE_3_3_2 */
{ 5, 6, 5, 0 }, /* Any GL_UNSIGNED_SHORT_5_6_5 */
{ 8, 8, 8, 0 }, /* Any RGB with any GL_UNSIGNED_INT_8_8_8_8 */
{ 8, 8, 8, 8 } /* Any RGBA with any GL_UNSIGNED_INT_8_8_8_8 */
};
- static const u_int32_t masks_table_rgb[6][4] = {
- { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 3_3_2 */
- { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 2_3_3_REV */
+ /* The following arrays are all indexed by the fb_type masked with 0x07.
+ * Given the four supported fb_type values, this results in valid array
+ * indices of 3, 4, 5, and 7.
+ */
+ static const u_int32_t masks_table_rgb[8][4] = {
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5 */
{ 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5_REV */
{ 0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000 }, /* 8_8_8_8 */
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 } /* 8_8_8_8_REV */
};
- static const u_int32_t masks_table_rgba[6][4] = {
- { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 3_3_2 */
- { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 2_3_3_REV */
+ static const u_int32_t masks_table_rgba[8][4] = {
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5 */
{ 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5_REV */
{ 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF }, /* 8_8_8_8 */
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 }, /* 8_8_8_8_REV */
};
- static const u_int32_t masks_table_bgr[6][4] = {
- { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2 */
- { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV */
+ static const u_int32_t masks_table_bgr[8][4] = {
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5 */
{ 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5_REV */
{ 0x0000FF00, 0x00FF0000, 0xFF000000, 0x00000000 }, /* 8_8_8_8 */
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 }, /* 8_8_8_8_REV */
};
- static const u_int32_t masks_table_bgra[6][4] = {
- { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2 */
- { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV */
+ static const u_int32_t masks_table_bgra[8][4] = {
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5 */
{ 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5_REV */
{ 0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF }, /* 8_8_8_8 */
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
{ 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 }, /* 8_8_8_8_REV */
};
- static const u_int8_t bytes_per_pixel[6] = {
- 1, /* 3_3_2 */
- 1, /* 2_3_3_REV */
- 2, /* 5_6_5 */
- 2, /* 5_6_5_REV */
- 4, /* 8_8_8_8 */
- 4 /* 8_8_8_8_REV */
+ static const u_int8_t bytes_per_pixel[8] = {
+ 0, 0, 0, 2, 2, 4, 0, 4
};
const u_int8_t * bits;
const u_int32_t * masks;
- int index;
- __DRIconfig **configs, **c;
- __GLcontextModes *modes;
+ const int index = fb_type & 0x07;
+ __GLcontextModes * modes = *ptr_to_modes;
unsigned i;
unsigned j;
unsigned k;
- unsigned num_modes;
- unsigned num_accum_bits = 2;
-
- switch ( fb_type ) {
- case GL_UNSIGNED_BYTE_3_3_2:
- index = 0;
- break;
- case GL_UNSIGNED_BYTE_2_3_3_REV:
- index = 1;
- break;
- case GL_UNSIGNED_SHORT_5_6_5:
- index = 2;
- break;
- case GL_UNSIGNED_SHORT_5_6_5_REV:
- index = 3;
- break;
- case GL_UNSIGNED_INT_8_8_8_8:
- index = 4;
- break;
- case GL_UNSIGNED_INT_8_8_8_8_REV:
- index = 5;
- break;
- default:
- fprintf( stderr, "[%s:%u] Unknown framebuffer type 0x%04x.\n",
- __FUNCTION__, __LINE__, fb_type );
- return NULL;
+
+
+ if ( bytes_per_pixel[ index ] == 0 ) {
+ fprintf( stderr, "[%s:%u] Framebuffer type 0x%04x has 0 bytes per pixel.\n",
+ __FUNCTION__, __LINE__, fb_type );
+ return GL_FALSE;
}
@@ -623,55 +627,40 @@ driCreateConfigs(GLenum fb_format, GLenum fb_type,
switch ( fb_format ) {
case GL_RGB:
+ bits = (bytes_per_pixel[ index ] == 2)
+ ? bits_table[0] : bits_table[1];
masks = masks_table_rgb[ index ];
break;
case GL_RGBA:
+ bits = (bytes_per_pixel[ index ] == 2)
+ ? bits_table[0] : bits_table[2];
masks = masks_table_rgba[ index ];
break;
case GL_BGR:
+ bits = (bytes_per_pixel[ index ] == 2)
+ ? bits_table[0] : bits_table[1];
masks = masks_table_bgr[ index ];
break;
case GL_BGRA:
+ bits = (bytes_per_pixel[ index ] == 2)
+ ? bits_table[0] : bits_table[2];
masks = masks_table_bgra[ index ];
break;
default:
- fprintf( stderr, "[%s:%u] Unknown framebuffer format 0x%04x.\n",
- __FUNCTION__, __LINE__, fb_format );
- return NULL;
- }
-
- switch ( bytes_per_pixel[ index ] ) {
- case 1:
- bits = bits_table[0];
- break;
- case 2:
- bits = bits_table[1];
- break;
- default:
- bits = ((fb_format == GL_RGB) || (fb_format == GL_BGR))
- ? bits_table[2]
- : bits_table[3];
- break;
+ fprintf( stderr, "[%s:%u] Framebuffer format 0x%04x is not GL_RGB, GL_RGBA, GL_BGR, or GL_BGRA.\n",
+ __FUNCTION__, __LINE__, fb_format );
+ return GL_FALSE;
}
- num_modes = num_depth_stencil_bits * num_db_modes * num_accum_bits;
- configs = _mesa_calloc((num_modes + 1) * sizeof *configs);
- if (configs == NULL)
- return NULL;
- c = configs;
for ( k = 0 ; k < num_depth_stencil_bits ; k++ ) {
for ( i = 0 ; i < num_db_modes ; i++ ) {
- for ( j = 0 ; j < num_accum_bits ; j++ ) {
- *c = _mesa_malloc (sizeof **c);
- modes = &(*c)->modes;
- c++;
+ for ( j = 0 ; j < 2 ; j++ ) {
- memset(modes, 0, sizeof *modes);
modes->redBits = bits[0];
modes->greenBits = bits[1];
modes->blueBits = bits[2];
@@ -692,13 +681,7 @@ driCreateConfigs(GLenum fb_format, GLenum fb_type,
modes->stencilBits = stencil_bits[k];
modes->depthBits = depth_bits[k];
- modes->transparentPixel = GLX_NONE;
- modes->transparentRed = GLX_DONT_CARE;
- modes->transparentGreen = GLX_DONT_CARE;
- modes->transparentBlue = GLX_DONT_CARE;
- modes->transparentAlpha = GLX_DONT_CARE;
- modes->transparentIndex = GLX_DONT_CARE;
- modes->visualType = GLX_DONT_CARE;
+ modes->visualType = visType;
modes->renderType = GLX_RGBA_BIT;
modes->drawableType = GLX_WINDOW_BIT;
modes->rgbMode = GL_TRUE;
@@ -718,155 +701,11 @@ driCreateConfigs(GLenum fb_format, GLenum fb_type,
modes->haveDepthBuffer = (modes->depthBits > 0);
modes->haveStencilBuffer = (modes->stencilBits > 0);
- modes->bindToTextureRgb = GL_TRUE;
- modes->bindToTextureRgba = GL_TRUE;
- modes->bindToMipmapTexture = GL_FALSE;
- modes->bindToTextureTargets = modes->rgbMode ?
- __DRI_ATTRIB_TEXTURE_1D_BIT |
- __DRI_ATTRIB_TEXTURE_2D_BIT |
- __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT :
- 0;
+ modes = modes->next;
}
}
}
- *c = NULL;
-
- return configs;
-}
-
-const __DRIconfig **driConcatConfigs(__DRIconfig **a, __DRIconfig **b)
-{
- const __DRIconfig **all;
- int i, j, index;
-
- i = 0;
- while (a[i] != NULL)
- i++;
- j = 0;
- while (b[j] != NULL)
- j++;
-
- all = _mesa_malloc((i + j + 1) * sizeof *all);
- index = 0;
- for (i = 0; a[i] != NULL; i++)
- all[index++] = a[i];
- for (j = 0; b[j] != NULL; j++)
- all[index++] = b[j];
- all[index++] = NULL;
-
- _mesa_free(a);
- _mesa_free(b);
-
- return all;
-}
-
-#define __ATTRIB(attrib, field) \
- { attrib, offsetof(__GLcontextModes, field) }
-
-static const struct { unsigned int attrib, offset; } attribMap[] = {
- __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE, rgbBits),
- __ATTRIB(__DRI_ATTRIB_LEVEL, level),
- __ATTRIB(__DRI_ATTRIB_RED_SIZE, redBits),
- __ATTRIB(__DRI_ATTRIB_GREEN_SIZE, greenBits),
- __ATTRIB(__DRI_ATTRIB_BLUE_SIZE, blueBits),
- __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE, alphaBits),
- __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE, depthBits),
- __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE, stencilBits),
- __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE, accumRedBits),
- __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE, accumGreenBits),
- __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE, accumBlueBits),
- __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE, accumAlphaBits),
- __ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS, sampleBuffers),
- __ATTRIB(__DRI_ATTRIB_SAMPLES, samples),
- __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER, doubleBufferMode),
- __ATTRIB(__DRI_ATTRIB_STEREO, stereoMode),
- __ATTRIB(__DRI_ATTRIB_AUX_BUFFERS, numAuxBuffers),
- __ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE, transparentPixel),
- __ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE, transparentPixel),
- __ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE, transparentRed),
- __ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE, transparentGreen),
- __ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE, transparentBlue),
- __ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE, transparentAlpha),
- __ATTRIB(__DRI_ATTRIB_FLOAT_MODE, floatMode),
- __ATTRIB(__DRI_ATTRIB_RED_MASK, redMask),
- __ATTRIB(__DRI_ATTRIB_GREEN_MASK, greenMask),
- __ATTRIB(__DRI_ATTRIB_BLUE_MASK, blueMask),
- __ATTRIB(__DRI_ATTRIB_ALPHA_MASK, alphaMask),
- __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH, maxPbufferWidth),
- __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT, maxPbufferHeight),
- __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS, maxPbufferPixels),
- __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH, optimalPbufferWidth),
- __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT, optimalPbufferHeight),
- __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod),
- __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb),
- __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA, bindToTextureRgba),
- __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE, bindToMipmapTexture),
- __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS, bindToTextureTargets),
- __ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted),
-
- /* The struct field doesn't matter here, these are handled by the
- * switch in driGetConfigAttribIndex. We need them in the array
- * so the iterator includes them though.*/
- __ATTRIB(__DRI_ATTRIB_RENDER_TYPE, level),
- __ATTRIB(__DRI_ATTRIB_CONFIG_CAVEAT, level),
- __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, level)
-};
-
-#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
-
-static int
-driGetConfigAttribIndex(const __DRIconfig *config,
- unsigned int index, unsigned int *value)
-{
- switch (attribMap[index].attrib) {
- case __DRI_ATTRIB_RENDER_TYPE:
- if (config->modes.rgbMode)
- *value = __DRI_ATTRIB_RGBA_BIT;
- else
- *value = __DRI_ATTRIB_COLOR_INDEX_BIT;
- break;
- case __DRI_ATTRIB_CONFIG_CAVEAT:
- if (config->modes.visualRating == GLX_NON_CONFORMANT_CONFIG)
- *value = __DRI_ATTRIB_NON_CONFORMANT_CONFIG;
- else if (config->modes.visualRating == GLX_SLOW_CONFIG)
- *value = __DRI_ATTRIB_SLOW_BIT;
- else
- *value = 0;
- break;
- case __DRI_ATTRIB_SWAP_METHOD:
- break;
-
- default:
- *value = *(unsigned int *)
- ((char *) &config->modes + attribMap[index].offset);
-
- break;
- }
+ *ptr_to_modes = modes;
return GL_TRUE;
}
-
-int
-driGetConfigAttrib(const __DRIconfig *config,
- unsigned int attrib, unsigned int *value)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(attribMap); i++)
- if (attribMap[i].attrib == attrib)
- return driGetConfigAttribIndex(config, i, value);
-
- return GL_FALSE;
-}
-
-int
-driIndexConfigAttrib(const __DRIconfig *config, int index,
- unsigned int *attrib, unsigned int *value)
-{
- if (index >= 0 && index < ARRAY_SIZE(attribMap)) {
- *attrib = attribMap[index].attrib;
- return driGetConfigAttribIndex(config, index, value);
- }
-
- return GL_FALSE;
-}
diff --git a/src/mesa/drivers/dri/common/utils.h b/src/mesa/drivers/dri/common/utils.h
index 9ac3b51447..b28b895627 100644
--- a/src/mesa/drivers/dri/common/utils.h
+++ b/src/mesa/drivers/dri/common/utils.h
@@ -28,11 +28,8 @@
#ifndef DRI_DEBUG_H
#define DRI_DEBUG_H
-#include <GL/gl.h>
-#include <GL/internal/dri_interface.h>
#include "context.h"
-
-typedef struct __DRIutilversionRec2 __DRIutilversion2;
+#include "dri_util.h"
struct dri_debug_control {
const char * string;
@@ -86,17 +83,6 @@ struct dri_extension {
const struct dri_extension_function * functions;
};
-/**
- * Used to store a version which includes a major range instead of a single
- * major version number.
- */
-struct __DRIutilversionRec2 {
- int major_min; /** min allowed Major version number. */
- int major_max; /** max allowed Major version number. */
- int minor; /**< Minor version number. */
- int patch; /**< Patch-level. */
-};
-
extern unsigned driParseDebugString( const char * debug,
const struct dri_debug_control * control );
@@ -119,27 +105,16 @@ extern GLboolean driCheckDriDdxDrmVersions3(const char * driver_name,
const __DRIversion * ddxActual, const __DRIutilversion2 * ddxExpected,
const __DRIversion * drmActual, const __DRIversion * drmExpected);
+extern GLint driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 );
+
extern GLboolean driClipRectToFramebuffer( const GLframebuffer *buffer,
GLint *x, GLint *y,
GLsizei *width, GLsizei *height );
-struct __DRIconfigRec {
- __GLcontextModes modes;
-};
-
-extern __DRIconfig **
-driCreateConfigs(GLenum fb_format, GLenum fb_type,
- const u_int8_t * depth_bits, const u_int8_t * stencil_bits,
- unsigned num_depth_stencil_bits,
- const GLenum * db_modes, unsigned num_db_modes);
-
-const __DRIconfig **driConcatConfigs(__DRIconfig **a, __DRIconfig **b);
-
-int
-driGetConfigAttrib(const __DRIconfig *config,
- unsigned int attrib, unsigned int *value);
-int
-driIndexConfigAttrib(const __DRIconfig *config, int index,
- unsigned int *attrib, unsigned int *value);
+extern GLboolean driFillInModes( __GLcontextModes ** modes,
+ GLenum fb_format, GLenum fb_type,
+ const u_int8_t * depth_bits, const u_int8_t * stencil_bits,
+ unsigned num_depth_stencil_bits,
+ const GLenum * db_modes, unsigned num_db_modes, int visType );
#endif /* DRI_DEBUG_H */
diff --git a/src/mesa/drivers/dri/common/vblank.c b/src/mesa/drivers/dri/common/vblank.c
index 0008ab1c34..094950d362 100644
--- a/src/mesa/drivers/dri/common/vblank.c
+++ b/src/mesa/drivers/dri/common/vblank.c
@@ -34,16 +34,6 @@
#include "vblank.h"
#include "xmlpool.h"
-static unsigned int msc_to_vblank(__DRIdrawablePrivate * dPriv, int64_t msc)
-{
- return (unsigned int)(msc - dPriv->msc_base + dPriv->vblank_base);
-}
-
-static int64_t vblank_to_msc(__DRIdrawablePrivate * dPriv, unsigned int vblank)
-{
- return (int64_t)(vblank - dPriv->vblank_base + dPriv->msc_base);
-}
-
/****************************************************************************/
/**
@@ -51,7 +41,7 @@ static int64_t vblank_to_msc(__DRIdrawablePrivate * dPriv, unsigned int vblank)
*
* Stores the 64-bit count of vertical refreshes since some (arbitrary)
* point in time in \c count. Unless the value wraps around, which it
- * may, it will never decrease for a given drawable.
+ * may, it will never decrease.
*
* \warning This function is called from \c glXGetVideoSyncSGI, which expects
* a \c count of type \c unsigned (32-bit), and \c glXGetSyncValuesOML, which
@@ -59,14 +49,11 @@ static int64_t vblank_to_msc(__DRIdrawablePrivate * dPriv, unsigned int vblank)
* currently always returns a \c sequence of type \c unsigned.
*
* \param priv Pointer to the DRI screen private struct.
- * \param dPriv Pointer to the DRI drawable private struct
* \param count Storage to hold MSC counter.
* \return Zero is returned on success. A negative errno value
* is returned on failure.
*/
-int driDrawableGetMSC32( __DRIscreenPrivate * priv,
- __DRIdrawablePrivate * dPriv,
- int64_t * count)
+int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count )
{
drmVBlank vbl;
int ret;
@@ -75,21 +62,14 @@ int driDrawableGetMSC32( __DRIscreenPrivate * priv,
vbl.request.type = DRM_VBLANK_RELATIVE;
vbl.request.sequence = 0;
- if ( dPriv && dPriv->vblFlags & VBLANK_FLAG_SECONDARY )
- vbl.request.type |= DRM_VBLANK_SECONDARY;
ret = drmWaitVBlank( priv->fd, &vbl );
-
- if (dPriv) {
- *count = vblank_to_msc(dPriv, vbl.reply.sequence);
- } else {
- /* Old driver (no knowledge of drawable MSC callback) */
- *count = vbl.reply.sequence;
- }
+ *count = (int64_t)vbl.reply.sequence;
return ret;
}
+
/****************************************************************************/
/**
* Wait for a specified refresh count. This implements most of the
@@ -142,9 +122,7 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv,
*/
vbl.request.type = dont_wait ? DRM_VBLANK_RELATIVE :
DRM_VBLANK_ABSOLUTE;
- vbl.request.sequence = next ? msc_to_vblank(priv, next) : 0;
- if ( priv->vblFlags & VBLANK_FLAG_SECONDARY )
- vbl.request.type |= DRM_VBLANK_SECONDARY;
+ vbl.request.sequence = next;
if ( drmWaitVBlank( priv->driScreenPriv->fd, &vbl ) != 0 ) {
/* FIXME: This doesn't seem like the right thing to return here.
@@ -152,10 +130,8 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv,
return GLX_BAD_CONTEXT;
}
- *msc = vblank_to_msc(priv, vbl.reply.sequence);
-
dont_wait = 0;
- if (target_msc != 0 && *msc == target)
+ if (target_msc != 0 && vbl.reply.sequence == target)
break;
/* Assuming the wait-done test fails, the next refresh to wait for
@@ -165,9 +141,9 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv,
* If this refresh has already happened, we add divisor to obtain
* the next refresh after the current one that will satisfy it.
*/
- r = (*msc % (unsigned int)divisor);
- next = (*msc - r + (unsigned int)remainder);
- if (next <= *msc) next += (unsigned int)divisor;
+ r = (vbl.reply.sequence % (unsigned int)divisor);
+ next = (vbl.reply.sequence - r + (unsigned int)remainder);
+ if (next <= vbl.reply.sequence) next += (unsigned int)divisor;
} while ( r != (unsigned int)remainder );
}
@@ -177,10 +153,7 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv,
*/
vbl.request.type = DRM_VBLANK_ABSOLUTE;
- vbl.request.sequence = target_msc ? msc_to_vblank(priv, target_msc) : 0;
-
- if ( priv->vblFlags & VBLANK_FLAG_SECONDARY )
- vbl.request.type |= DRM_VBLANK_SECONDARY;
+ vbl.request.sequence = target_msc;
if ( drmWaitVBlank( priv->driScreenPriv->fd, &vbl ) != 0 ) {
/* FIXME: This doesn't seem like the right thing to return here.
@@ -189,8 +162,8 @@ int driWaitForMSC32( __DRIdrawablePrivate *priv,
}
}
- *msc = vblank_to_msc(priv, vbl.reply.sequence);
-
+ *msc = (target_msc & 0xffffffff00000000LL);
+ *msc |= vbl.reply.sequence;
if ( *msc < target_msc ) {
*msc += 0x0000000100000000LL;
}
@@ -259,8 +232,8 @@ static int do_wait( drmVBlank * vbl, GLuint * vbl_seq, int fd )
if ( first_time ) {
fprintf(stderr,
"%s: drmWaitVBlank returned %d, IRQs don't seem to be"
- " working correctly.\nTry adjusting the vblank_mode"
- " configuration parameter.\n", __FUNCTION__, ret);
+ " working correctly.\nTry running with LIBGL_THROTTLE_REFRESH"
+ " and LIBL_SYNC_REFRESH unset.\n", __FUNCTION__, ret);
first_time = GL_FALSE;
}
@@ -274,42 +247,20 @@ static int do_wait( drmVBlank * vbl, GLuint * vbl_seq, int fd )
/****************************************************************************/
/**
- * Returns the default swap interval of the given drawable.
- */
-
-static unsigned
-driGetDefaultVBlankInterval( const __DRIdrawablePrivate *priv )
-{
- if ( (priv->vblFlags & (VBLANK_FLAG_THROTTLE | VBLANK_FLAG_SYNC)) != 0 ) {
- return 1;
- }
- else {
- return 0;
- }
-}
-
-
-/****************************************************************************/
-/**
* Sets the default swap interval when the drawable is first bound to a
* direct rendering context.
*/
-void driDrawableInitVBlank( __DRIdrawablePrivate *priv )
+void driDrawableInitVBlank( __DRIdrawablePrivate *priv, GLuint flags,
+ GLuint *vbl_seq )
{
- if ( priv->swap_interval == (unsigned)-1 &&
- !( priv->vblFlags & VBLANK_FLAG_NO_IRQ ) ) {
+ if ( priv->pdraw->swap_interval == (unsigned)-1 ) {
/* Get current vertical blank sequence */
- drmVBlank vbl;
-
- vbl.request.type = DRM_VBLANK_RELATIVE;
- if ( priv->vblFlags & VBLANK_FLAG_SECONDARY )
- vbl.request.type |= DRM_VBLANK_SECONDARY;
- vbl.request.sequence = 0;
- do_wait( &vbl, &priv->vblSeq, priv->driScreenPriv->fd );
- priv->vblank_base = priv->vblSeq;
-
- priv->swap_interval = driGetDefaultVBlankInterval( priv );
+ drmVBlank vbl = { .request={ .type = DRM_VBLANK_RELATIVE, .sequence = 0 } };
+ do_wait( &vbl, vbl_seq, priv->driScreenPriv->fd );
+
+ priv->pdraw->swap_interval = (flags & (VBLANK_FLAG_THROTTLE |
+ VBLANK_FLAG_SYNC)) != 0 ? 1 : 0;
}
}
@@ -320,17 +271,21 @@ void driDrawableInitVBlank( __DRIdrawablePrivate *priv )
*/
unsigned
-driGetVBlankInterval( const __DRIdrawablePrivate *priv )
+driGetVBlankInterval( const __DRIdrawablePrivate *priv, GLuint flags )
{
- if ( (priv->vblFlags & VBLANK_FLAG_INTERVAL) != 0 ) {
+ if ( (flags & VBLANK_FLAG_INTERVAL) != 0 ) {
/* this must have been initialized when the drawable was first bound
* to a direct rendering context. */
- assert ( priv->swap_interval != (unsigned)-1 );
+ assert ( priv->pdraw->swap_interval != (unsigned)-1 );
- return priv->swap_interval;
+ return priv->pdraw->swap_interval;
+ }
+ else if ( (flags & (VBLANK_FLAG_THROTTLE | VBLANK_FLAG_SYNC)) != 0 ) {
+ return 1;
+ }
+ else {
+ return 0;
}
- else
- return driGetDefaultVBlankInterval( priv );
}
@@ -340,17 +295,18 @@ driGetVBlankInterval( const __DRIdrawablePrivate *priv )
*/
void
-driGetCurrentVBlank( __DRIdrawablePrivate *priv )
+driGetCurrentVBlank( const __DRIdrawablePrivate *priv, GLuint flags,
+ GLuint *vbl_seq )
{
drmVBlank vbl;
vbl.request.type = DRM_VBLANK_RELATIVE;
- if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) {
+ if ( flags & VBLANK_FLAG_SECONDARY ) {
vbl.request.type |= DRM_VBLANK_SECONDARY;
}
vbl.request.sequence = 0;
- (void) do_wait( &vbl, &priv->vblSeq, priv->driScreenPriv->fd );
+ (void) do_wait( &vbl, vbl_seq, priv->driScreenPriv->fd );
}
@@ -358,15 +314,19 @@ driGetCurrentVBlank( __DRIdrawablePrivate *priv )
/**
* Waits for the vertical blank for use with glXSwapBuffers.
*
+ * \param vbl_seq Vertical blank sequence number (MSC) after the last buffer
+ * swap. Updated after this wait.
+ * \param flags \c VBLANK_FLAG bits that control how long to wait.
* \param missed_deadline Set to \c GL_TRUE if the MSC after waiting is later
- * than the "target" based on \c priv->vblFlags. The idea is
- * that if \c missed_deadline is set, then the application is
- * not achieving its desired framerate.
+ * than the "target" based on \c flags. The idea is that if
+ * \c missed_deadline is set, then the application is not
+ * achieving its desired framerate.
* \return Zero on success, -1 on error.
*/
int
-driWaitForVBlank( __DRIdrawablePrivate *priv, GLboolean * missed_deadline )
+driWaitForVBlank( const __DRIdrawablePrivate *priv, GLuint * vbl_seq,
+ GLuint flags, GLboolean * missed_deadline )
{
drmVBlank vbl;
unsigned original_seq;
@@ -375,10 +335,10 @@ driWaitForVBlank( __DRIdrawablePrivate *priv, GLboolean * missed_deadline )
unsigned diff;
*missed_deadline = GL_FALSE;
- if ( (priv->vblFlags & (VBLANK_FLAG_INTERVAL |
- VBLANK_FLAG_THROTTLE |
- VBLANK_FLAG_SYNC)) == 0 ||
- (priv->vblFlags & VBLANK_FLAG_NO_IRQ) != 0 ) {
+ if ( (flags & (VBLANK_FLAG_INTERVAL |
+ VBLANK_FLAG_THROTTLE |
+ VBLANK_FLAG_SYNC)) == 0 ||
+ (flags & VBLANK_FLAG_NO_IRQ) != 0 ) {
return 0;
}
@@ -389,45 +349,44 @@ driWaitForVBlank( __DRIdrawablePrivate *priv, GLboolean * missed_deadline )
*
* VBLANK_FLAG_INTERVAL and VBLANK_FLAG_THROTTLE mean to wait for at
* least one vertical blank since the last wait. Since do_wait modifies
- * priv->vblSeq, we have to save the original value of priv->vblSeq for the
+ * vbl_seq, we have to save the original value of vbl_seq for the
* VBLANK_FLAG_INTERVAL / VBLANK_FLAG_THROTTLE calculation later.
*/
- original_seq = priv->vblSeq;
- interval = driGetVBlankInterval(priv);
+ original_seq = *vbl_seq;
+ interval = driGetVBlankInterval(priv, flags);
deadline = original_seq + interval;
vbl.request.type = DRM_VBLANK_RELATIVE;
- if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) {
+ if ( flags & VBLANK_FLAG_SECONDARY ) {
vbl.request.type |= DRM_VBLANK_SECONDARY;
}
- vbl.request.sequence = ((priv->vblFlags & VBLANK_FLAG_SYNC) != 0) ? 1 : 0;
+ vbl.request.sequence = ((flags & VBLANK_FLAG_SYNC) != 0) ? 1 : 0;
- if ( do_wait( & vbl, &priv->vblSeq, priv->driScreenPriv->fd ) != 0 ) {
+ if ( do_wait( & vbl, vbl_seq, priv->driScreenPriv->fd ) != 0 ) {
return -1;
}
- diff = priv->vblSeq - deadline;
+ diff = *vbl_seq - deadline;
/* No need to wait again if we've already reached the target */
if (diff <= (1 << 23)) {
- *missed_deadline = (priv->vblFlags & VBLANK_FLAG_SYNC) ? (diff > 0) :
- GL_TRUE;
+ *missed_deadline = (flags & VBLANK_FLAG_SYNC) ? (diff > 0) : GL_TRUE;
return 0;
}
/* Wait until the target vertical blank. */
vbl.request.type = DRM_VBLANK_ABSOLUTE;
- if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) {
+ if ( flags & VBLANK_FLAG_SECONDARY ) {
vbl.request.type |= DRM_VBLANK_SECONDARY;
}
vbl.request.sequence = deadline;
- if ( do_wait( & vbl, &priv->vblSeq, priv->driScreenPriv->fd ) != 0 ) {
+ if ( do_wait( & vbl, vbl_seq, priv->driScreenPriv->fd ) != 0 ) {
return -1;
}
- diff = priv->vblSeq - deadline;
+ diff = *vbl_seq - deadline;
*missed_deadline = diff > 0 && diff <= (1 << 23);
return 0;
diff --git a/src/mesa/drivers/dri/common/vblank.h b/src/mesa/drivers/dri/common/vblank.h
index b3a0dadab1..52c1933ca5 100644
--- a/src/mesa/drivers/dri/common/vblank.h
+++ b/src/mesa/drivers/dri/common/vblank.h
@@ -45,17 +45,17 @@
*/
extern int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count );
-extern int driDrawableGetMSC32( __DRIscreenPrivate * priv,
- __DRIdrawablePrivate * drawablePrivate,
- int64_t * count);
extern int driWaitForMSC32( __DRIdrawablePrivate *priv,
int64_t target_msc, int64_t divisor, int64_t remainder, int64_t * msc );
extern GLuint driGetDefaultVBlankFlags( const driOptionCache *optionCache );
-extern void driDrawableInitVBlank ( __DRIdrawablePrivate *priv );
-extern unsigned driGetVBlankInterval( const __DRIdrawablePrivate *priv );
-extern void driGetCurrentVBlank( __DRIdrawablePrivate *priv );
-extern int driWaitForVBlank( __DRIdrawablePrivate *priv,
- GLboolean * missed_deadline );
+extern void driDrawableInitVBlank ( __DRIdrawablePrivate *priv, GLuint flags,
+ GLuint *vbl_seq );
+extern unsigned driGetVBlankInterval( const __DRIdrawablePrivate *priv,
+ GLuint flags );
+extern void driGetCurrentVBlank( const __DRIdrawablePrivate *priv,
+ GLuint flags, GLuint *vbl_seq );
+extern int driWaitForVBlank( const __DRIdrawablePrivate *priv,
+ GLuint * vbl_seq, GLuint flags, GLboolean * missed_deadline );
#undef usleep
#include <unistd.h> /* for usleep() */
diff --git a/src/mesa/drivers/dri/common/xmlconfig.c b/src/mesa/drivers/dri/common/xmlconfig.c
index 8602d47cf9..b635894fe5 100644
--- a/src/mesa/drivers/dri/common/xmlconfig.c
+++ b/src/mesa/drivers/dri/common/xmlconfig.c
@@ -279,7 +279,7 @@ static GLfloat strToF (const XML_Char *string, const XML_Char **tail) {
/** \brief Parse a value of a given type. */
static GLboolean parseValue (driOptionValue *v, driOptionType type,
const XML_Char *string) {
- const XML_Char *tail = NULL;
+ const XML_Char *tail;
/* skip leading white-space */
string += strspn (string, " \f\n\r\t\v");
switch (type) {
@@ -403,40 +403,40 @@ static GLboolean checkValue (const driOptionValue *v, const driOptionInfo *info)
/** \brief Output a warning message. */
#define XML_WARNING1(msg) do {\
__driUtilMessage ("Warning in %s line %d, column %d: "msg, data->name, \
- (int) XML_GetCurrentLineNumber(data->parser), \
- (int) XML_GetCurrentColumnNumber(data->parser)); \
+ XML_GetCurrentLineNumber(data->parser), \
+ XML_GetCurrentColumnNumber(data->parser)); \
} while (0)
#define XML_WARNING(msg,args...) do { \
__driUtilMessage ("Warning in %s line %d, column %d: "msg, data->name, \
- (int) XML_GetCurrentLineNumber(data->parser), \
- (int) XML_GetCurrentColumnNumber(data->parser), \
+ XML_GetCurrentLineNumber(data->parser), \
+ XML_GetCurrentColumnNumber(data->parser), \
args); \
} while (0)
/** \brief Output an error message. */
#define XML_ERROR1(msg) do { \
__driUtilMessage ("Error in %s line %d, column %d: "msg, data->name, \
- (int) XML_GetCurrentLineNumber(data->parser), \
- (int) XML_GetCurrentColumnNumber(data->parser)); \
+ XML_GetCurrentLineNumber(data->parser), \
+ XML_GetCurrentColumnNumber(data->parser)); \
} while (0)
#define XML_ERROR(msg,args...) do { \
__driUtilMessage ("Error in %s line %d, column %d: "msg, data->name, \
- (int) XML_GetCurrentLineNumber(data->parser), \
- (int) XML_GetCurrentColumnNumber(data->parser), \
+ XML_GetCurrentLineNumber(data->parser), \
+ XML_GetCurrentColumnNumber(data->parser), \
args); \
} while (0)
/** \brief Output a fatal error message and abort. */
#define XML_FATAL1(msg) do { \
fprintf (stderr, "Fatal error in %s line %d, column %d: "msg"\n", \
data->name, \
- (int) XML_GetCurrentLineNumber(data->parser), \
- (int) XML_GetCurrentColumnNumber(data->parser)); \
+ XML_GetCurrentLineNumber(data->parser), \
+ XML_GetCurrentColumnNumber(data->parser)); \
abort();\
} while (0)
#define XML_FATAL(msg,args...) do { \
fprintf (stderr, "Fatal error in %s line %d, column %d: "msg"\n", \
data->name, \
- (int) XML_GetCurrentLineNumber(data->parser), \
- (int) XML_GetCurrentColumnNumber(data->parser), \
+ XML_GetCurrentLineNumber(data->parser), \
+ XML_GetCurrentColumnNumber(data->parser), \
args); \
abort();\
} while (0)