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 */
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);
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);
_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);
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 */
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;
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;
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__);
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
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 {
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 {
*/
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);
#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 */
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);
}
int height;
int current_rotation;
+ /* Page flipping
+ */
+ GLboolean doPageFlip;
+ GLboolean flip_pending;
};
/* These are functions now:
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
#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
/* _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.
*/