summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichel Dänzer <michel@tungstengraphics.com>2007-02-02 17:10:25 +0100
committerMichel Dänzer <michel@tungstengraphics.com>2007-02-20 19:15:44 +0100
commitaf64dd2ae0aa31261002335f10d46492000f552b (patch)
treea8d382985dfb3e1f2529697e948dbd3b39b9fa29 /src
parentd2b06403c6f06ee37f46c2a504983884382c8abc (diff)
i915tex: Make page flipping work again.
Diffstat (limited to 'src')
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_blit.c40
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_buffers.c50
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_context.c14
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_context.h4
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_fbo.c19
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_reg.h3
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_tris.c10
7 files changed, 94 insertions, 46 deletions
diff --git a/src/mesa/drivers/dri/i915tex/intel_blit.c b/src/mesa/drivers/dri/i915tex/intel_blit.c
index 550669ab0c..c08c45a936 100644
--- a/src/mesa/drivers/dri/i915tex/intel_blit.c
+++ b/src/mesa/drivers/dri/i915tex/intel_blit.c
@@ -453,16 +453,6 @@ intelClearWithBlit(GLcontext * ctx, GLbitfield mask)
clear.y1 = intel->driDrawable->y + intel->driDrawable->h - cy - ch;
clear.x2 = clear.x1 + cw;
clear.y2 = clear.y1 + ch;
-
- /* adjust for page flipping */
- if (intel->sarea->pf_current_page == 1) {
- const GLuint tmp = mask;
- mask &= ~(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT);
- if (tmp & BUFFER_BIT_FRONT_LEFT)
- mask |= BUFFER_BIT_BACK_LEFT;
- if (tmp & BUFFER_BIT_BACK_LEFT)
- mask |= BUFFER_BIT_FRONT_LEFT;
- }
}
else {
/* clearing FBO */
@@ -499,11 +489,10 @@ intelClearWithBlit(GLcontext * ctx, GLbitfield mask)
const GLbitfield bufBit = 1 << buf;
if ((clearMask & bufBit) && !(bufBit & skipBuffers)) {
/* OK, clear this renderbuffer */
- const struct intel_renderbuffer *irb
- = intel_renderbuffer(ctx->DrawBuffer->
- Attachment[buf].Renderbuffer);
+ struct intel_region *irb_region =
+ intel_get_rb_region(ctx->DrawBuffer, buf);
struct _DriBufferObject *write_buffer =
- intel_region_buffer(intel->intelScreen, irb->region,
+ intel_region_buffer(intel->intelScreen, irb_region,
all ? INTEL_WRITE_FULL :
INTEL_WRITE_PART);
@@ -511,16 +500,15 @@ intelClearWithBlit(GLcontext * ctx, GLbitfield mask)
GLint pitch, cpp;
GLuint BR13, CMD;
- ASSERT(irb);
- ASSERT(irb->region);
+ ASSERT(irb_region);
- pitch = irb->region->pitch;
- cpp = irb->region->cpp;
+ pitch = irb_region->pitch;
+ cpp = irb_region->cpp;
DBG("%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",
__FUNCTION__,
- irb->region->buffer, (pitch * cpp),
- irb->region->draw_offset,
+ irb_region->buffer, (pitch * cpp),
+ irb_region->draw_offset,
b.x1, b.y1, b.x2 - b.x1, b.y2 - b.y1);
@@ -558,6 +546,16 @@ intelClearWithBlit(GLcontext * ctx, GLbitfield mask)
_mesa_debug(ctx, "hardware blit clear buf %d rb id %d\n",
buf, irb->Base.Name);
*/
+ if (intel->flip_pending) {
+ /* Wait for a pending flip to take effect */
+ BEGIN_BATCH(2, INTEL_BATCH_NO_CLIPRECTS);
+ OUT_BATCH(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP);
+ OUT_BATCH(0);
+ ADVANCE_BATCH();
+
+ intel->flip_pending = GL_FALSE;
+ }
+
BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS);
OUT_BATCH(CMD);
OUT_BATCH(BR13);
@@ -565,7 +563,7 @@ intelClearWithBlit(GLcontext * ctx, GLbitfield mask)
OUT_BATCH((b.y2 << 16) | b.x2);
OUT_RELOC(write_buffer, DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE,
- irb->region->draw_offset);
+ irb_region->draw_offset);
OUT_BATCH(clearVal);
ADVANCE_BATCH();
clearMask &= ~bufBit; /* turn off bit, for faster loop exit */
diff --git a/src/mesa/drivers/dri/i915tex/intel_buffers.c b/src/mesa/drivers/dri/i915tex/intel_buffers.c
index 1ded0b5417..a8fb0b14a1 100644
--- a/src/mesa/drivers/dri/i915tex/intel_buffers.c
+++ b/src/mesa/drivers/dri/i915tex/intel_buffers.c
@@ -159,7 +159,7 @@ intelSetBackClipRects(struct intel_context *intel)
if (!dPriv)
return;
- if (intel->sarea->pf_enabled == 0 && dPriv->numBackClipRects == 0) {
+ if (intel->sarea->pf_active || dPriv->numBackClipRects == 0) {
/* use the front clip rects */
intel->numClipRects = dPriv->numClipRects;
intel->pClipRects = dPriv->pClipRects;
@@ -421,7 +421,8 @@ intelRotateWindow(struct intel_context *intel,
intel->vtbl.meta_draw_region(intel, screen->rotated_region, NULL); /* ? */
- if (srcBuf == BUFFER_BIT_FRONT_LEFT) {
+ if ((srcBuf == BUFFER_BIT_BACK_LEFT && intel->sarea->pf_current_page) ||
+ (srcBuf == BUFFER_BIT_FRONT_LEFT && !intel->sarea->pf_current_page)) {
src = intel->intelScreen->front_region;
clipRects = dPriv->pClipRects;
numClipRects = dPriv->numClipRects;
@@ -592,9 +593,9 @@ intelClear(GLcontext *ctx, GLbitfield mask)
static void
intelPageFlip(const __DRIdrawablePrivate * dPriv)
{
-#if 0
struct intel_context *intel;
- int tmp, ret;
+ GLboolean missed_target;
+ int ret;
if (INTEL_DEBUG & DEBUG_IOCTL)
fprintf(stderr, "%s\n", __FUNCTION__);
@@ -606,27 +607,36 @@ intelPageFlip(const __DRIdrawablePrivate * dPriv)
intel = (struct intel_context *) dPriv->driContextPriv->driverPrivate;
intelFlush(&intel->ctx);
- LOCK_HARDWARE(intel);
- if (dPriv->pClipRects) {
- *(drm_clip_rect_t *) intel->sarea->boxes = dPriv->pClipRects[0];
- intel->sarea->nbox = 1;
+ driWaitForVBlank(dPriv, &intel->vbl_seq, intel->vblank_flags, &missed_target);
+
+ if (missed_target) {
+ intel->swap_missed_count++;
+ (void)(*dri_interface->getUST) (&intel->swap_missed_ust);
}
- ret = drmCommandNone(intel->driFd, DRM_I830_FLIP);
- if (ret) {
- fprintf(stderr, "%s: %d\n", __FUNCTION__, ret);
+ LOCK_HARDWARE(intel);
+
+ if (!dPriv->numClipRects) {
UNLOCK_HARDWARE(intel);
- exit(1);
+ usleep(10000); /* throttle invisible client 10ms */
+ return;
}
- tmp = intel->sarea->last_enqueue;
- intelRefillBatchLocked(intel);
+ ret = drmCommandNone(intel->driFd, DRM_I830_FLIP);
UNLOCK_HARDWARE(intel);
+ if (ret) {
+ _mesa_error(&intel->ctx, GL_INVALID_OPERATION, "DRM_I830_FLIP: %d\n",
+ ret);
+ return;
+ }
- intelSetDrawBuffer(&intel->ctx, intel->ctx.Color.DriverDrawBuffer);
-#endif
+ driFlipRenderbuffers(intel->ctx.WinSysDrawBuffer,
+ intel->sarea->pf_current_page);
+ intel_draw_buffer(&intel->ctx, intel->ctx.DrawBuffer);
+
+ intel->flip_pending = GL_TRUE;
}
#if 0
@@ -641,7 +651,7 @@ intelSwapBuffers(__DRIdrawablePrivate * dPriv)
if (ctx && ctx->DrawBuffer == fb) {
_mesa_notifySwapBuffers(ctx); /* flush pending rendering */
}
- if (0 /*intel->doPageFlip */ ) { /* doPageFlip is never set !!! */
+ if (intel->doPageFlip) {
intelPageFlip(dPriv);
}
else {
@@ -672,7 +682,7 @@ intelSwapBuffers(__DRIdrawablePrivate * dPriv)
if (ctx->Visual.doubleBufferMode) {
intelScreenPrivate *screen = intel->intelScreen;
_mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */
- if (0 /*intel->doPageFlip */ ) { /* doPageFlip is never set !!! */
+ if (screen->current_rotation == 0 && intel->doPageFlip) {
intelPageFlip(dPriv);
}
else {
@@ -788,10 +798,6 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb)
*/
if (fb->Name == 0) {
/* drawing to window system buffer */
- if (intel->sarea->pf_current_page == 1) {
- /* page flipped back/front */
- front ^= 1;
- }
if (front) {
intelSetFrontClipRects(intel);
colorRegion = intel_get_rb_region(fb, BUFFER_FRONT_LEFT);
diff --git a/src/mesa/drivers/dri/i915tex/intel_context.c b/src/mesa/drivers/dri/i915tex/intel_context.c
index a5ce08b170..7eb209cf5f 100644
--- a/src/mesa/drivers/dri/i915tex/intel_context.c
+++ b/src/mesa/drivers/dri/i915tex/intel_context.c
@@ -59,6 +59,7 @@
#include "intel_buffer_objects.h"
#include "intel_fbo.h"
+#include "drirenderbuffer.h"
#include "vblank.h"
#include "utils.h"
#include "xmlpool.h" /* for symbolic values of enum-type options */
@@ -683,13 +684,24 @@ intelContendedLock(struct intel_context *intel, GLuint flags)
intel->current_rotation = sarea->rotation;
}
-
/* Drawable changed?
*/
if (dPriv && intel->lastStamp != dPriv->lastStamp) {
intelWindowMoved(intel);
intel->lastStamp = dPriv->lastStamp;
}
+
+ /* Update page flipping info
+ */
+ if (INTEL_DEBUG & DEBUG_LOCK)
+ if (intel->doPageFlip != intel->sarea->pf_active)
+ _mesa_printf("%s - age flipping %sactive\n", __progname,
+ intel->sarea->pf_active ? "" : "in");
+
+ intel->doPageFlip = intel->sarea->pf_active;
+ driFlipRenderbuffers(intel->ctx.WinSysDrawBuffer,
+ intel->sarea->pf_current_page);
+ intel_draw_buffer(&intel->ctx, intel->ctx.DrawBuffer);
}
diff --git a/src/mesa/drivers/dri/i915tex/intel_context.h b/src/mesa/drivers/dri/i915tex/intel_context.h
index 96b911501f..321a945c05 100644
--- a/src/mesa/drivers/dri/i915tex/intel_context.h
+++ b/src/mesa/drivers/dri/i915tex/intel_context.h
@@ -295,6 +295,10 @@ struct intel_context
int height;
int current_rotation;
+ /* Page flipping
+ */
+ GLboolean doPageFlip;
+ GLboolean flip_pending;
};
/* These are functions now:
diff --git a/src/mesa/drivers/dri/i915tex/intel_fbo.c b/src/mesa/drivers/dri/i915tex/intel_fbo.c
index ab0e569bd9..b739e22cca 100644
--- a/src/mesa/drivers/dri/i915tex/intel_fbo.c
+++ b/src/mesa/drivers/dri/i915tex/intel_fbo.c
@@ -78,8 +78,23 @@ intel_get_renderbuffer(struct gl_framebuffer *fb, GLuint attIndex)
struct intel_region *
intel_get_rb_region(struct gl_framebuffer *fb, GLuint attIndex)
{
- struct intel_renderbuffer *irb
- = intel_renderbuffer(fb->Attachment[attIndex].Renderbuffer);
+ GET_CURRENT_CONTEXT(ctx);
+ struct intel_context *intel = intel_context(ctx);
+ struct intel_renderbuffer *irb;
+
+ if (intel->sarea->pf_current_page) {
+ switch (attIndex) {
+ case BUFFER_BACK_LEFT:
+ attIndex = BUFFER_FRONT_LEFT;
+ break;
+ case BUFFER_FRONT_LEFT:
+ attIndex = BUFFER_BACK_LEFT;
+ break;
+ }
+ }
+
+ irb = intel_renderbuffer(fb->Attachment[attIndex].Renderbuffer);
+
if (irb)
return irb->region;
else
diff --git a/src/mesa/drivers/dri/i915tex/intel_reg.h b/src/mesa/drivers/dri/i915tex/intel_reg.h
index 1ec153266c..126d2ea7ff 100644
--- a/src/mesa/drivers/dri/i915tex/intel_reg.h
+++ b/src/mesa/drivers/dri/i915tex/intel_reg.h
@@ -81,4 +81,7 @@
#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21)
#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20)
+#define MI_WAIT_FOR_EVENT ((0x3<<23))
+#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
+
#endif
diff --git a/src/mesa/drivers/dri/i915tex/intel_tris.c b/src/mesa/drivers/dri/i915tex/intel_tris.c
index 1ba49d8f6e..4e0ca70c1e 100644
--- a/src/mesa/drivers/dri/i915tex/intel_tris.c
+++ b/src/mesa/drivers/dri/i915tex/intel_tris.c
@@ -102,6 +102,16 @@ intelStartInlinePrimitive(struct intel_context *intel,
/* _mesa_printf("%s *", __progname); */
+ if (intel->flip_pending) {
+ /* Wait for a pending flip to take effect */
+ BEGIN_BATCH(2, batch_flags);
+ OUT_BATCH(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP);
+ OUT_BATCH(0);
+ ADVANCE_BATCH();
+
+ intel->flip_pending = GL_FALSE;
+ }
+
/* Emit a slot which will be filled with the inline primitive
* command later.
*/