summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichel Dänzer <michel@daenzer.net>2006-09-29 11:00:50 +0000
committerMichel Dänzer <michel@daenzer.net>2006-09-29 11:00:50 +0000
commit7d553984e259d7c48724b38809b58060752e1ba6 (patch)
tree5996075a2e4c1b02fb918a702e985a8de5321e05
parentd431dd49cb255c119d2234a22431a5308d083407 (diff)
Merge vsync changes from trunk.
-rw-r--r--src/mesa/drivers/dri/common/utils.c13
-rw-r--r--src/mesa/drivers/dri/common/utils.h2
-rw-r--r--src/mesa/drivers/dri/common/vblank.c129
-rw-r--r--src/mesa/drivers/dri/common/vblank.h9
-rw-r--r--src/mesa/drivers/dri/i915/intel_blit.c232
-rw-r--r--src/mesa/drivers/dri/i915/intel_buffers.c31
-rw-r--r--src/mesa/drivers/dri/i915/intel_context.c18
-rw-r--r--src/mesa/drivers/dri/i915/intel_context.h1
-rw-r--r--src/mesa/drivers/dri/i915/intel_screen.c2
-rw-r--r--src/mesa/drivers/dri/i915/server/i830_common.h15
-rw-r--r--src/mesa/drivers/dri/mach64/mach64_context.c3
-rw-r--r--src/mesa/drivers/dri/mga/mga_xmesa.c3
-rw-r--r--src/mesa/drivers/dri/r128/r128_context.c3
-rw-r--r--src/mesa/drivers/dri/r200/r200_context.c3
-rw-r--r--src/mesa/drivers/dri/r300/radeon_context.c3
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_context.c3
-rw-r--r--src/mesa/drivers/dri/unichrome/via_context.c3
17 files changed, 322 insertions, 151 deletions
diff --git a/src/mesa/drivers/dri/common/utils.c b/src/mesa/drivers/dri/common/utils.c
index e3eca86da1b..d872e11d755 100644
--- a/src/mesa/drivers/dri/common/utils.c
+++ b/src/mesa/drivers/dri/common/utils.c
@@ -419,6 +419,19 @@ driCheckDriDdxDrmVersions2(const char * driver_name,
+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 )
diff --git a/src/mesa/drivers/dri/common/utils.h b/src/mesa/drivers/dri/common/utils.h
index 26d178f7478..b2bab86e66c 100644
--- a/src/mesa/drivers/dri/common/utils.h
+++ b/src/mesa/drivers/dri/common/utils.h
@@ -106,6 +106,8 @@ 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 );
diff --git a/src/mesa/drivers/dri/common/vblank.c b/src/mesa/drivers/dri/common/vblank.c
index eebe42d96a1..e7ed545f13c 100644
--- a/src/mesa/drivers/dri/common/vblank.c
+++ b/src/mesa/drivers/dri/common/vblank.c
@@ -210,20 +210,6 @@ GLuint driGetDefaultVBlankFlags( const driOptionCache *optionCache )
/****************************************************************************/
/**
- * Sets the default swap interval when the drawable is first bound to a
- * direct rendering context.
- */
-
-void driDrawableInitVBlank( __DRIdrawablePrivate *priv, GLuint flags )
-{
- if ( priv->pdraw->swap_interval == (unsigned)-1 ) {
- priv->pdraw->swap_interval = (flags & VBLANK_FLAG_THROTTLE) != 0 ? 1 : 0;
- }
-}
-
-
-/****************************************************************************/
-/**
* Wrapper to call \c drmWaitVBlank. The main purpose of this function is to
* wrap the error message logging. The error message should only be logged
* the first time the \c drmWaitVBlank fails. If \c drmWaitVBlank is
@@ -262,6 +248,71 @@ static int do_wait( drmVBlank * vbl, GLuint * vbl_seq, int fd )
/****************************************************************************/
/**
+ * Sets the default swap interval when the drawable is first bound to a
+ * direct rendering context.
+ */
+
+void driDrawableInitVBlank( __DRIdrawablePrivate *priv, GLuint flags,
+ GLuint *vbl_seq )
+{
+ if ( priv->pdraw->swap_interval == (unsigned)-1 ) {
+ /* Get current vertical blank sequence */
+ 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;
+ }
+}
+
+
+/****************************************************************************/
+/**
+ * Returns the current swap interval of the given drawable.
+ */
+
+unsigned
+driGetVBlankInterval( const __DRIdrawablePrivate *priv, GLuint flags )
+{
+ if ( (flags & VBLANK_FLAG_INTERVAL) != 0 ) {
+ /* this must have been initialized when the drawable was first bound
+ * to a direct rendering context. */
+ assert ( priv->pdraw->swap_interval != (unsigned)-1 );
+
+ return priv->pdraw->swap_interval;
+ }
+ else if ( (flags & (VBLANK_FLAG_THROTTLE | VBLANK_FLAG_SYNC)) != 0 ) {
+ return 1;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+/****************************************************************************/
+/**
+ * Returns the current vertical blank sequence number of the given drawable.
+ */
+
+void
+driGetCurrentVBlank( const __DRIdrawablePrivate *priv, GLuint flags,
+ GLuint *vbl_seq )
+{
+ drmVBlank vbl;
+
+ vbl.request.type = DRM_VBLANK_RELATIVE;
+ if ( flags & VBLANK_FLAG_SECONDARY ) {
+ vbl.request.type |= DRM_VBLANK_SECONDARY;
+ }
+ vbl.request.sequence = 0;
+
+ (void) do_wait( &vbl, vbl_seq, priv->driScreenPriv->fd );
+}
+
+
+/****************************************************************************/
+/**
* Waits for the vertical blank for use with glXSwapBuffers.
*
* \param vbl_seq Vertical blank sequence number (MSC) after the last buffer
@@ -282,7 +333,7 @@ driWaitForVBlank( const __DRIdrawablePrivate *priv, GLuint * vbl_seq,
unsigned original_seq;
unsigned deadline;
unsigned interval;
-
+ unsigned diff;
*missed_deadline = GL_FALSE;
if ( (flags & (VBLANK_FLAG_INTERVAL |
@@ -304,44 +355,40 @@ driWaitForVBlank( const __DRIdrawablePrivate *priv, GLuint * vbl_seq,
*/
original_seq = *vbl_seq;
+ interval = driGetVBlankInterval(priv, flags);
+ deadline = original_seq + interval;
- vbl.request.sequence = ((flags & VBLANK_FLAG_SYNC) != 0) ? 1 : 0;
vbl.request.type = DRM_VBLANK_RELATIVE;
-
+ if ( flags & VBLANK_FLAG_SECONDARY ) {
+ vbl.request.type |= DRM_VBLANK_SECONDARY;
+ }
+ vbl.request.sequence = ((flags & VBLANK_FLAG_SYNC) != 0) ? 1 : 0;
+
if ( do_wait( & vbl, vbl_seq, priv->driScreenPriv->fd ) != 0 ) {
return -1;
}
-
- vbl.request.type = DRM_VBLANK_ABSOLUTE;
+ diff = *vbl_seq - deadline;
- if ( (flags & VBLANK_FLAG_INTERVAL) != 0 ) {
- interval = priv->pdraw->swap_interval;
- /* this must have been initialized when the drawable was first bound
- * to a direct rendering context. */
- assert ( interval != (unsigned)-1 );
- }
- else if ( (flags & VBLANK_FLAG_THROTTLE) != 0 ) {
- interval = 1;
- }
- else {
- interval = 0;
+ /* No need to wait again if we've already reached the target */
+ if (diff <= (1 << 23)) {
+ *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 ( flags & VBLANK_FLAG_SECONDARY ) {
+ vbl.request.type |= DRM_VBLANK_SECONDARY;
+ }
+ vbl.request.sequence = deadline;
- /* Wait until the next vertical blank. If the interval is zero, then
- * the deadline is one vertical blank after the previous wait.
- */
-
- vbl.request.sequence = original_seq + interval;
- if ( *vbl_seq < vbl.request.sequence ) {
- if ( do_wait( & vbl, vbl_seq, priv->driScreenPriv->fd ) != 0 ) {
- return -1;
- }
+ if ( do_wait( & vbl, vbl_seq, priv->driScreenPriv->fd ) != 0 ) {
+ return -1;
}
- deadline = original_seq + ((interval == 0) ? 1 : interval);
- *missed_deadline = ( *vbl_seq > 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 3dc965def1a..ec83adc78dd 100644
--- a/src/mesa/drivers/dri/common/vblank.h
+++ b/src/mesa/drivers/dri/common/vblank.h
@@ -42,12 +42,19 @@
*/
#define VBLANK_FLAG_NO_IRQ (1U << 7) /* DRM has no IRQ to wait on.
*/
+#define VBLANK_FLAG_SECONDARY (1U << 8) /* Wait for secondary vblank.
+ */
extern int driGetMSC32( __DRIscreenPrivate * priv, 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, GLuint flags );
+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 );
diff --git a/src/mesa/drivers/dri/i915/intel_blit.c b/src/mesa/drivers/dri/i915/intel_blit.c
index e55f05bd1f5..af2f60312fb 100644
--- a/src/mesa/drivers/dri/i915/intel_blit.c
+++ b/src/mesa/drivers/dri/i915/intel_blit.c
@@ -54,6 +54,7 @@ intelCopyBuffer(const __DRIdrawablePrivate * dPriv,
{
struct intel_context *intel;
+ const intelScreenPrivate *intelScreen;
GLboolean missed_target;
int64_t ust;
@@ -65,6 +66,41 @@ intelCopyBuffer(const __DRIdrawablePrivate * dPriv,
if (!intel)
return;
+ intelScreen = intel->intelScreen;
+
+ if (!rect && !intel->swap_scheduled && intelScreen->drmMinor >= 6 &&
+ !(intel->vblank_flags & VBLANK_FLAG_NO_IRQ) &&
+ intelScreen->current_rotation == 0) {
+ unsigned int interval = driGetVBlankInterval(dPriv, intel->vblank_flags);
+ unsigned int target;
+ drm_i915_vblank_swap_t swap;
+
+ swap.drawable = dPriv->hHWDrawable;
+ swap.seqtype = DRM_VBLANK_ABSOLUTE;
+ target = swap.sequence = intel->vbl_seq + interval;
+
+ if (intel->vblank_flags & VBLANK_FLAG_SYNC) {
+ swap.seqtype |= DRM_VBLANK_NEXTONMISS;
+ } else if (interval == 0) {
+ goto noschedule;
+ }
+
+ if ( intel->vblank_flags & VBLANK_FLAG_SECONDARY ) {
+ swap.seqtype |= DRM_VBLANK_SECONDARY;
+ }
+
+ if (!drmCommandWriteRead(intel->driFd, DRM_I915_VBLANK_SWAP, &swap,
+ sizeof(swap))) {
+ intel->swap_scheduled = 1;
+ intel->vbl_seq = swap.sequence;
+ swap.sequence -= target;
+ missed_target = swap.sequence > 0 && swap.sequence <= (1 << 23);
+ }
+ } else {
+ intel->swap_scheduled = 0;
+ }
+noschedule:
+
if (intel->last_swap_fence) {
driFenceFinish(intel->last_swap_fence, DRM_FENCE_TYPE_EXE, GL_TRUE);
driFenceUnReference(intel->last_swap_fence);
@@ -73,110 +109,112 @@ intelCopyBuffer(const __DRIdrawablePrivate * dPriv,
intel->last_swap_fence = intel->first_swap_fence;
intel->first_swap_fence = NULL;
- if (!rect) {
- driWaitForVBlank(dPriv, &intel->vbl_seq, intel->vblank_flags,
- &missed_target);
- }
-
-
- /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets
- * should work regardless.
- */
- LOCK_HARDWARE(intel);
-
- if (intel->driDrawable && intel->driDrawable->numClipRects) {
- const intelScreenPrivate *intelScreen = intel->intelScreen;
- struct gl_framebuffer *fb
- = (struct gl_framebuffer *) dPriv->driverPrivate;
- const struct intel_region *frontRegion
- = intel_get_rb_region(fb, BUFFER_FRONT_LEFT);
- const struct intel_region *backRegion
- = intel_get_rb_region(fb, BUFFER_BACK_LEFT);
- const int nbox = dPriv->numClipRects;
- const drm_clip_rect_t *pbox = dPriv->pClipRects;
- const int pitch = frontRegion->pitch;
- const int cpp = frontRegion->cpp;
- int BR13, CMD;
- int i;
-
- ASSERT(fb);
- ASSERT(fb->Name == 0); /* Not a user-created FBO */
- ASSERT(frontRegion);
- ASSERT(backRegion);
- ASSERT(frontRegion->pitch == backRegion->pitch);
- ASSERT(frontRegion->cpp == backRegion->cpp);
-
- if (cpp == 2) {
- BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24);
- CMD = XY_SRC_COPY_BLT_CMD;
+ if (!intel->swap_scheduled) {
+ if (!rect) {
+ driWaitForVBlank(dPriv, &intel->vbl_seq, intel->vblank_flags,
+ &missed_target);
}
- else {
- BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25);
- CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB);
- }
-
- for (i = 0; i < nbox; i++, pbox++) {
- drm_clip_rect_t box;
-
- if (pbox->x1 > pbox->x2 ||
- pbox->y1 > pbox->y2 ||
- pbox->x2 > intelScreen->width || pbox->y2 > intelScreen->height)
- continue;
- box = *pbox;
- if (rect) {
- if (rect->x1 > box.x1)
- box.x1 = rect->x1;
- if (rect->y1 > box.y1)
- box.y1 = rect->y1;
- if (rect->x2 < box.x2)
- box.x2 = rect->x2;
- if (rect->y2 < box.y2)
- box.y2 = rect->y2;
-
- if (box.x1 > box.x2 || box.y1 > box.y2)
- continue;
- }
-
- BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS);
- OUT_BATCH(CMD);
- OUT_BATCH(BR13);
- OUT_BATCH((pbox->y1 << 16) | pbox->x1);
- OUT_BATCH((pbox->y2 << 16) | pbox->x2);
-
- if (intel->sarea->pf_current_page == 0)
- OUT_RELOC(frontRegion->buffer,
- DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
- DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0);
- else
- OUT_RELOC(backRegion->buffer,
- DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
- DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0);
- OUT_BATCH((pbox->y1 << 16) | pbox->x1);
- OUT_BATCH(BR13 & 0xffff);
-
- if (intel->sarea->pf_current_page == 0)
- OUT_RELOC(backRegion->buffer,
- DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
- DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0);
- else
- OUT_RELOC(frontRegion->buffer,
- DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
- DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0);
-
- ADVANCE_BATCH();
+ /* The LOCK_HARDWARE is required for the cliprects. Buffer offsets
+ * should work regardless.
+ */
+ LOCK_HARDWARE(intel);
+
+ if (intel->driDrawable && intel->driDrawable->numClipRects) {
+ const intelScreenPrivate *intelScreen = intel->intelScreen;
+ struct gl_framebuffer *fb
+ = (struct gl_framebuffer *) dPriv->driverPrivate;
+ const struct intel_region *frontRegion
+ = intel_get_rb_region(fb, BUFFER_FRONT_LEFT);
+ const struct intel_region *backRegion
+ = intel_get_rb_region(fb, BUFFER_BACK_LEFT);
+ const int nbox = dPriv->numClipRects;
+ const drm_clip_rect_t *pbox = dPriv->pClipRects;
+ const int pitch = frontRegion->pitch;
+ const int cpp = frontRegion->cpp;
+ int BR13, CMD;
+ int i;
+
+ ASSERT(fb);
+ ASSERT(fb->Name == 0); /* Not a user-created FBO */
+ ASSERT(frontRegion);
+ ASSERT(backRegion);
+ ASSERT(frontRegion->pitch == backRegion->pitch);
+ ASSERT(frontRegion->cpp == backRegion->cpp);
+
+ if (cpp == 2) {
+ BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24);
+ CMD = XY_SRC_COPY_BLT_CMD;
+ }
+ else {
+ BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25);
+ CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
+ XY_SRC_COPY_BLT_WRITE_RGB);
+ }
+
+ for (i = 0; i < nbox; i++, pbox++) {
+ drm_clip_rect_t box;
+
+ if (pbox->x1 > pbox->x2 ||
+ pbox->y1 > pbox->y2 ||
+ pbox->x2 > intelScreen->width || pbox->y2 > intelScreen->height)
+ continue;
+
+ box = *pbox;
+
+ if (rect) {
+ if (rect->x1 > box.x1)
+ box.x1 = rect->x1;
+ if (rect->y1 > box.y1)
+ box.y1 = rect->y1;
+ if (rect->x2 < box.x2)
+ box.x2 = rect->x2;
+ if (rect->y2 < box.y2)
+ box.y2 = rect->y2;
+
+ if (box.x1 > box.x2 || box.y1 > box.y2)
+ continue;
+ }
+
+ BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS);
+ OUT_BATCH(CMD);
+ OUT_BATCH(BR13);
+ OUT_BATCH((pbox->y1 << 16) | pbox->x1);
+ OUT_BATCH((pbox->y2 << 16) | pbox->x2);
+
+ if (intel->sarea->pf_current_page == 0)
+ OUT_RELOC(frontRegion->buffer,
+ DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
+ DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0);
+ else
+ OUT_RELOC(backRegion->buffer,
+ DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
+ DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0);
+ OUT_BATCH((pbox->y1 << 16) | pbox->x1);
+ OUT_BATCH(BR13 & 0xffff);
+
+ if (intel->sarea->pf_current_page == 0)
+ OUT_RELOC(backRegion->buffer,
+ DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
+ DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0);
+ else
+ OUT_RELOC(frontRegion->buffer,
+ DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
+ DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0);
+
+ ADVANCE_BATCH();
+ }
+
+ if (intel->first_swap_fence)
+ driFenceUnReference(intel->first_swap_fence);
+ intel->first_swap_fence = intel_batchbuffer_flush(intel->batch);
+ driFenceReference(intel->first_swap_fence);
}
- if (intel->first_swap_fence)
- driFenceUnReference(intel->first_swap_fence);
- intel->first_swap_fence = intel_batchbuffer_flush(intel->batch);
- driFenceReference(intel->first_swap_fence);
+ UNLOCK_HARDWARE(intel);
}
- UNLOCK_HARDWARE(intel);
-
if (!rect) {
intel->swap_count++;
(*dri_interface->getUST) (&ust);
diff --git a/src/mesa/drivers/dri/i915/intel_buffers.c b/src/mesa/drivers/dri/i915/intel_buffers.c
index 34eedc31e65..3c9be8448ea 100644
--- a/src/mesa/drivers/dri/i915/intel_buffers.c
+++ b/src/mesa/drivers/dri/i915/intel_buffers.c
@@ -35,8 +35,10 @@
#include "intel_regions.h"
#include "intel_batchbuffer.h"
#include "context.h"
+#include "utils.h"
#include "framebuffer.h"
#include "swrast/swrast.h"
+#include "vblank.h"
/**
@@ -270,6 +272,35 @@ intelWindowMoved(struct intel_context *intel)
intel->driDrawable->w, intel->driDrawable->h);
}
+ if (intel->intelScreen->driScrnPriv->ddxMinor >= 7 && intel->driDrawable) {
+ __DRIdrawablePrivate *dPriv = intel->driDrawable;
+ drmI830Sarea *sarea = intel->sarea;
+ drm_clip_rect_t drw_rect = { .x1 = dPriv->x, .x2 = dPriv->x + dPriv->w,
+ .y1 = dPriv->y, .y2 = dPriv->y + dPriv->h };
+ drm_clip_rect_t pipeA_rect = { .x1 = sarea->pipeA_x, .y1 = sarea->pipeA_y,
+ .x2 = sarea->pipeA_x + sarea->pipeA_w,
+ .y2 = sarea->pipeA_y + sarea->pipeA_h };
+ drm_clip_rect_t pipeB_rect = { .x1 = sarea->pipeB_x, .y1 = sarea->pipeB_y,
+ .x2 = sarea->pipeB_x + sarea->pipeB_w,
+ .y2 = sarea->pipeB_y + sarea->pipeB_h };
+ GLint areaA = driIntersectArea( drw_rect, pipeA_rect );
+ GLint areaB = driIntersectArea( drw_rect, pipeB_rect );
+ GLuint flags = intel->vblank_flags;
+
+ if (areaB > areaA || (areaA == areaB && areaB > 0)) {
+ flags = intel->vblank_flags | VBLANK_FLAG_SECONDARY;
+ } else {
+ flags = intel->vblank_flags & ~VBLANK_FLAG_SECONDARY;
+ }
+
+ if (flags != intel->vblank_flags) {
+ intel->vblank_flags = flags;
+ driGetCurrentVBlank(dPriv, intel->vblank_flags, &intel->vbl_seq);
+ }
+ } else {
+ intel->vblank_flags &= ~VBLANK_FLAG_SECONDARY;
+ }
+
/* Update hardware scissor */
ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
ctx->Scissor.Width, ctx->Scissor.Height);
diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c
index d956a20396c..7a23450841c 100644
--- a/src/mesa/drivers/dri/i915/intel_context.c
+++ b/src/mesa/drivers/dri/i915/intel_context.c
@@ -440,8 +440,7 @@ intelInitContext(struct intel_context *intel,
intel->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
intel->vblank_flags = (intel->intelScreen->irq_active != 0)
- ? driGetDefaultVBlankFlags(&intelScreen->
- optionCache) : VBLANK_FLAG_NO_IRQ;
+ ? driGetDefaultVBlankFlags(&intel->optionCache) : VBLANK_FLAG_NO_IRQ;
(*dri_interface->getUST) (&intel->swap_ust);
_math_matrix_ctr(&intel->ViewportMatrix);
@@ -465,7 +464,7 @@ intelInitContext(struct intel_context *intel,
_mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc");
_mesa_enable_extension(ctx, "GL_S3_s3tc");
}
- else if (driQueryOptionb(&intelScreen->optionCache, "force_s3tc_enable")) {
+ else if (driQueryOptionb(&intel->optionCache, "force_s3tc_enable")) {
_mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc");
}
@@ -553,7 +552,7 @@ intelMakeCurrent(__DRIcontextPrivate * driContextPriv,
if (intel->driDrawable != driDrawPriv) {
/* Shouldn't the readbuffer be stored also? */
- driDrawableInitVBlank(driDrawPriv, intel->vblank_flags);
+ driDrawableInitVBlank(driDrawPriv, intel->vblank_flags, &intel->vbl_seq);
intel->driDrawable = driDrawPriv;
intelWindowMoved(intel);
@@ -664,6 +663,17 @@ void LOCK_HARDWARE( struct intel_context *intel )
_glthread_LOCK_MUTEX(lockMutex);
assert(!intel->locked);
+ if (intel->swap_scheduled) {
+ drmVBlank vbl;
+ vbl.request.type = DRM_VBLANK_ABSOLUTE;
+ if ( intel->vblank_flags & VBLANK_FLAG_SECONDARY ) {
+ vbl.request.type |= DRM_VBLANK_SECONDARY;
+ }
+ vbl.request.sequence = intel->vbl_seq;
+ drmWaitVBlank(intel->driFd, &vbl);
+ intel->swap_scheduled = 0;
+ }
+
DRM_CAS(intel->driHwLock, intel->hHWContext,
(DRM_LOCK_HELD|intel->hHWContext), __ret);
diff --git a/src/mesa/drivers/dri/i915/intel_context.h b/src/mesa/drivers/dri/i915/intel_context.h
index ef8993c69b5..fa3cf585718 100644
--- a/src/mesa/drivers/dri/i915/intel_context.h
+++ b/src/mesa/drivers/dri/i915/intel_context.h
@@ -285,6 +285,7 @@ struct intel_context
GLuint swap_count;
GLuint swap_missed_count;
+ GLuint swap_scheduled;
};
/* These are functions now:
diff --git a/src/mesa/drivers/dri/i915/intel_screen.c b/src/mesa/drivers/dri/i915/intel_screen.c
index 288fa237289..4f563a1c013 100644
--- a/src/mesa/drivers/dri/i915/intel_screen.c
+++ b/src/mesa/drivers/dri/i915/intel_screen.c
@@ -801,7 +801,7 @@ __driCreateNewScreen_20050727(__DRInativeDisplay * dpy, int scrn,
__DRIscreenPrivate *psp;
static const __DRIversion ddx_expected = { 1, 5, 0 };
static const __DRIversion dri_expected = { 4, 0, 0 };
- static const __DRIversion drm_expected = { 1, 6, 0 };
+ static const __DRIversion drm_expected = { 1, 7, 0 };
dri_interface = interface;
diff --git a/src/mesa/drivers/dri/i915/server/i830_common.h b/src/mesa/drivers/dri/i915/server/i830_common.h
index 41b5cc3c01b..fb6ceaa52d4 100644
--- a/src/mesa/drivers/dri/i915/server/i830_common.h
+++ b/src/mesa/drivers/dri/i915/server/i830_common.h
@@ -112,6 +112,21 @@ typedef struct {
int rotated_size;
int rotated_pitch;
int virtualX, virtualY;
+
+ unsigned int front_tiled;
+ unsigned int back_tiled;
+ unsigned int depth_tiled;
+ unsigned int rotated_tiled;
+ unsigned int rotated2_tiled;
+
+ int pipeA_x;
+ int pipeA_y;
+ int pipeA_w;
+ int pipeA_h;
+ int pipeB_x;
+ int pipeB_y;
+ int pipeB_w;
+ int pipeB_h;
} drmI830Sarea;
/* Flags for perf_boxes
diff --git a/src/mesa/drivers/dri/mach64/mach64_context.c b/src/mesa/drivers/dri/mach64/mach64_context.c
index 717b9b9e8d8..03ec96a222e 100644
--- a/src/mesa/drivers/dri/mach64/mach64_context.c
+++ b/src/mesa/drivers/dri/mach64/mach64_context.c
@@ -308,7 +308,8 @@ mach64MakeCurrent( __DRIcontextPrivate *driContextPriv,
}
- driDrawableInitVBlank( driDrawPriv, newMach64Ctx->vblank_flags );
+ driDrawableInitVBlank( driDrawPriv, newMach64Ctx->vblank_flags,
+ &newMach64Ctx->vbl_seq );
if ( newMach64Ctx->driDrawable != driDrawPriv ) {
newMach64Ctx->driDrawable = driDrawPriv;
diff --git a/src/mesa/drivers/dri/mga/mga_xmesa.c b/src/mesa/drivers/dri/mga/mga_xmesa.c
index 6450340a48c..73bcfcce738 100644
--- a/src/mesa/drivers/dri/mga/mga_xmesa.c
+++ b/src/mesa/drivers/dri/mga/mga_xmesa.c
@@ -878,7 +878,8 @@ mgaMakeCurrent(__DRIcontextPrivate *driContextPriv,
mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate;
if (mmesa->driDrawable != driDrawPriv) {
- driDrawableInitVBlank( driDrawPriv, mmesa->vblank_flags );
+ driDrawableInitVBlank( driDrawPriv, mmesa->vblank_flags,
+ &mmesa->vbl_seq );
mmesa->driDrawable = driDrawPriv;
mmesa->dirty = ~0;
mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK);
diff --git a/src/mesa/drivers/dri/r128/r128_context.c b/src/mesa/drivers/dri/r128/r128_context.c
index 2f30bd253bf..8ec027542ad 100644
--- a/src/mesa/drivers/dri/r128/r128_context.c
+++ b/src/mesa/drivers/dri/r128/r128_context.c
@@ -345,7 +345,8 @@ r128MakeCurrent( __DRIcontextPrivate *driContextPriv,
newR128Ctx->dirty = R128_UPLOAD_ALL;
}
- driDrawableInitVBlank( driDrawPriv, newR128Ctx->vblank_flags );
+ driDrawableInitVBlank( driDrawPriv, newR128Ctx->vblank_flags,
+ &newR128Ctx->vbl_seq );
newR128Ctx->driDrawable = driDrawPriv;
_mesa_make_current( newR128Ctx->glCtx,
diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c
index 0e85b9680ce..1ef7e749833 100644
--- a/src/mesa/drivers/dri/r200/r200_context.c
+++ b/src/mesa/drivers/dri/r200/r200_context.c
@@ -695,7 +695,8 @@ r200MakeCurrent( __DRIcontextPrivate *driContextPriv,
fprintf(stderr, "%s ctx %p\n", __FUNCTION__, (void *)newCtx->glCtx);
if ( newCtx->dri.drawable != driDrawPriv ) {
- driDrawableInitVBlank( driDrawPriv, newCtx->vblank_flags );
+ driDrawableInitVBlank( driDrawPriv, newCtx->vblank_flags,
+ &newCtx->vbl_seq );
newCtx->dri.drawable = driDrawPriv;
r200UpdateWindow( newCtx->glCtx );
r200UpdateViewportOffset( newCtx->glCtx );
diff --git a/src/mesa/drivers/dri/r300/radeon_context.c b/src/mesa/drivers/dri/r300/radeon_context.c
index d886788b341..bea219742d6 100644
--- a/src/mesa/drivers/dri/r300/radeon_context.c
+++ b/src/mesa/drivers/dri/r300/radeon_context.c
@@ -287,7 +287,8 @@ GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv,
if (radeon->dri.drawable != driDrawPriv) {
driDrawableInitVBlank(driDrawPriv,
- radeon->vblank_flags);
+ radeon->vblank_flags,
+ &radeon->vbl_seq);
radeon->dri.drawable = driDrawPriv;
r300UpdateWindow(radeon->glCtx);
diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c
index 21161d2f69d..7772715b91b 100644
--- a/src/mesa/drivers/dri/radeon/radeon_context.c
+++ b/src/mesa/drivers/dri/radeon/radeon_context.c
@@ -625,7 +625,8 @@ radeonMakeCurrent( __DRIcontextPrivate *driContextPriv,
if ( newCtx->dri.drawable != driDrawPriv ) {
/* XXX we may need to validate the drawable here!!! */
- driDrawableInitVBlank( driDrawPriv, newCtx->vblank_flags );
+ driDrawableInitVBlank( driDrawPriv, newCtx->vblank_flags,
+ &newCtx->vbl_seq );
newCtx->dri.drawable = driDrawPriv;
radeonUpdateWindow( newCtx->glCtx );
radeonUpdateViewportOffset( newCtx->glCtx );
diff --git a/src/mesa/drivers/dri/unichrome/via_context.c b/src/mesa/drivers/dri/unichrome/via_context.c
index ffde1b66b76..2459336bd66 100644
--- a/src/mesa/drivers/dri/unichrome/via_context.c
+++ b/src/mesa/drivers/dri/unichrome/via_context.c
@@ -815,7 +815,8 @@ viaMakeCurrent(__DRIcontextPrivate *driContextPriv,
readBuffer = (GLframebuffer *)driReadPriv->driverPrivate;
if ( vmesa->driDrawable != driDrawPriv ) {
- driDrawableInitVBlank( driDrawPriv, vmesa->vblank_flags );
+ driDrawableInitVBlank( driDrawPriv, vmesa->vblank_flags,
+ &vmesa->vbl_seq );
vmesa->driDrawable = driDrawPriv;
if ( ! calculate_buffer_parameters( vmesa, drawBuffer ) ) {
return GL_FALSE;