summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/i915tex/intel_buffers.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/i915tex/intel_buffers.c')
-rw-r--r--src/mesa/drivers/dri/i915tex/intel_buffers.c156
1 files changed, 122 insertions, 34 deletions
diff --git a/src/mesa/drivers/dri/i915tex/intel_buffers.c b/src/mesa/drivers/dri/i915tex/intel_buffers.c
index a8fb0b14a1..fdb6ea9444 100644
--- a/src/mesa/drivers/dri/i915tex/intel_buffers.c
+++ b/src/mesa/drivers/dri/i915tex/intel_buffers.c
@@ -34,6 +34,7 @@
#include "intel_tris.h"
#include "intel_regions.h"
#include "intel_batchbuffer.h"
+#include "intel_reg.h"
#include "context.h"
#include "utils.h"
#include "drirenderbuffer.h"
@@ -155,11 +156,14 @@ static void
intelSetBackClipRects(struct intel_context *intel)
{
__DRIdrawablePrivate *dPriv = intel->driDrawable;
+ struct intel_framebuffer *intel_fb;
if (!dPriv)
return;
- if (intel->sarea->pf_active || dPriv->numBackClipRects == 0) {
+ intel_fb = dPriv->driverPrivate;
+
+ if (intel_fb->pf_active || dPriv->numBackClipRects == 0) {
/* use the front clip rects */
intel->numClipRects = dPriv->numClipRects;
intel->pClipRects = dPriv->pClipRects;
@@ -185,7 +189,7 @@ intelWindowMoved(struct intel_context *intel)
{
GLcontext *ctx = &intel->ctx;
__DRIdrawablePrivate *dPriv = intel->driDrawable;
- GLframebuffer *drawFb = (GLframebuffer *) dPriv->driverPrivate;
+ struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
if (!intel->ctx.DrawBuffer) {
/* when would this happen? -BP */
@@ -197,7 +201,7 @@ intelWindowMoved(struct intel_context *intel)
}
else {
/* drawing to a window */
- switch (drawFb->_ColorDrawBufferMask[0]) {
+ switch (intel_fb->Base._ColorDrawBufferMask[0]) {
case BUFFER_BIT_FRONT_LEFT:
intelSetFrontClipRects(intel);
break;
@@ -212,7 +216,7 @@ intelWindowMoved(struct intel_context *intel)
/* Update Mesa's notion of window size */
driUpdateFramebufferSize(ctx, dPriv);
- drawFb->Initialized = GL_TRUE; /* XXX remove someday */
+ intel_fb->Base.Initialized = GL_TRUE; /* XXX remove someday */
if (intel->intelScreen->driScrnPriv->ddxMinor >= 7) {
drmI830Sarea *sarea = intel->sarea;
@@ -227,7 +231,50 @@ intelWindowMoved(struct intel_context *intel)
GLint areaA = driIntersectArea( drw_rect, pipeA_rect );
GLint areaB = driIntersectArea( drw_rect, pipeB_rect );
GLuint flags = intel->vblank_flags;
+ GLboolean pf_active;
+ GLint pf_pipes;
+
+ /* Update page flipping info
+ */
+ pf_pipes = 0;
+
+ if (areaA > 0)
+ pf_pipes |= 1;
+
+ if (areaB > 0)
+ pf_pipes |= 2;
+
+ 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;
+
+ if (1 /*INTEL_DEBUG & DEBUG_LOCK*/)
+ if (pf_active != intel_fb->pf_active)
+ _mesa_printf("%s - Page flipping %sactive\n", __progname,
+ 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)) {
+ drm_i915_flip_t flip;
+
+ flip.pipes = (intel_fb->pf_current_page ==
+ (intel->sarea->pf_current_page & 0x3)) ? 0x2 : 0x1;
+
+ drmCommandWrite(intel->driFd, DRM_I915_FLIP, &flip, sizeof(flip));
+ }
+
+ intel_fb->pf_pipes = pf_pipes;
+ }
+
+ intel_fb->pf_active = pf_active;
+ driFlipRenderbuffers(intel->ctx.WinSysDrawBuffer, intel_fb->pf_current_page);
+ intel_draw_buffer(&intel->ctx, intel->ctx.DrawBuffer);
+ /* Update vblank info
+ */
if (areaB > areaA || (areaA == areaB && areaB > 0)) {
flags = intel->vblank_flags | VBLANK_FLAG_SECONDARY;
} else {
@@ -259,6 +306,7 @@ static void
intelClearWithTris(struct intel_context *intel, GLbitfield mask)
{
GLcontext *ctx = &intel->ctx;
+ struct gl_framebuffer *fb = ctx->DrawBuffer;
drm_clip_rect_t clear;
if (INTEL_DEBUG & DEBUG_BLIT)
@@ -274,10 +322,10 @@ intelClearWithTris(struct intel_context *intel, GLbitfield mask)
intel->vtbl.install_meta_state(intel);
/* Get clear bounds after locking */
- cx = ctx->DrawBuffer->_Xmin;
- cy = ctx->DrawBuffer->_Ymin;
- ch = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
- cw = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
+ cx = fb->_Xmin;
+ cy = fb->_Ymin;
+ ch = fb->_Ymax - cx;
+ cw = fb->_Xmax - cy;
/* note: regardless of 'all', cx, cy, cw, ch are now correct */
clear.x1 = cx;
@@ -291,9 +339,9 @@ intelClearWithTris(struct intel_context *intel, GLbitfield mask)
if (mask &
(BUFFER_BIT_BACK_LEFT | BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH)) {
struct intel_region *backRegion =
- intel_get_rb_region(ctx->DrawBuffer, BUFFER_BACK_LEFT);
+ intel_get_rb_region(fb, BUFFER_BACK_LEFT);
struct intel_region *depthRegion =
- intel_get_rb_region(ctx->DrawBuffer, BUFFER_DEPTH);
+ intel_get_rb_region(fb, BUFFER_DEPTH);
const GLuint clearColor = (backRegion && backRegion->cpp == 4)
? intel->ClearColor8888 : intel->ClearColor565;
@@ -330,8 +378,7 @@ intelClearWithTris(struct intel_context *intel, GLbitfield mask)
const GLuint bufBit = 1 << buf;
if (mask & bufBit) {
struct intel_renderbuffer *irbColor =
- intel_renderbuffer(ctx->DrawBuffer->
- Attachment[buf].Renderbuffer);
+ intel_renderbuffer(fb->Attachment[buf].Renderbuffer);
GLuint color = (irbColor->region->cpp == 4)
? intel->ClearColor8888 : intel->ClearColor565;
@@ -372,6 +419,7 @@ intelRotateWindow(struct intel_context *intel,
{
intelScreenPrivate *screen = intel->intelScreen;
drm_clip_rect_t fullRect;
+ struct intel_framebuffer *intel_fb;
struct intel_region *src;
const drm_clip_rect_t *clipRects;
int numClipRects;
@@ -421,8 +469,10 @@ intelRotateWindow(struct intel_context *intel,
intel->vtbl.meta_draw_region(intel, screen->rotated_region, NULL); /* ? */
- if ((srcBuf == BUFFER_BIT_BACK_LEFT && intel->sarea->pf_current_page) ||
- (srcBuf == BUFFER_BIT_FRONT_LEFT && !intel->sarea->pf_current_page)) {
+ intel_fb = dPriv->driverPrivate;
+
+ if ((srcBuf == BUFFER_BIT_BACK_LEFT && intel_fb->pf_current_page) ||
+ (srcBuf == BUFFER_BIT_FRONT_LEFT && !intel_fb->pf_current_page)) {
src = intel->intelScreen->front_region;
clipRects = dPriv->pClipRects;
numClipRects = dPriv->numClipRects;
@@ -517,6 +567,7 @@ intelClear(GLcontext *ctx, GLbitfield mask)
GLbitfield tri_mask = 0;
GLbitfield blit_mask = 0;
GLbitfield swrast_mask = 0;
+ struct gl_framebuffer *fb = ctx->DrawBuffer;
GLuint i;
if (0)
@@ -536,7 +587,7 @@ intelClear(GLcontext *ctx, GLbitfield mask)
/* HW stencil */
if (mask & BUFFER_BIT_STENCIL) {
const struct intel_region *stencilRegion
- = intel_get_rb_region(ctx->DrawBuffer, BUFFER_STENCIL);
+ = intel_get_rb_region(fb, BUFFER_STENCIL);
if (stencilRegion) {
/* have hw stencil */
if ((ctx->Stencil.WriteMask[0] & 0xff) != 0xff) {
@@ -565,7 +616,7 @@ intelClear(GLcontext *ctx, GLbitfield mask)
for (i = 0; i < BUFFER_COUNT; i++) {
GLuint bufBit = 1 << i;
if ((blit_mask | tri_mask) & bufBit) {
- if (!ctx->DrawBuffer->Attachment[i].Renderbuffer->ClassID) {
+ if (!fb->Attachment[i].Renderbuffer->ClassID) {
blit_mask &= ~bufBit;
tri_mask &= ~bufBit;
swrast_mask |= bufBit;
@@ -587,15 +638,44 @@ intelClear(GLcontext *ctx, GLbitfield mask)
}
+/* Emit wait for pending flips */
+void
+intel_wait_flips(struct intel_context *intel, GLuint batch_flags)
+{
+ struct intel_framebuffer *intel_fb =
+ (struct intel_framebuffer *) intel->ctx.DrawBuffer;
+
+ if (intel_fb->Base.Name == 0 && intel_fb->flip_pending) {
+ GLuint mi_wait = MI_WAIT_FOR_EVENT;
+ GLint pf_pipes = intel_fb->pf_pipes;
+ BATCH_LOCALS;
+
+ if (pf_pipes & 0x1)
+ mi_wait |= MI_WAIT_FOR_PLANE_A_FLIP;
+
+ if (pf_pipes & 0x2)
+ mi_wait |= MI_WAIT_FOR_PLANE_B_FLIP;
+
+ /* Wait for pending flips to take effect */
+ BEGIN_BATCH(2, batch_flags);
+ OUT_BATCH(mi_wait);
+ OUT_BATCH(0);
+ ADVANCE_BATCH();
+
+ intel_fb->flip_pending = GL_FALSE;
+ }
+}
+
/* Flip the front & back buffers
*/
-static void
+static GLboolean
intelPageFlip(const __DRIdrawablePrivate * dPriv)
{
struct intel_context *intel;
GLboolean missed_target;
int ret;
+ struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
if (INTEL_DEBUG & DEBUG_IOCTL)
fprintf(stderr, "%s\n", __FUNCTION__);
@@ -606,6 +686,9 @@ intelPageFlip(const __DRIdrawablePrivate * dPriv)
intel = (struct intel_context *) dPriv->driContextPriv->driverPrivate;
+ if (intel->intelScreen->drmMinor < 9)
+ return GL_FALSE;
+
intelFlush(&intel->ctx);
driWaitForVBlank(dPriv, &intel->vbl_seq, intel->vblank_flags, &missed_target);
@@ -615,28 +698,36 @@ intelPageFlip(const __DRIdrawablePrivate * dPriv)
(void)(*dri_interface->getUST) (&intel->swap_missed_ust);
}
+ ret = 0;
+
LOCK_HARDWARE(intel);
- if (!dPriv->numClipRects) {
- UNLOCK_HARDWARE(intel);
- usleep(10000); /* throttle invisible client 10ms */
- return;
+ if (dPriv->numClipRects && intel_fb->pf_active) {
+ drm_i915_flip_t flip;
+
+ flip.pipes = intel_fb->pf_pipes;
+
+ ret = drmCommandWrite(intel->driFd, DRM_I915_FLIP, &flip, sizeof(flip));
}
- 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;
+ if (ret || !intel_fb->pf_active)
+ return GL_FALSE;
+
+ if (!dPriv->numClipRects) {
+ usleep(10000); /* throttle invisible client 10ms */
}
- driFlipRenderbuffers(intel->ctx.WinSysDrawBuffer,
- intel->sarea->pf_current_page);
- intel_draw_buffer(&intel->ctx, intel->ctx.DrawBuffer);
+ 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);
- intel->flip_pending = GL_TRUE;
+ intel_fb->flip_pending = dPriv->numClipRects != 0;
+
+ return GL_TRUE;
}
#if 0
@@ -682,10 +773,7 @@ intelSwapBuffers(__DRIdrawablePrivate * dPriv)
if (ctx->Visual.doubleBufferMode) {
intelScreenPrivate *screen = intel->intelScreen;
_mesa_notifySwapBuffers(ctx); /* flush pending rendering comands */
- if (screen->current_rotation == 0 && intel->doPageFlip) {
- intelPageFlip(dPriv);
- }
- else {
+ if (screen->current_rotation != 0 || !intelPageFlip(dPriv)) {
intelCopyBuffer(dPriv, NULL);
}
if (screen->current_rotation != 0) {