}
}
- /* Update Mesa's notion of window size */
- driUpdateFramebufferSize(ctx, dPriv);
- intel_fb->Base.Initialized = GL_TRUE; /* XXX remove someday */
-
if (intel->intelScreen->driScrnPriv->ddxMinor >= 7) {
drmI830Sarea *sarea = intel->sarea;
drm_clip_rect_t drw_rect = { .x1 = dPriv->x, .x2 = dPriv->x + dPriv->w,
intel_fb->pf_current_page = (intel->sarea->pf_current_page >>
(intel_fb->pf_pipes & 0x2)) & 0x3;
- pf_active = (pf_pipes & intel->sarea->pf_active) == pf_pipes;
+ intel_fb->pf_num_pages = intel->intelScreen->third.handle ? 3 : 2;
+
+ pf_active = pf_pipes && (pf_pipes & intel->sarea->pf_active) == pf_pipes;
if (INTEL_DEBUG & DEBUG_LOCK)
if (pf_active != intel_fb->pf_active)
pf_active ? "" : "in");
if (pf_active) {
- if (pf_pipes != intel_fb->pf_pipes && intel_fb->pf_pipes == 0x3 &&
- (intel->sarea->pf_current_page & 0x3) !=
- ((intel->sarea->pf_current_page) >> 2 & 0x3)) {
+ int i;
+
+ /* Sync pages between pipes if we're flipping on both at the same time */
+ for (i = 0; i < 2 && pf_pipes != intel_fb->pf_pipes &&
+ intel_fb->pf_pipes == 0x3 &&
+ (intel->sarea->pf_current_page & 0x3) !=
+ ((intel->sarea->pf_current_page) >> 2 & 0x3); i++) {
drm_i915_flip_t flip;
flip.pipes = (intel_fb->pf_current_page ==
}
intel_fb->pf_active = pf_active;
- driFlipRenderbuffers(intel->ctx.WinSysDrawBuffer, intel_fb->pf_current_page);
+ intel_flip_renderbuffers(intel_fb);
intel_draw_buffer(&intel->ctx, intel->ctx.DrawBuffer);
/* Update vblank info
intel->vblank_flags &= ~VBLANK_FLAG_SECONDARY;
}
+ /* Update Mesa's notion of window size */
+ driUpdateFramebufferSize(ctx, dPriv);
+ intel_fb->Base.Initialized = GL_TRUE; /* XXX remove someday */
+
/* Update hardware scissor */
ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
ctx->Scissor.Width, ctx->Scissor.Height);
intel_fb = dPriv->driverPrivate;
if ((srcBuf == BUFFER_BIT_BACK_LEFT && !intel_fb->pf_active)) {
- src = intel->intelScreen->back_region;
+ src = intel_get_rb_region(&intel_fb->Base, BUFFER_BACK_LEFT);
clipRects = dPriv->pBackClipRects;
numClipRects = dPriv->numBackClipRects;
}
else {
- src = intel->intelScreen->front_region;
+ src = intel_get_rb_region(&intel_fb->Base, BUFFER_FRONT_LEFT);
clipRects = dPriv->pClipRects;
numClipRects = dPriv->numClipRects;
}
{
struct intel_framebuffer *intel_fb =
(struct intel_framebuffer *) intel->ctx.DrawBuffer;
+ struct intel_renderbuffer *intel_rb =
+ intel_get_renderbuffer(&intel_fb->Base,
+ intel_fb->Base._ColorDrawBufferMask[0] ==
+ BUFFER_BIT_FRONT_LEFT ? BUFFER_FRONT_LEFT :
+ BUFFER_BACK_LEFT);
- if (intel_fb->Base.Name == 0 && intel_fb->flip_pending) {
+ if (intel_fb->Base.Name == 0 && intel_rb->pf_pending == intel_fb->pf_seq) {
GLuint mi_wait = MI_WAIT_FOR_EVENT;
GLint pf_pipes = intel_fb->pf_pipes;
BATCH_LOCALS;
OUT_BATCH(0);
ADVANCE_BATCH();
- intel_fb->flip_pending = GL_FALSE;
+ intel_rb->pf_pending--;
}
}
intel_fb->pf_current_page = (intel->sarea->pf_current_page >>
(intel_fb->pf_pipes & 0x2)) & 0x3;
- driFlipRenderbuffers(intel->ctx.WinSysDrawBuffer, intel_fb->pf_current_page);
- intel_draw_buffer(&intel->ctx, &intel_fb->Base);
+ if (dPriv->numClipRects != 0) {
+ intel_get_renderbuffer(&intel_fb->Base, BUFFER_FRONT_LEFT)->pf_pending =
+ intel_get_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT)->pf_pending =
+ ++intel_fb->pf_seq;
+ }
- intel_fb->flip_pending = dPriv->numClipRects != 0;
+ intel_flip_renderbuffers(intel_fb);
+ intel_draw_buffer(&intel->ctx, &intel_fb->Base);
return GL_TRUE;
}
if (driContextPriv) {
struct intel_context *intel =
(struct intel_context *) driContextPriv->driverPrivate;
- GLframebuffer *drawFb = (GLframebuffer *) driDrawPriv->driverPrivate;
+ struct intel_framebuffer *intel_fb =
+ (struct intel_framebuffer *) driDrawPriv->driverPrivate;
GLframebuffer *readFb = (GLframebuffer *) driReadPriv->driverPrivate;
/* XXX FBO temporary fix-ups! */
/* if the renderbuffers don't have regions, init them from the context */
{
- struct intel_renderbuffer *irbFront
- = intel_get_renderbuffer(drawFb, BUFFER_FRONT_LEFT);
- struct intel_renderbuffer *irbBack
- = intel_get_renderbuffer(drawFb, BUFFER_BACK_LEFT);
struct intel_renderbuffer *irbDepth
- = intel_get_renderbuffer(drawFb, BUFFER_DEPTH);
+ = intel_get_renderbuffer(&intel_fb->Base, BUFFER_DEPTH);
struct intel_renderbuffer *irbStencil
- = intel_get_renderbuffer(drawFb, BUFFER_STENCIL);
+ = intel_get_renderbuffer(&intel_fb->Base, BUFFER_STENCIL);
- if (irbFront && !irbFront->region) {
- intel_region_reference(&irbFront->region, intel->intelScreen->front_region);
+ if (intel_fb->color_rb[0] && !intel_fb->color_rb[0]->region) {
+ intel_region_reference(&intel_fb->color_rb[0]->region,
+ intel->intelScreen->front_region);
}
- if (irbBack && !irbBack->region) {
- intel_region_reference(&irbBack->region, intel->intelScreen->back_region);
+ if (intel_fb->color_rb[1] && !intel_fb->color_rb[1]->region) {
+ intel_region_reference(&intel_fb->color_rb[1]->region,
+ intel->intelScreen->back_region);
+ }
+ if (intel_fb->color_rb[2] && !intel_fb->color_rb[2]->region) {
+ intel_region_reference(&intel_fb->color_rb[2]->region,
+ intel->intelScreen->third_region);
}
if (irbDepth && !irbDepth->region) {
intel_region_reference(&irbDepth->region, intel->intelScreen->depth_region);
}
}
- /* set initial GLframebuffer size to match window, if needed */
- if (drawFb->Width == 0 && driDrawPriv->w) {
- _mesa_resize_framebuffer(&intel->ctx, drawFb,
- driDrawPriv->w, driDrawPriv->h);
- }
- if (readFb->Width == 0 && driReadPriv->w) {
- _mesa_resize_framebuffer(&intel->ctx, readFb,
- driReadPriv->w, driReadPriv->h);
- }
-
- _mesa_make_current(&intel->ctx, drawFb, readFb);
+ _mesa_make_current(&intel->ctx, &intel_fb->Base, readFb);
/* The drawbuffer won't always be updated by _mesa_make_current:
*/
- if (intel->ctx.DrawBuffer == drawFb) {
+ if (intel->ctx.DrawBuffer == &intel_fb->Base) {
if (intel->driDrawable != driDrawPriv) {
driDrawableInitVBlank(driDrawPriv, intel->vblank_flags, &intel->vbl_seq);
intelWindowMoved(intel);
}
- intel_draw_buffer(&intel->ctx, drawFb);
+ intel_draw_buffer(&intel->ctx, &intel_fb->Base);
}
+
+ /* set initial GLframebuffer size to match window, if needed */
+ if (&intel_fb->Base.Width == 0 && driDrawPriv->w) {
+ _mesa_resize_framebuffer(&intel->ctx, &intel_fb->Base,
+ driDrawPriv->w, driDrawPriv->h);
+ }
+ if (readFb->Width == 0 && driReadPriv->w) {
+ _mesa_resize_framebuffer(&intel->ctx, readFb,
+ driReadPriv->w, driReadPriv->h);
+ }
}
else {
_mesa_make_current(NULL, NULL, NULL);
struct intel_renderbuffer *
intel_get_renderbuffer(struct gl_framebuffer *fb, GLuint attIndex)
{
- if (fb->Name == 0) {
- struct intel_framebuffer *intel_fb = (struct intel_framebuffer*)fb;
-
- if (intel_fb->pf_current_page) {
- switch (attIndex) {
- case BUFFER_BACK_LEFT:
- attIndex = BUFFER_FRONT_LEFT;
- break;
- case BUFFER_FRONT_LEFT:
- attIndex = BUFFER_BACK_LEFT;
- break;
- }
- }
+ return intel_renderbuffer(fb->Attachment[attIndex].Renderbuffer);
+}
+
+
+void
+intel_flip_renderbuffers(struct intel_framebuffer *intel_fb)
+{
+ int current_page = intel_fb->pf_current_page;
+ int next_page = (current_page + 1) % intel_fb->pf_num_pages;
+
+ if (intel_fb->Base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer !=
+ &intel_fb->color_rb[current_page]->Base) {
+ _mesa_remove_renderbuffer(&intel_fb->Base, BUFFER_FRONT_LEFT);
+ _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_FRONT_LEFT,
+ &intel_fb->color_rb[current_page]->Base);
}
- return intel_renderbuffer(fb->Attachment[attIndex].Renderbuffer);
+ if (intel_fb->Base.Attachment[BUFFER_BACK_LEFT].Renderbuffer !=
+ &intel_fb->color_rb[next_page]->Base) {
+ _mesa_remove_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT);
+ _mesa_add_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT,
+ &intel_fb->color_rb[next_page]->Base);
+ }
}
intel_alloc_window_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
GLenum internalFormat, GLuint width, GLuint height)
{
+ struct intel_context *intel = intel_context(ctx);
+ struct intel_framebuffer *intel_fb;
+
ASSERT(rb->Name == 0);
rb->Width = width;
rb->Height = height;
rb->_ActualFormat = internalFormat;
+
+ if (intel && intel->driDrawable &&
+ (intel_fb = intel->driDrawable->driverPrivate) &&
+ intel_fb->pf_num_pages == 3 &&
+ rb == &intel_fb->color_rb[intel_fb->pf_current_page]->Base &&
+ (rb = &intel_fb->color_rb[(intel_fb->pf_current_page + 2) % 3]->Base)) {
+ rb->Width = width;
+ rb->Height = height;
+ rb->_ActualFormat = internalFormat;
+ }
+
return GL_TRUE;
}
{
struct gl_framebuffer Base;
+ struct intel_renderbuffer *color_rb[3];
+
/* Drawable page flipping state */
GLboolean pf_active;
- GLboolean flip_pending;
+ GLuint pf_seq;
GLint pf_pipes;
GLint pf_current_page;
+ GLint pf_num_pages;
};
GLuint PairedDepth; /**< only used if this is a depth renderbuffer */
GLuint PairedStencil; /**< only used if this is a stencil renderbuffer */
+
+ GLuint pf_pending; /**< sequence number of pending flip */
};
*fb,
GLuint attIndex);
+extern void intel_flip_renderbuffers(struct intel_framebuffer *intel_fb);
+
/* XXX make inline or macro */
extern struct intel_region *intel_get_rb_region(struct gl_framebuffer *fb,
return GL_FALSE;
}
+ if (intelScreen->third.handle) {
+ if (0)
+ _mesa_printf("Third 0x%08x ", intelScreen->third.handle);
+ if (drmMap(sPriv->fd,
+ intelScreen->third.handle,
+ intelScreen->third.size,
+ (drmAddress *) & intelScreen->third.map) != 0) {
+ intelUnmapScreenRegions(intelScreen);
+ return GL_FALSE;
+ }
+ }
+
if (0)
_mesa_printf("Depth 0x%08x ", intelScreen->depth.handle);
if (drmMap(sPriv->fd,
}
#endif
if (0)
- printf("Mappings: front: %p back: %p depth: %p tex: %p\n",
+ printf("Mappings: front: %p back: %p third: %p depth: %p tex: %p\n",
intelScreen->front.map,
- intelScreen->back.map,
+ intelScreen->back.map, intelScreen->third.map,
intelScreen->depth.map, intelScreen->tex.map);
return GL_TRUE;
}
intelScreen->back.pitch / intelScreen->cpp,
intelScreen->height);
+ if (intelScreen->third.handle) {
+ intelScreen->third_region =
+ intel_recreate_static(intelScreen,
+ intelScreen->third_region,
+ DRM_BO_FLAG_MEM_TT,
+ intelScreen->third.offset,
+ intelScreen->third.map,
+ intelScreen->cpp,
+ intelScreen->third.pitch / intelScreen->cpp,
+ intelScreen->height);
+ }
+
/* Still assuming front.cpp == depth.cpp
*/
intelScreen->depth_region =
#endif
intelScreen->back.map = NULL;
}
+ if (intelScreen->third.map) {
+#if REALLY_UNMAP
+ if (drmUnmap(intelScreen->third.map, intelScreen->third.size) != 0)
+ printf("drmUnmap third failed!\n");
+#endif
+ intelScreen->third.map = NULL;
+ }
if (intelScreen->depth.map) {
#if REALLY_UNMAP
drmUnmap(intelScreen->depth.map, intelScreen->depth.size);
intelScreen->back.handle = sarea->back_handle;
intelScreen->back.size = sarea->back_size;
+ if (intelScreen->driScrnPriv->ddxMinor >= 8) {
+ intelScreen->third.offset = sarea->third_offset;
+ intelScreen->third.pitch = sarea->pitch * intelScreen->cpp;
+ intelScreen->third.handle = sarea->third_handle;
+ intelScreen->third.size = sarea->third_size;
+ }
+
intelScreen->depth.offset = sarea->depth_offset;
intelScreen->depth.pitch = sarea->pitch * intelScreen->cpp;
intelScreen->depth.handle = sarea->depth_handle;
/* setup the hardware-based renderbuffers */
{
- struct intel_renderbuffer *frontRb
+ intel_fb->color_rb[0]
= intel_create_renderbuffer(rgbFormat,
screen->width, screen->height,
screen->front.offset,
screen->front.pitch,
screen->cpp,
screen->front.map);
- intel_set_span_functions(&frontRb->Base);
+ intel_set_span_functions(&intel_fb->color_rb[0]->Base);
_mesa_add_renderbuffer(&intel_fb->Base, BUFFER_FRONT_LEFT,
- &frontRb->Base);
+ &intel_fb->color_rb[0]->Base);
}
if (mesaVis->doubleBufferMode) {
- struct intel_renderbuffer *backRb
+ intel_fb->color_rb[1]
= intel_create_renderbuffer(rgbFormat,
screen->width, screen->height,
screen->back.offset,
screen->back.pitch,
screen->cpp,
screen->back.map);
- intel_set_span_functions(&backRb->Base);
+ intel_set_span_functions(&intel_fb->color_rb[1]->Base);
_mesa_add_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT,
- &backRb->Base);
+ &intel_fb->color_rb[1]->Base);
+
+ if (screen->third.handle) {
+ intel_fb->color_rb[2]
+ = intel_create_renderbuffer(rgbFormat,
+ screen->width, screen->height,
+ screen->third.offset,
+ screen->third.pitch,
+ screen->cpp,
+ screen->third.map);
+ intel_set_span_functions(&intel_fb->color_rb[2]->Base);
+ }
}
if (mesaVis->depthBits == 24 && mesaVis->stencilBits == 8) {
{
intelRegion front;
intelRegion back;
+ intelRegion third;
intelRegion rotated;
intelRegion depth;
intelRegion tex;
struct intel_region *front_region;
struct intel_region *back_region;
+ struct intel_region *third_region;
struct intel_region *depth_region;
struct intel_region *rotated_region;
int pipeB_y;
int pipeB_w;
int pipeB_h;
+
+ /* Triple buffering */
+ drm_handle_t third_handle;
+ int third_offset;
+ int third_size;
+ unsigned int third_tiled;
} drmI830Sarea;
/* Flags for perf_boxes