intel_buffers.c revision beddf653a914903156712aa472b5deaddb7bbaed
1ad5e73887052193afda72db8efcb812bd083a4a8John McCall/**************************************************************************
25f2bfd4811996abb783aa6c7254c56baa6930e8cDouglas Gregor *
35f2bfd4811996abb783aa6c7254c56baa6930e8cDouglas Gregor * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlsson * All Rights Reserved.
59234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson *
69234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson * Permission is hereby granted, free of charge, to any person obtaining a
79234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson * copy of this software and associated documentation files (the
89234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson * "Software"), to deal in the Software without restriction, including
99234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson * without limitation the rights to use, copy, modify, merge, publish,
109234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson * distribute, sub license, and/or sell copies of the Software, and to
1131455256ae26cc7069111643ec4429ea564377daSean Hunt * permit persons to whom the Software is furnished to do so, subject to
1231455256ae26cc7069111643ec4429ea564377daSean Hunt * the following conditions:
1331455256ae26cc7069111643ec4429ea564377daSean Hunt *
149234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson * The above copyright notice and this permission notice (including the
155f2bfd4811996abb783aa6c7254c56baa6930e8cDouglas Gregor * next paragraph) shall be included in all copies or substantial portions
165f2bfd4811996abb783aa6c7254c56baa6930e8cDouglas Gregor * of the Software.
179234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson *
18b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlsson * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlsson * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlsson * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
219234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlsson * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlsson * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlsson * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
259234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson *
26b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlsson **************************************************************************/
27b1d947b1011cb559be5745153f292b2dfb46b8e6Anders Carlsson
284843e584b54460973b8445d38907bab0401ebb0cAnders Carlsson#include "intel_screen.h"
299234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson#include "intel_context.h"
304843e584b54460973b8445d38907bab0401ebb0cAnders Carlsson#include "intel_blit.h"
314843e584b54460973b8445d38907bab0401ebb0cAnders Carlsson#include "intel_buffers.h"
324843e584b54460973b8445d38907bab0401ebb0cAnders Carlsson#include "intel_chipset.h"
339234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson#include "intel_depthstencil.h"
34c6c91bc019ff7fa09f6570025ba011aad4c0d004Anders Carlsson#include "intel_fbo.h"
35984e06874685396ca2cb51f0008cfff7c9b3d9c6Anders Carlsson#include "intel_regions.h"
369234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson#include "intel_batchbuffer.h"
37984e06874685396ca2cb51f0008cfff7c9b3d9c6Anders Carlsson#include "intel_reg.h"
38984e06874685396ca2cb51f0008cfff7c9b3d9c6Anders Carlsson#include "context.h"
399234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson#include "utils.h"
40984e06874685396ca2cb51f0008cfff7c9b3d9c6Anders Carlsson#include "drirenderbuffer.h"
4191e20dd8bf1bc8980ee93839383d2bd170bce050Anders Carlsson#include "framebuffer.h"
429234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson#include "swrast/swrast.h"
4391e20dd8bf1bc8980ee93839383d2bd170bce050Anders Carlsson#include "vblank.h"
4491e20dd8bf1bc8980ee93839383d2bd170bce050Anders Carlsson#include "i915_drm.h"
452928c2107f2e0007f35fe1c224aab63535f1403dAnders Carlsson
4691e20dd8bf1bc8980ee93839383d2bd170bce050Anders Carlsson/* This block can be removed when libdrm >= 2.3.1 is required */
47329749c1ec1ead3c41af52260f1203e4991b4e83Anders Carlsson
481b42c794481f6f958267e4ba913d74fef43161f6Anders Carlsson#ifndef DRM_IOCTL_I915_FLIP
491b42c794481f6f958267e4ba913d74fef43161f6Anders Carlsson
50283a062a633d6e868aa2be319da812341fe73728Anders Carlsson#define DRM_VBLANK_FLIP 0x8000000
51283a062a633d6e868aa2be319da812341fe73728Anders Carlsson
522df9ced9fd1e8c7d7b38443db07e0e811de22571Chris Lattnertypedef struct drm_i915_flip {
539234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson   int pipes;
542df9ced9fd1e8c7d7b38443db07e0e811de22571Chris Lattner} drm_i915_flip_t;
557a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson
567a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson#undef DRM_IOCTL_I915_FLIP
577a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson#define DRM_IOCTL_I915_FLIP DRM_IOW(DRM_COMMAND_BASE + DRM_I915_FLIP, \
589234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson				    drm_i915_flip_t)
597a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson
607a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson#endif
619234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson
627a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson#define FILE_DEBUG_FLAG DEBUG_BLIT
637a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson
647a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson/**
659234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson * XXX move this into a new dri/common/cliprects.c file.
667a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson */
677a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders CarlssonGLboolean
689234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlssonintel_intersect_cliprects(drm_clip_rect_t * dst,
697a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson                          const drm_clip_rect_t * a,
707a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson                          const drm_clip_rect_t * b)
717a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson{
727a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson   GLint bx = b->x1;
739234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson   GLint by = b->y1;
747a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson   GLint bw = b->x2 - bx;
757a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson   GLint bh = b->y2 - by;
769234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson
777a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson   if (bx < a->x1)
787a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson      bw -= a->x1 - bx, bx = a->x1;
799234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson   if (by < a->y1)
807a0ba875a7dcee94ec74fa79b7f8a247d200a76cAnders Carlsson      bh -= a->y1 - by, by = a->y1;
810e650017acdbbeb0c590e77bbea88c200ea1caefAnders Carlsson   if (bx + bw > a->x2)
820e650017acdbbeb0c590e77bbea88c200ea1caefAnders Carlsson      bw = a->x2 - bx;
830e650017acdbbeb0c590e77bbea88c200ea1caefAnders Carlsson   if (by + bh > a->y2)
849234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson      bh = a->y2 - by;
850e650017acdbbeb0c590e77bbea88c200ea1caefAnders Carlsson   if (bw <= 0)
860e650017acdbbeb0c590e77bbea88c200ea1caefAnders Carlsson      return GL_FALSE;
879234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson   if (bh <= 0)
880e650017acdbbeb0c590e77bbea88c200ea1caefAnders Carlsson      return GL_FALSE;
89cf85b933fef4ce827df83ef2d22c322ab2078aa5Anders Carlsson
909234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson   dst->x1 = bx;
91cf85b933fef4ce827df83ef2d22c322ab2078aa5Anders Carlsson   dst->y1 = by;
92cf85b933fef4ce827df83ef2d22c322ab2078aa5Anders Carlsson   dst->x2 = bx + bw;
9303c9d530dbdcbb00b0b1ac0abced5dcce2e21408Anders Carlsson   dst->y2 = by + bh;
9403c9d530dbdcbb00b0b1ac0abced5dcce2e21408Anders Carlsson
9503c9d530dbdcbb00b0b1ac0abced5dcce2e21408Anders Carlsson   return GL_TRUE;
969234b7ff2bb99479fb97d5faa181a55aacf28b78Anders Carlsson}
977624f219388f2434a4988ba2508a6ca7b57ba1c3Anders Carlsson
987624f219388f2434a4988ba2508a6ca7b57ba1c3Anders Carlsson/**
997624f219388f2434a4988ba2508a6ca7b57ba1c3Anders Carlsson * Return pointer to current color drawing region, or NULL.
1007482e247163978792654ca1a99913e19dd507e0aAnders Carlsson */
1017482e247163978792654ca1a99913e19dd507e0aAnders Carlssonstruct intel_region *
1027624f219388f2434a4988ba2508a6ca7b57ba1c3Anders Carlssonintel_drawbuf_region(struct intel_context *intel)
1037624f219388f2434a4988ba2508a6ca7b57ba1c3Anders Carlsson{
104d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson   struct intel_renderbuffer *irbColor =
10503c9d530dbdcbb00b0b1ac0abced5dcce2e21408Anders Carlsson      intel_renderbuffer(intel->ctx.DrawBuffer->_ColorDrawBuffers[0]);
10603c9d530dbdcbb00b0b1ac0abced5dcce2e21408Anders Carlsson   if (irbColor)
10703c9d530dbdcbb00b0b1ac0abced5dcce2e21408Anders Carlsson      return irbColor->region;
10803c9d530dbdcbb00b0b1ac0abced5dcce2e21408Anders Carlsson   else
10903c9d530dbdcbb00b0b1ac0abced5dcce2e21408Anders Carlsson      return NULL;
1107624f219388f2434a4988ba2508a6ca7b57ba1c3Anders Carlsson}
1117624f219388f2434a4988ba2508a6ca7b57ba1c3Anders Carlsson
1127624f219388f2434a4988ba2508a6ca7b57ba1c3Anders Carlsson/**
1137482e247163978792654ca1a99913e19dd507e0aAnders Carlsson * Return pointer to current color reading region, or NULL.
1147482e247163978792654ca1a99913e19dd507e0aAnders Carlsson */
1157482e247163978792654ca1a99913e19dd507e0aAnders Carlssonstruct intel_region *
1167482e247163978792654ca1a99913e19dd507e0aAnders Carlssonintel_readbuf_region(struct intel_context *intel)
1177482e247163978792654ca1a99913e19dd507e0aAnders Carlsson{
118d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson   struct intel_renderbuffer *irb
119d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson      = intel_renderbuffer(intel->ctx.ReadBuffer->_ColorReadBuffer);
120d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson   if (irb)
121d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson      return irb->region;
122d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson   else
123d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson      return NULL;
124d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson}
125d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson
126d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson
127d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson
128d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson/**
129d553f8c57fc77a46f6a1a1c90d7fd8f2d0e96073Anders Carlsson * Update the following fields for rendering to a user-created FBO:
1307482e247163978792654ca1a99913e19dd507e0aAnders Carlsson *   intel->numClipRects
1317482e247163978792654ca1a99913e19dd507e0aAnders Carlsson *   intel->pClipRects
1327482e247163978792654ca1a99913e19dd507e0aAnders Carlsson *   intel->drawX
133d58d6f778de936516d8815783f2e88348c41dce4Anders Carlsson *   intel->drawY
1347482e247163978792654ca1a99913e19dd507e0aAnders Carlsson */
1355cc58c6cfe4a6378287dbf92f9b1a23e133a6118Anders Carlssonstatic void
1365cc58c6cfe4a6378287dbf92f9b1a23e133a6118Anders CarlssonintelSetRenderbufferClipRects(struct intel_context *intel)
1375cc58c6cfe4a6378287dbf92f9b1a23e133a6118Anders Carlsson{
1385cc58c6cfe4a6378287dbf92f9b1a23e133a6118Anders Carlsson   /* flush batch since pClipRects may change */
1395cc58c6cfe4a6378287dbf92f9b1a23e133a6118Anders Carlsson   intel_batchbuffer_flush(intel->batch);
1405cc58c6cfe4a6378287dbf92f9b1a23e133a6118Anders Carlsson
1415cc58c6cfe4a6378287dbf92f9b1a23e133a6118Anders Carlsson   assert(intel->ctx.DrawBuffer->Width > 0);
142add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson   assert(intel->ctx.DrawBuffer->Height > 0);
143add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson   intel->fboRect.x1 = 0;
144add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson   intel->fboRect.y1 = 0;
145add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson   intel->fboRect.x2 = intel->ctx.DrawBuffer->Width;
1468257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson   intel->fboRect.y2 = intel->ctx.DrawBuffer->Height;
147add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson   intel->numClipRects = 1;
148add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson   intel->pClipRects = &intel->fboRect;
149add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson   intel->drawX = 0;
150add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson   intel->drawY = 0;
151add28829c7a8d3c5da9ae140f18d3c9ad2d8b599Anders Carlsson}
152ae3524866124021f3bc695886668254093c0793fAnders Carlsson
153ae3524866124021f3bc695886668254093c0793fAnders Carlsson
154ae3524866124021f3bc695886668254093c0793fAnders Carlsson/**
155ae3524866124021f3bc695886668254093c0793fAnders Carlsson * As above, but for rendering to front buffer of a window.
156ae3524866124021f3bc695886668254093c0793fAnders Carlsson * \sa intelSetRenderbufferClipRects
157ae3524866124021f3bc695886668254093c0793fAnders Carlsson */
158ae3524866124021f3bc695886668254093c0793fAnders Carlssonstatic void
159ae3524866124021f3bc695886668254093c0793fAnders CarlssonintelSetFrontClipRects(struct intel_context *intel)
1601668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson{
1611668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson   __DRIdrawablePrivate *dPriv = intel->driDrawable;
1621668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson
1631668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson   if (!dPriv)
1641668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson      return;
1651668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson
1661668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson   /* flush batch since pClipRects may change */
167aeb85374e92619b8e4ce92ac6e30756b5053a137Anders Carlsson   intel_batchbuffer_flush(intel->batch);
1681668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson
1691668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson   intel->numClipRects = dPriv->numClipRects;
1701668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson   intel->pClipRects = dPriv->pClipRects;
1711668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson   intel->drawX = dPriv->x;
1721668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson   intel->drawY = dPriv->y;
1731668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson}
1741668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson
1751668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson
1761668f2062b237ddb137f5d16388b3dea49651f85Anders Carlsson/**
1770ccdf8d62cba2ad730001f133b6cc4836c42da83Anders Carlsson * As above, but for rendering to back buffer of a window.
1780ccdf8d62cba2ad730001f133b6cc4836c42da83Anders Carlsson */
1790ccdf8d62cba2ad730001f133b6cc4836c42da83Anders Carlssonstatic void
1800ccdf8d62cba2ad730001f133b6cc4836c42da83Anders CarlssonintelSetBackClipRects(struct intel_context *intel)
1810ccdf8d62cba2ad730001f133b6cc4836c42da83Anders Carlsson{
1820ccdf8d62cba2ad730001f133b6cc4836c42da83Anders Carlsson   __DRIdrawablePrivate *dPriv = intel->driDrawable;
1830ccdf8d62cba2ad730001f133b6cc4836c42da83Anders Carlsson   struct intel_framebuffer *intel_fb;
1840ccdf8d62cba2ad730001f133b6cc4836c42da83Anders Carlsson
18550755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson   if (!dPriv)
18620c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley      return;
18750755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson
18850755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson   /* flush batch since pClipRects may change */
18950755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson   intel_batchbuffer_flush(intel->batch);
19050755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson
19150755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson   intel_fb = dPriv->driverPrivate;
19250755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson
19350755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson   if (intel_fb->pf_active || dPriv->numBackClipRects == 0) {
19450755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson      /* use the front clip rects */
19550755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson      intel->numClipRects = dPriv->numClipRects;
19650755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson      intel->pClipRects = dPriv->pClipRects;
19720c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley      intel->drawX = dPriv->x;
19850755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson      intel->drawY = dPriv->y;
19926a6ec7be5ad57aa380f62aa2c39cd073e22d9dcJohn McCall   }
20050755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson   else {
20126a6ec7be5ad57aa380f62aa2c39cd073e22d9dcJohn McCall      /* use the back clip rects */
20250755b0dcc81eed9dcf27abe9162527013f26bd4Anders Carlsson      intel->numClipRects = dPriv->numBackClipRects;
203b217c1b9d2225521f4021984ad5a424784fa22bbAnders Carlsson      intel->pClipRects = dPriv->pBackClipRects;
204b217c1b9d2225521f4021984ad5a424784fa22bbAnders Carlsson      intel->drawX = dPriv->backX;
205b217c1b9d2225521f4021984ad5a424784fa22bbAnders Carlsson      intel->drawY = dPriv->backY;
206b217c1b9d2225521f4021984ad5a424784fa22bbAnders Carlsson   }
207b217c1b9d2225521f4021984ad5a424784fa22bbAnders Carlsson}
208b217c1b9d2225521f4021984ad5a424784fa22bbAnders Carlsson
209b217c1b9d2225521f4021984ad5a424784fa22bbAnders Carlsson#ifdef I915
210b217c1b9d2225521f4021984ad5a424784fa22bbAnders Carlssonstatic void
211b217c1b9d2225521f4021984ad5a424784fa22bbAnders CarlssonintelUpdatePageFlipping(struct intel_context *intel,
212c4355b6883382b85cda3b7337587784dabf3450bAnders Carlsson			GLint areaA, GLint areaB)
2135c478cf2d54157062cd843737324e0d0df03a464Anders Carlsson{
214c4355b6883382b85cda3b7337587784dabf3450bAnders Carlsson   __DRIdrawablePrivate *dPriv = intel->driDrawable;
2155c478cf2d54157062cd843737324e0d0df03a464Anders Carlsson   struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
216c4355b6883382b85cda3b7337587784dabf3450bAnders Carlsson   GLboolean pf_active;
217c4355b6883382b85cda3b7337587784dabf3450bAnders Carlsson   GLint pf_planes;
218c4355b6883382b85cda3b7337587784dabf3450bAnders Carlsson
219c4355b6883382b85cda3b7337587784dabf3450bAnders Carlsson   /* Update page flipping info */
220c4355b6883382b85cda3b7337587784dabf3450bAnders Carlsson   pf_planes = 0;
221c4355b6883382b85cda3b7337587784dabf3450bAnders Carlsson
2228e51a1f5da6ef4a1a168d14116c6eed3a578a263John McCall   if (areaA > 0)
223c4355b6883382b85cda3b7337587784dabf3450bAnders Carlsson      pf_planes |= 1;
224c4355b6883382b85cda3b7337587784dabf3450bAnders Carlsson
225c4355b6883382b85cda3b7337587784dabf3450bAnders Carlsson   if (areaB > 0)
226c4355b6883382b85cda3b7337587784dabf3450bAnders Carlsson      pf_planes |= 2;
227a7694087e4abaea261918ffbb3ffe38feb1da489Anders Carlsson
22820c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley   intel_fb->pf_current_page = (intel->sarea->pf_current_page >>
22926a6ec7be5ad57aa380f62aa2c39cd073e22d9dcJohn McCall				(intel_fb->pf_planes & 0x2)) & 0x3;
230a7694087e4abaea261918ffbb3ffe38feb1da489Anders Carlsson
23126a6ec7be5ad57aa380f62aa2c39cd073e22d9dcJohn McCall   intel_fb->pf_num_pages = intel->intelScreen->third.handle ? 3 : 2;
232a7694087e4abaea261918ffbb3ffe38feb1da489Anders Carlsson
233e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson   pf_active = pf_planes && (pf_planes & intel->sarea->pf_active) == pf_planes;
23458040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson
23558040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson   if (INTEL_DEBUG & DEBUG_LOCK)
23620c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley      if (pf_active != intel_fb->pf_active)
23758040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson	 _mesa_printf("%s - Page flipping %sactive\n", __progname,
23858040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson		      pf_active ? "" : "in");
23958040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson
24058040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson   if (pf_active) {
24158040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson      /* Sync pages between planes if flipping on both at the same time */
24258040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson      if (pf_planes == 0x3 && pf_planes != intel_fb->pf_planes &&
24358040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson	  (intel->sarea->pf_current_page & 0x3) !=
24426a6ec7be5ad57aa380f62aa2c39cd073e22d9dcJohn McCall	  (((intel->sarea->pf_current_page) >> 2) & 0x3)) {
24520c0da7787c9a7d2529e42a4a91d777778595d74John Wiegley	 drm_i915_flip_t flip;
24658040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson
24758040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson	 if (intel_fb->pf_current_page ==
24858040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson	     (intel->sarea->pf_current_page & 0x3)) {
24958040a5ee50bcaebbcbebe47fbdc5fd70be90e83Anders Carlsson	    /* XXX: This is ugly, but emitting two flips 'in a row' can cause
250e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson	     * lockups for unknown reasons.
251e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson	     */
252e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson	    intel->sarea->pf_current_page =
2538f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor	       intel->sarea->pf_current_page & 0x3;
254e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson	    intel->sarea->pf_current_page |=
255e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson	       ((intel_fb->pf_current_page + intel_fb->pf_num_pages - 1) %
256e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson		intel_fb->pf_num_pages) << 2;
2578f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor
258e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson	    flip.pipes = 0x2;
259e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson	 } else {
260e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson	    intel->sarea->pf_current_page =
261e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson	       intel->sarea->pf_current_page & (0x3 << 2);
262e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson	    intel->sarea->pf_current_page |=
2638f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor	       (intel_fb->pf_current_page + intel_fb->pf_num_pages - 1) %
264e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson	       intel_fb->pf_num_pages;
265e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson
266e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson	    flip.pipes = 0x1;
2678f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor	 }
268e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson
269e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson	 drmCommandWrite(intel->driFd, DRM_I915_FLIP, &flip, sizeof(flip));
270e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson      }
271e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson
2728f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor      intel_fb->pf_planes = pf_planes;
273e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson   }
274e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson
275e170ba7846bc4cae4b376b52eb4448645c141e59Anders Carlsson   intel_fb->pf_active = pf_active;
2768257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson   intel_flip_renderbuffers(intel_fb);
2778257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson   intel_draw_buffer(&intel->ctx, intel->ctx.DrawBuffer);
2788257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson}
2798257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson#endif /* I915 */
2808257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson
2818257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson/**
2828257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson * This will be called whenever the currently bound window is moved/resized.
2838257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson * XXX: actually, it seems to NOT be called when the window is only moved (BP).
2848257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson */
2858257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlssonvoid
2868257d411a759b91921681c3b7f79e50e0d9252dbAnders CarlssonintelWindowMoved(struct intel_context *intel)
2878257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson{
2888257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson   GLcontext *ctx = &intel->ctx;
2898257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson   __DRIdrawablePrivate *dPriv = intel->driDrawable;
2908257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson   struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
2918257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson
2928257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson   if (!intel->ctx.DrawBuffer) {
2938257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson      /* when would this happen? -BP */
2948257d411a759b91921681c3b7f79e50e0d9252dbAnders Carlsson      intelSetFrontClipRects(intel);
2959e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson   }
2969e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson   else if (intel->ctx.DrawBuffer->Name != 0) {
2979e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson      /* drawing to user-created FBO - do nothing */
2989e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson      /* Cliprects would be set from intelDrawBuffer() */
2999e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson   }
3009e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson   else {
3019e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson      /* drawing to a window */
3029e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson      switch (intel_fb->Base._ColorDrawBufferIndexes[0]) {
3039e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson      case BUFFER_FRONT_LEFT:
3049e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson         intelSetFrontClipRects(intel);
3059e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson         break;
3069e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson      case BUFFER_BACK_LEFT:
3079e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson         intelSetBackClipRects(intel);
3088f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor         break;
3099e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson      default:
3109e85c743a4cefff7386764bba3f3f2cdbe5c06e2Anders Carlsson         intelSetFrontClipRects(intel);
311f28c687866aed1ed7b4b9ddf44a51673861236cfAnders Carlsson      }
312f28c687866aed1ed7b4b9ddf44a51673861236cfAnders Carlsson   }
313a9efbf009468f36df0bb66551677339055757d51Nuno Lopes
314a9efbf009468f36df0bb66551677339055757d51Nuno Lopes   if (intel->intelScreen->driScrnPriv->ddx_version.minor >= 7) {
31531455256ae26cc7069111643ec4429ea564377daSean Hunt      volatile drmI830Sarea *sarea = intel->sarea;
31631455256ae26cc7069111643ec4429ea564377daSean Hunt      drm_clip_rect_t drw_rect = { .x1 = dPriv->x, .x2 = dPriv->x + dPriv->w,
31731455256ae26cc7069111643ec4429ea564377daSean Hunt				   .y1 = dPriv->y, .y2 = dPriv->y + dPriv->h };
31831455256ae26cc7069111643ec4429ea564377daSean Hunt      drm_clip_rect_t planeA_rect = { .x1 = sarea->planeA_x, .y1 = sarea->planeA_y,
31931455256ae26cc7069111643ec4429ea564377daSean Hunt				     .x2 = sarea->planeA_x + sarea->planeA_w,
32031455256ae26cc7069111643ec4429ea564377daSean Hunt				     .y2 = sarea->planeA_y + sarea->planeA_h };
32131455256ae26cc7069111643ec4429ea564377daSean Hunt      drm_clip_rect_t planeB_rect = { .x1 = sarea->planeB_x, .y1 = sarea->planeB_y,
32231455256ae26cc7069111643ec4429ea564377daSean Hunt				     .x2 = sarea->planeB_x + sarea->planeB_w,
32331455256ae26cc7069111643ec4429ea564377daSean Hunt				     .y2 = sarea->planeB_y + sarea->planeB_h };
32431455256ae26cc7069111643ec4429ea564377daSean Hunt      GLint areaA = driIntersectArea( drw_rect, planeA_rect );
3251dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall      GLint areaB = driIntersectArea( drw_rect, planeB_rect );
3261dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall      GLuint flags = dPriv->vblFlags;
3271dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall
3281dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall#ifdef I915
3291dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall      intelUpdatePageFlipping(intel, areaA, areaB);
3301dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall#endif
3311dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall
3321dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall      /* Update vblank info
3331dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall       */
3341dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall      if (areaB > areaA || (areaA == areaB && areaB > 0)) {
3351dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall	 flags = dPriv->vblFlags | VBLANK_FLAG_SECONDARY;
3361dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall      } else {
3371dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall	 flags = dPriv->vblFlags & ~VBLANK_FLAG_SECONDARY;
3381dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall      }
3391dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall
3401dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall      /* Check to see if we changed pipes */
3411dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall      if (flags != dPriv->vblFlags && dPriv->vblFlags &&
3421dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall	  !(dPriv->vblFlags & VBLANK_FLAG_NO_IRQ)) {
3431dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall	 int64_t count;
3441dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall	 drmVBlank vbl;
3451dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall	 int i;
3461dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall
3471dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall	 /*
3481dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall	  * Deal with page flipping
3491dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall	  */
3501dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall	 vbl.request.type = DRM_VBLANK_ABSOLUTE;
3511b6005285e234bc30698917b2d3abb2f1f98bc77John McCall
3521dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall	 if ( dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) {
3531dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall	    vbl.request.type |= DRM_VBLANK_SECONDARY;
3541dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall	 }
3551dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall
3561dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall	 for (i = 0; i < intel_fb->pf_num_pages; i++) {
3571dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall	    if (!intel_fb->color_rb[i] ||
3581dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall		(intel_fb->vbl_waited - intel_fb->color_rb[i]->vbl_pending) <=
3592f27bf854f0519810b34afd209089cc75536b757John McCall		(1<<23))
3602f27bf854f0519810b34afd209089cc75536b757John McCall	       continue;
3612f27bf854f0519810b34afd209089cc75536b757John McCall
3622f27bf854f0519810b34afd209089cc75536b757John McCall	    vbl.request.sequence = intel_fb->color_rb[i]->vbl_pending;
3632f27bf854f0519810b34afd209089cc75536b757John McCall	    drmWaitVBlank(intel->driFd, &vbl);
3642f27bf854f0519810b34afd209089cc75536b757John McCall	 }
3652f27bf854f0519810b34afd209089cc75536b757John McCall
366e1e342f4a96f132d8d7e802284417bd520f9f4f8John McCall	 /*
3671dd7383dc48718c452e71a625b29531dd96fbb9dJohn McCall	  * Update msc_base from old pipe
36832fb4e1fd1cbd2ff006cc0e06c997e4eea2f0e28Douglas Gregor	  */
36932fb4e1fd1cbd2ff006cc0e06c997e4eea2f0e28Douglas Gregor	 driDrawableGetMSC32(dPriv->driScreenPriv, dPriv, &count);
37032fb4e1fd1cbd2ff006cc0e06c997e4eea2f0e28Douglas Gregor	 dPriv->msc_base = count;
37132fb4e1fd1cbd2ff006cc0e06c997e4eea2f0e28Douglas Gregor	 /*
3728f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor	  * Then get new vblank_base and vblSeq values
37332fb4e1fd1cbd2ff006cc0e06c997e4eea2f0e28Douglas Gregor	  */
37432fb4e1fd1cbd2ff006cc0e06c997e4eea2f0e28Douglas Gregor	 dPriv->vblFlags = flags;
375aec2523ab2c91413ef2f66dc944d0d6ac6a58abeAnders Carlsson	 driGetCurrentVBlank(dPriv);
37674990f45b0bc57fca81f908efb13d2b6c6350f03John McCall	 dPriv->vblank_base = dPriv->vblSeq;
377aec2523ab2c91413ef2f66dc944d0d6ac6a58abeAnders Carlsson
378aec2523ab2c91413ef2f66dc944d0d6ac6a58abeAnders Carlsson	 intel_fb->vbl_waited = dPriv->vblSeq;
379ad5e73887052193afda72db8efcb812bd083a4a8John McCall
380ad5e73887052193afda72db8efcb812bd083a4a8John McCall	 for (i = 0; i < intel_fb->pf_num_pages; i++) {
381ad5e73887052193afda72db8efcb812bd083a4a8John McCall	    if (intel_fb->color_rb[i])
382ad5e73887052193afda72db8efcb812bd083a4a8John McCall	       intel_fb->color_rb[i]->vbl_pending = intel_fb->vbl_waited;
383ad5e73887052193afda72db8efcb812bd083a4a8John McCall	 }
384ad5e73887052193afda72db8efcb812bd083a4a8John McCall      }
385ad5e73887052193afda72db8efcb812bd083a4a8John McCall   } else {
386ad5e73887052193afda72db8efcb812bd083a4a8John McCall      dPriv->vblFlags &= ~VBLANK_FLAG_SECONDARY;
387ad5e73887052193afda72db8efcb812bd083a4a8John McCall   }
388ad5e73887052193afda72db8efcb812bd083a4a8John McCall
389ad5e73887052193afda72db8efcb812bd083a4a8John McCall   /* Update Mesa's notion of window size */
390ad5e73887052193afda72db8efcb812bd083a4a8John McCall   driUpdateFramebufferSize(ctx, dPriv);
391ad5e73887052193afda72db8efcb812bd083a4a8John McCall   intel_fb->Base.Initialized = GL_TRUE; /* XXX remove someday */
392ad5e73887052193afda72db8efcb812bd083a4a8John McCall
393a0ce15c13a69c430d8980a1fcf03f420855c18caJohn McCall   /* Update hardware scissor */
394ad5e73887052193afda72db8efcb812bd083a4a8John McCall   if (ctx->Driver.Scissor != NULL) {
395ad5e73887052193afda72db8efcb812bd083a4a8John McCall      ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
396ad5e73887052193afda72db8efcb812bd083a4a8John McCall			  ctx->Scissor.Width, ctx->Scissor.Height);
397ad5e73887052193afda72db8efcb812bd083a4a8John McCall   }
398ad5e73887052193afda72db8efcb812bd083a4a8John McCall
399ad5e73887052193afda72db8efcb812bd083a4a8John McCall   /* Re-calculate viewport related state */
4004f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall   if (ctx->Driver.DepthRange != NULL)
401a0ce15c13a69c430d8980a1fcf03f420855c18caJohn McCall      ctx->Driver.DepthRange( ctx, ctx->Viewport.Near, ctx->Viewport.Far );
402ad5e73887052193afda72db8efcb812bd083a4a8John McCall}
4034f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall
404a0ce15c13a69c430d8980a1fcf03f420855c18caJohn McCall
405a0ce15c13a69c430d8980a1fcf03f420855c18caJohn McCall
4064f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall/* A true meta version of this would be very simple and additionally
407ad5e73887052193afda72db8efcb812bd083a4a8John McCall * machine independent.  Maybe we'll get there one day.
408ad5e73887052193afda72db8efcb812bd083a4a8John McCall */
4094f4e413f282609d4a488b44fc8669c28636a7abaJohn McCallstatic void
410ad5e73887052193afda72db8efcb812bd083a4a8John McCallintelClearWithTris(struct intel_context *intel, GLbitfield mask)
411ad5e73887052193afda72db8efcb812bd083a4a8John McCall{
412ad5e73887052193afda72db8efcb812bd083a4a8John McCall   GLcontext *ctx = &intel->ctx;
413ad5e73887052193afda72db8efcb812bd083a4a8John McCall   struct gl_framebuffer *fb = ctx->DrawBuffer;
414a0ce15c13a69c430d8980a1fcf03f420855c18caJohn McCall   GLuint buf;
415a0ce15c13a69c430d8980a1fcf03f420855c18caJohn McCall
416ad5e73887052193afda72db8efcb812bd083a4a8John McCall   intel->vtbl.install_meta_state(intel);
417ad5e73887052193afda72db8efcb812bd083a4a8John McCall
418ad5e73887052193afda72db8efcb812bd083a4a8John McCall   /* Back and stencil cliprects are the same.  Try and do both
419ad5e73887052193afda72db8efcb812bd083a4a8John McCall    * buffers at once:
420d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola    */
421d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola   if (mask & (BUFFER_BIT_BACK_LEFT | BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH)) {
422d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola      struct intel_region *backRegion =
423d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola	 intel_get_rb_region(fb, BUFFER_BACK_LEFT);
424d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola      struct intel_region *depthRegion =
425d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola	 intel_get_rb_region(fb, BUFFER_DEPTH);
426d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola
427d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola      intel->vtbl.meta_draw_region(intel, backRegion, depthRegion);
428d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola
429d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola      if (mask & BUFFER_BIT_BACK_LEFT)
430d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola	 intel->vtbl.meta_color_mask(intel, GL_TRUE);
431d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola      else
432d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola	 intel->vtbl.meta_color_mask(intel, GL_FALSE);
433d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola
434d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola      if (mask & BUFFER_BIT_STENCIL)
435d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola	 intel->vtbl.meta_stencil_replace(intel,
436d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola					  intel->ctx.Stencil.WriteMask[0],
437d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola					  intel->ctx.Stencil.Clear);
438d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola      else
439d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola	 intel->vtbl.meta_no_stencil_write(intel);
440d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola
441d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola      if (mask & BUFFER_BIT_DEPTH)
442d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola	 intel->vtbl.meta_depth_replace(intel);
443d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola      else
444d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola	 intel->vtbl.meta_no_depth_write(intel);
445d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola
446d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola      intel->vtbl.meta_draw_quad(intel,
447d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola				 fb->_Xmin,
448d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola				 fb->_Xmax,
449d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola				 fb->_Ymin,
450d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola				 fb->_Ymax,
451d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola				 intel->ctx.Depth.Clear,
452d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola				 intel->ClearColor8888,
4538f51a4f2d00b0abda3cde7f3828fb2e2b9beafb5Douglas Gregor				 0, 0, 0, 0);   /* texcoords */
454d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola
455d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola      mask &= ~(BUFFER_BIT_BACK_LEFT | BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH);
4567002f4c03c2d0544f4e8bea8d3a5636519081e35John McCall   }
457d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola
458d9800728cc3e7f478eec4d4b19af5b808ac51942Rafael Espindola   /* clear the remaining (color) renderbuffers */
4599b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola   for (buf = 0; buf < BUFFER_COUNT && mask; buf++) {
4609b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola      const GLuint bufBit = 1 << buf;
4619b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola      if (mask & bufBit) {
4629b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola	 struct intel_renderbuffer *irbColor =
4639b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola	    intel_renderbuffer(fb->Attachment[buf].Renderbuffer);
4649b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola
4659b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola	 ASSERT(irbColor);
4669b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola
4679b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola	 intel->vtbl.meta_no_depth_write(intel);
4689b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola	 intel->vtbl.meta_no_stencil_write(intel);
4699b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola	 intel->vtbl.meta_color_mask(intel, GL_TRUE);
4709b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola	 intel->vtbl.meta_draw_region(intel, irbColor->region, NULL);
4719b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola
4729b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola	 /* XXX: Using INTEL_BATCH_NO_CLIPRECTS here is dangerous as the
4739b35b25db3641dfa8876d24b41cfa5b4d51477cbRafael Espindola	  * drawing origin may not be correctly emitted.
474de81063acdc999fbe1225f466ead12f7e9107acfJohn McCall	  */
475de81063acdc999fbe1225f466ead12f7e9107acfJohn McCall	 intel->vtbl.meta_draw_quad(intel,
476de81063acdc999fbe1225f466ead12f7e9107acfJohn McCall				    fb->_Xmin,
477de81063acdc999fbe1225f466ead12f7e9107acfJohn McCall				    fb->_Xmax,
478de81063acdc999fbe1225f466ead12f7e9107acfJohn McCall				    fb->_Ymin,
479de81063acdc999fbe1225f466ead12f7e9107acfJohn McCall				    fb->_Ymax,
480de81063acdc999fbe1225f466ead12f7e9107acfJohn McCall				    0, intel->ClearColor8888,
481de81063acdc999fbe1225f466ead12f7e9107acfJohn McCall				    0, 0, 0, 0);   /* texcoords */
482de81063acdc999fbe1225f466ead12f7e9107acfJohn McCall
48393296683a70eed2fae0b694748ed4cc51c53aef4Anders Carlsson	 mask &= ~bufBit;
48493296683a70eed2fae0b694748ed4cc51c53aef4Anders Carlsson      }
48593296683a70eed2fae0b694748ed4cc51c53aef4Anders Carlsson   }
48693296683a70eed2fae0b694748ed4cc51c53aef4Anders Carlsson
48793296683a70eed2fae0b694748ed4cc51c53aef4Anders Carlsson   intel->vtbl.leave_meta_state(intel);
48893296683a70eed2fae0b694748ed4cc51c53aef4Anders Carlsson   intel_batchbuffer_flush(intel->batch);
48993296683a70eed2fae0b694748ed4cc51c53aef4Anders Carlsson}
49093296683a70eed2fae0b694748ed4cc51c53aef4Anders Carlsson
49193296683a70eed2fae0b694748ed4cc51c53aef4Anders Carlssonstatic const char *buffer_names[] = {
49293296683a70eed2fae0b694748ed4cc51c53aef4Anders Carlsson   [BUFFER_FRONT_LEFT] = "front",
49393296683a70eed2fae0b694748ed4cc51c53aef4Anders Carlsson   [BUFFER_BACK_LEFT] = "back",
49493296683a70eed2fae0b694748ed4cc51c53aef4Anders Carlsson   [BUFFER_FRONT_RIGHT] = "front right",
495dfc0d1ff1af5b199945a1ff98a6f7db0fdfb1615Anders Carlsson   [BUFFER_BACK_RIGHT] = "back right",
496dfc0d1ff1af5b199945a1ff98a6f7db0fdfb1615Anders Carlsson   [BUFFER_AUX0] = "aux0",
497dfc0d1ff1af5b199945a1ff98a6f7db0fdfb1615Anders Carlsson   [BUFFER_AUX1] = "aux1",
498dfc0d1ff1af5b199945a1ff98a6f7db0fdfb1615Anders Carlsson   [BUFFER_AUX2] = "aux2",
499dfc0d1ff1af5b199945a1ff98a6f7db0fdfb1615Anders Carlsson   [BUFFER_AUX3] = "aux3",
500dfc0d1ff1af5b199945a1ff98a6f7db0fdfb1615Anders Carlsson   [BUFFER_DEPTH] = "depth",
501b6f532e2b03dbbfd97a37a7bb845fe23f8136889John McCall   [BUFFER_STENCIL] = "stencil",
502b6f532e2b03dbbfd97a37a7bb845fe23f8136889John McCall   [BUFFER_ACCUM] = "accum",
503b6f532e2b03dbbfd97a37a7bb845fe23f8136889John McCall   [BUFFER_COLOR0] = "color0",
504b6f532e2b03dbbfd97a37a7bb845fe23f8136889John McCall   [BUFFER_COLOR1] = "color1",
505b6f532e2b03dbbfd97a37a7bb845fe23f8136889John McCall   [BUFFER_COLOR2] = "color2",
506b6f532e2b03dbbfd97a37a7bb845fe23f8136889John McCall   [BUFFER_COLOR3] = "color3",
507b6f532e2b03dbbfd97a37a7bb845fe23f8136889John McCall   [BUFFER_COLOR4] = "color4",
508b6f532e2b03dbbfd97a37a7bb845fe23f8136889John McCall   [BUFFER_COLOR5] = "color5",
509b6f532e2b03dbbfd97a37a7bb845fe23f8136889John McCall   [BUFFER_COLOR6] = "color6",
510b6f532e2b03dbbfd97a37a7bb845fe23f8136889John McCall   [BUFFER_COLOR7] = "color7",
511b6f532e2b03dbbfd97a37a7bb845fe23f8136889John McCall};
512b6f532e2b03dbbfd97a37a7bb845fe23f8136889John McCall
513c00cb6409307846a9bbcd86d307a1a91aab659d0Eli Friedman/**
514c00cb6409307846a9bbcd86d307a1a91aab659d0Eli Friedman * Called by ctx->Driver.Clear.
515c00cb6409307846a9bbcd86d307a1a91aab659d0Eli Friedman */
516c00cb6409307846a9bbcd86d307a1a91aab659d0Eli Friedmanstatic void
517c00cb6409307846a9bbcd86d307a1a91aab659d0Eli FriedmanintelClear(GLcontext *ctx, GLbitfield mask)
518c00cb6409307846a9bbcd86d307a1a91aab659d0Eli Friedman{
519c00cb6409307846a9bbcd86d307a1a91aab659d0Eli Friedman   struct intel_context *intel = intel_context(ctx);
520c00cb6409307846a9bbcd86d307a1a91aab659d0Eli Friedman   const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask);
521c00cb6409307846a9bbcd86d307a1a91aab659d0Eli Friedman   GLbitfield tri_mask = 0;
522c00cb6409307846a9bbcd86d307a1a91aab659d0Eli Friedman   GLbitfield blit_mask = 0;
523c00cb6409307846a9bbcd86d307a1a91aab659d0Eli Friedman   GLbitfield swrast_mask = 0;
5243dc7e7b9c59b9a2ed4f530b32e710a3738611df7John McCall   struct gl_framebuffer *fb = ctx->DrawBuffer;
5253dc7e7b9c59b9a2ed4f530b32e710a3738611df7John McCall   GLuint i;
5263dc7e7b9c59b9a2ed4f530b32e710a3738611df7John McCall
5273dc7e7b9c59b9a2ed4f530b32e710a3738611df7John McCall   if (0)
5283dc7e7b9c59b9a2ed4f530b32e710a3738611df7John McCall      fprintf(stderr, "%s\n", __FUNCTION__);
5293dc7e7b9c59b9a2ed4f530b32e710a3738611df7John McCall
5303dc7e7b9c59b9a2ed4f530b32e710a3738611df7John McCall   /* HW color buffers (front, back, aux, generic FBO, etc) */
5313dc7e7b9c59b9a2ed4f530b32e710a3738611df7John McCall   if (colorMask == ~0) {
5323dc7e7b9c59b9a2ed4f530b32e710a3738611df7John McCall      /* clear all R,G,B,A */
5333dc7e7b9c59b9a2ed4f530b32e710a3738611df7John McCall      /* XXX FBO: need to check if colorbuffers are software RBOs! */
5343dc7e7b9c59b9a2ed4f530b32e710a3738611df7John McCall      blit_mask |= (mask & BUFFER_BITS_COLOR);
5357121c8f551d9c91c0cf0e5e1f7f9aafa97241b17John McCall   }
5367121c8f551d9c91c0cf0e5e1f7f9aafa97241b17John McCall   else {
5377121c8f551d9c91c0cf0e5e1f7f9aafa97241b17John McCall      /* glColorMask in effect */
5387121c8f551d9c91c0cf0e5e1f7f9aafa97241b17John McCall      tri_mask |= (mask & BUFFER_BITS_COLOR);
5397121c8f551d9c91c0cf0e5e1f7f9aafa97241b17John McCall   }
5407121c8f551d9c91c0cf0e5e1f7f9aafa97241b17John McCall
5417121c8f551d9c91c0cf0e5e1f7f9aafa97241b17John McCall   /* HW stencil */
5427121c8f551d9c91c0cf0e5e1f7f9aafa97241b17John McCall   if (mask & BUFFER_BIT_STENCIL) {
5437121c8f551d9c91c0cf0e5e1f7f9aafa97241b17John McCall      const struct intel_region *stencilRegion
5447121c8f551d9c91c0cf0e5e1f7f9aafa97241b17John McCall         = intel_get_rb_region(fb, BUFFER_STENCIL);
5457121c8f551d9c91c0cf0e5e1f7f9aafa97241b17John McCall      if (stencilRegion) {
5466f615bc52bd5513019c32b378834a3c1b8425bf8John McCall         /* have hw stencil */
5476f615bc52bd5513019c32b378834a3c1b8425bf8John McCall         if (IS_965(intel->intelScreen->deviceID) ||
5486f615bc52bd5513019c32b378834a3c1b8425bf8John McCall	     (ctx->Stencil.WriteMask[0] & 0xff) != 0xff) {
5496f615bc52bd5513019c32b378834a3c1b8425bf8John McCall	    /* We have to use the 3D engine if we're clearing a partial mask
5506f615bc52bd5513019c32b378834a3c1b8425bf8John McCall	     * of the stencil buffer, or if we're on a 965 which has a tiled
5516f615bc52bd5513019c32b378834a3c1b8425bf8John McCall	     * depth/stencil buffer in a layout we can't blit to.
5526f615bc52bd5513019c32b378834a3c1b8425bf8John McCall	     */
5536f615bc52bd5513019c32b378834a3c1b8425bf8John McCall            tri_mask |= BUFFER_BIT_STENCIL;
5546f615bc52bd5513019c32b378834a3c1b8425bf8John McCall         }
5556f615bc52bd5513019c32b378834a3c1b8425bf8John McCall         else {
5566f615bc52bd5513019c32b378834a3c1b8425bf8John McCall            /* clearing all stencil bits, use blitting */
5576dbce19fdae4cfae4eb5f826284978e723a04e61John McCall            blit_mask |= BUFFER_BIT_STENCIL;
5586f615bc52bd5513019c32b378834a3c1b8425bf8John McCall         }
5596dbce19fdae4cfae4eb5f826284978e723a04e61John McCall      }
5606dbce19fdae4cfae4eb5f826284978e723a04e61John McCall   }
5616f615bc52bd5513019c32b378834a3c1b8425bf8John McCall
5626f615bc52bd5513019c32b378834a3c1b8425bf8John McCall   /* HW depth */
5635e1e89b8af283af34943a477dc6378f1a641df26John McCall   if (mask & BUFFER_BIT_DEPTH) {
5645e1e89b8af283af34943a477dc6378f1a641df26John McCall      /* clear depth with whatever method is used for stencil (see above) */
5655e1e89b8af283af34943a477dc6378f1a641df26John McCall      if (IS_965(intel->intelScreen->deviceID) ||
5665e1e89b8af283af34943a477dc6378f1a641df26John McCall	  tri_mask & BUFFER_BIT_STENCIL)
5675e1e89b8af283af34943a477dc6378f1a641df26John McCall         tri_mask |= BUFFER_BIT_DEPTH;
5685e1e89b8af283af34943a477dc6378f1a641df26John McCall      else
5695e1e89b8af283af34943a477dc6378f1a641df26John McCall         blit_mask |= BUFFER_BIT_DEPTH;
5705e1e89b8af283af34943a477dc6378f1a641df26John McCall   }
5715e1e89b8af283af34943a477dc6378f1a641df26John McCall
5725e1e89b8af283af34943a477dc6378f1a641df26John McCall   /* SW fallback clearing */
5735e1e89b8af283af34943a477dc6378f1a641df26John McCall   swrast_mask = mask & ~tri_mask & ~blit_mask;
5745e1e89b8af283af34943a477dc6378f1a641df26John McCall
5755e1e89b8af283af34943a477dc6378f1a641df26John McCall   for (i = 0; i < BUFFER_COUNT; i++) {
5765e1e89b8af283af34943a477dc6378f1a641df26John McCall      GLuint bufBit = 1 << i;
5775e1e89b8af283af34943a477dc6378f1a641df26John McCall      if ((blit_mask | tri_mask) & bufBit) {
5785e1e89b8af283af34943a477dc6378f1a641df26John McCall         if (!fb->Attachment[i].Renderbuffer->ClassID) {
5795e1e89b8af283af34943a477dc6378f1a641df26John McCall            blit_mask &= ~bufBit;
5805e1e89b8af283af34943a477dc6378f1a641df26John McCall            tri_mask &= ~bufBit;
5815e1e89b8af283af34943a477dc6378f1a641df26John McCall            swrast_mask |= bufBit;
5825e1e89b8af283af34943a477dc6378f1a641df26John McCall         }
5835e1e89b8af283af34943a477dc6378f1a641df26John McCall      }
5845e1e89b8af283af34943a477dc6378f1a641df26John McCall   }
5855e1e89b8af283af34943a477dc6378f1a641df26John McCall
5865e1e89b8af283af34943a477dc6378f1a641df26John McCall   intelFlush(ctx);             /* XXX intelClearWithBlit also does this */
5875e1e89b8af283af34943a477dc6378f1a641df26John McCall
5885e1e89b8af283af34943a477dc6378f1a641df26John McCall   if (blit_mask) {
5895e1e89b8af283af34943a477dc6378f1a641df26John McCall      if (INTEL_DEBUG & DEBUG_BLIT) {
5905e1e89b8af283af34943a477dc6378f1a641df26John McCall	 DBG("blit clear:");
5916dbce19fdae4cfae4eb5f826284978e723a04e61John McCall	 for (i = 0; i < BUFFER_COUNT; i++) {
5926dbce19fdae4cfae4eb5f826284978e723a04e61John McCall	    if (blit_mask & (1 << i))
5936dbce19fdae4cfae4eb5f826284978e723a04e61John McCall	       DBG(" %s", buffer_names[i]);
5946dbce19fdae4cfae4eb5f826284978e723a04e61John McCall	 }
5956dbce19fdae4cfae4eb5f826284978e723a04e61John McCall	 DBG("\n");
5966dbce19fdae4cfae4eb5f826284978e723a04e61John McCall      }
5976dbce19fdae4cfae4eb5f826284978e723a04e61John McCall      intelClearWithBlit(ctx, blit_mask);
5986dbce19fdae4cfae4eb5f826284978e723a04e61John McCall   }
5996dbce19fdae4cfae4eb5f826284978e723a04e61John McCall
6006dbce19fdae4cfae4eb5f826284978e723a04e61John McCall   if (tri_mask) {
6016dbce19fdae4cfae4eb5f826284978e723a04e61John McCall      if (INTEL_DEBUG & DEBUG_BLIT) {
6026dbce19fdae4cfae4eb5f826284978e723a04e61John McCall	 DBG("tri clear:");
6036dbce19fdae4cfae4eb5f826284978e723a04e61John McCall	 for (i = 0; i < BUFFER_COUNT; i++) {
6046dbce19fdae4cfae4eb5f826284978e723a04e61John McCall	    if (tri_mask & (1 << i))
6056dbce19fdae4cfae4eb5f826284978e723a04e61John McCall	       DBG(" %s", buffer_names[i]);
6066dbce19fdae4cfae4eb5f826284978e723a04e61John McCall	 }
6076dbce19fdae4cfae4eb5f826284978e723a04e61John McCall	 DBG("\n");
6086dbce19fdae4cfae4eb5f826284978e723a04e61John McCall      }
6096dbce19fdae4cfae4eb5f826284978e723a04e61John McCall      intelClearWithTris(intel, tri_mask);
6106dbce19fdae4cfae4eb5f826284978e723a04e61John McCall   }
6116dbce19fdae4cfae4eb5f826284978e723a04e61John McCall
6126dbce19fdae4cfae4eb5f826284978e723a04e61John McCall   if (swrast_mask) {
6136dbce19fdae4cfae4eb5f826284978e723a04e61John McCall      if (INTEL_DEBUG & DEBUG_BLIT) {
6146dbce19fdae4cfae4eb5f826284978e723a04e61John McCall	 DBG("swrast clear:");
6156dbce19fdae4cfae4eb5f826284978e723a04e61John McCall	 for (i = 0; i < BUFFER_COUNT; i++) {
6166dbce19fdae4cfae4eb5f826284978e723a04e61John McCall	    if (swrast_mask & (1 << i))
6176dbce19fdae4cfae4eb5f826284978e723a04e61John McCall	       DBG(" %s", buffer_names[i]);
6186dbce19fdae4cfae4eb5f826284978e723a04e61John McCall	 }
6196dbce19fdae4cfae4eb5f826284978e723a04e61John McCall	 DBG("\n");
6206dbce19fdae4cfae4eb5f826284978e723a04e61John McCall      }
6216dbce19fdae4cfae4eb5f826284978e723a04e61John McCall      _swrast_Clear(ctx, swrast_mask);
6226dbce19fdae4cfae4eb5f826284978e723a04e61John McCall   }
6236dbce19fdae4cfae4eb5f826284978e723a04e61John McCall}
6246dbce19fdae4cfae4eb5f826284978e723a04e61John McCall
6256dbce19fdae4cfae4eb5f826284978e723a04e61John McCall
6266dbce19fdae4cfae4eb5f826284978e723a04e61John McCall/* Emit wait for pending flips */
6276dbce19fdae4cfae4eb5f826284978e723a04e61John McCallvoid
6286dbce19fdae4cfae4eb5f826284978e723a04e61John McCallintel_wait_flips(struct intel_context *intel, GLuint batch_flags)
6296dbce19fdae4cfae4eb5f826284978e723a04e61John McCall{
6307281d1fbea62a4549b045bb7dc434904f2b609d8Fariborz Jahanian   struct intel_framebuffer *intel_fb =
6317281d1fbea62a4549b045bb7dc434904f2b609d8Fariborz Jahanian      (struct intel_framebuffer *) intel->ctx.DrawBuffer;
6327281d1fbea62a4549b045bb7dc434904f2b609d8Fariborz Jahanian   struct intel_renderbuffer *intel_rb =
6337281d1fbea62a4549b045bb7dc434904f2b609d8Fariborz Jahanian      intel_get_renderbuffer(&intel_fb->Base,
6347281d1fbea62a4549b045bb7dc434904f2b609d8Fariborz Jahanian			     intel_fb->Base._ColorDrawBufferIndexes[0] ==
6357281d1fbea62a4549b045bb7dc434904f2b609d8Fariborz Jahanian			     BUFFER_FRONT_LEFT ? BUFFER_FRONT_LEFT :
636e292368afa63337f5ff64c967857a898d6f868daAnders Carlsson			     BUFFER_BACK_LEFT);
637e292368afa63337f5ff64c967857a898d6f868daAnders Carlsson
638e292368afa63337f5ff64c967857a898d6f868daAnders Carlsson   if (intel_fb->Base.Name == 0 && intel_rb &&
639e292368afa63337f5ff64c967857a898d6f868daAnders Carlsson       intel_rb->pf_pending == intel_fb->pf_seq) {
640e292368afa63337f5ff64c967857a898d6f868daAnders Carlsson      GLint pf_planes = intel_fb->pf_planes;
641b47f74818094fabd8f150fb4d6d0fa8a6c52cde1John McCall      BATCH_LOCALS;
642b47f74818094fabd8f150fb4d6d0fa8a6c52cde1John McCall
643b47f74818094fabd8f150fb4d6d0fa8a6c52cde1John McCall      /* Wait for pending flips to take effect */
644b47f74818094fabd8f150fb4d6d0fa8a6c52cde1John McCall      BEGIN_BATCH(2, batch_flags);
645b47f74818094fabd8f150fb4d6d0fa8a6c52cde1John McCall      OUT_BATCH(pf_planes & 0x1 ? (MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP)
646b47f74818094fabd8f150fb4d6d0fa8a6c52cde1John McCall		: 0);
647b47f74818094fabd8f150fb4d6d0fa8a6c52cde1John McCall      OUT_BATCH(pf_planes & 0x2 ? (MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_B_FLIP)
648b47f74818094fabd8f150fb4d6d0fa8a6c52cde1John McCall		: 0);
649b47f74818094fabd8f150fb4d6d0fa8a6c52cde1John McCall      ADVANCE_BATCH();
650b47f74818094fabd8f150fb4d6d0fa8a6c52cde1John McCall
651b47f74818094fabd8f150fb4d6d0fa8a6c52cde1John McCall      intel_rb->pf_pending--;
652b47f74818094fabd8f150fb4d6d0fa8a6c52cde1John McCall   }
65374990f45b0bc57fca81f908efb13d2b6c6350f03John McCall}
65474990f45b0bc57fca81f908efb13d2b6c6350f03John McCall
65574990f45b0bc57fca81f908efb13d2b6c6350f03John McCall
65674990f45b0bc57fca81f908efb13d2b6c6350f03John McCall/* Flip the front & back buffers
65774990f45b0bc57fca81f908efb13d2b6c6350f03John McCall */
65874990f45b0bc57fca81f908efb13d2b6c6350f03John McCallstatic GLboolean
65974990f45b0bc57fca81f908efb13d2b6c6350f03John McCallintelPageFlip(const __DRIdrawablePrivate * dPriv)
66074990f45b0bc57fca81f908efb13d2b6c6350f03John McCall{
66174990f45b0bc57fca81f908efb13d2b6c6350f03John McCall#ifdef I915
66274990f45b0bc57fca81f908efb13d2b6c6350f03John McCall   struct intel_context *intel;
66374990f45b0bc57fca81f908efb13d2b6c6350f03John McCall   int ret;
66474990f45b0bc57fca81f908efb13d2b6c6350f03John McCall   struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
66574990f45b0bc57fca81f908efb13d2b6c6350f03John McCall
66674990f45b0bc57fca81f908efb13d2b6c6350f03John McCall   if (INTEL_DEBUG & DEBUG_IOCTL)
667c0a455942453a37dd7db83eb354f40a49872ab06John McCall      fprintf(stderr, "%s\n", __FUNCTION__);
668c0a455942453a37dd7db83eb354f40a49872ab06John McCall
669c0a455942453a37dd7db83eb354f40a49872ab06John McCall   assert(dPriv);
670c0a455942453a37dd7db83eb354f40a49872ab06John McCall   assert(dPriv->driContextPriv);
671c0a455942453a37dd7db83eb354f40a49872ab06John McCall   assert(dPriv->driContextPriv->driverPrivate);
672c0a455942453a37dd7db83eb354f40a49872ab06John McCall
673c0a455942453a37dd7db83eb354f40a49872ab06John McCall   intel = (struct intel_context *) dPriv->driContextPriv->driverPrivate;
674c0a455942453a37dd7db83eb354f40a49872ab06John McCall
675c0a455942453a37dd7db83eb354f40a49872ab06John McCall   if (intel->intelScreen->drmMinor < 9)
676c0a455942453a37dd7db83eb354f40a49872ab06John McCall      return GL_FALSE;
677c0a455942453a37dd7db83eb354f40a49872ab06John McCall
678c0a455942453a37dd7db83eb354f40a49872ab06John McCall   intelFlush(&intel->ctx);
6794f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall
6804f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall   ret = 0;
6814f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall
6824f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall   LOCK_HARDWARE(intel);
6834f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall
6844f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall   if (dPriv->numClipRects && intel_fb->pf_active) {
6854f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall      drm_i915_flip_t flip;
6864f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall
6874f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall      flip.pipes = intel_fb->pf_planes;
6884f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall
6894f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall      ret = drmCommandWrite(intel->driFd, DRM_I915_FLIP, &flip, sizeof(flip));
6904f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall   }
6914f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall
6924f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall   UNLOCK_HARDWARE(intel);
6934f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall
6944f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall   if (ret || !intel_fb->pf_active)
6954f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall      return GL_FALSE;
6964f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall
6974f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall   if (!dPriv->numClipRects) {
6984f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall      usleep(10000);	/* throttle invisible client 10ms */
6994f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall   }
7004f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall
7014f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall   intel_fb->pf_current_page = (intel->sarea->pf_current_page >>
7024f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall				(intel_fb->pf_planes & 0x2)) & 0x3;
7034f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall
7044f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall   if (dPriv->numClipRects != 0) {
7054f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall      intel_get_renderbuffer(&intel_fb->Base, BUFFER_FRONT_LEFT)->pf_pending =
7064f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall      intel_get_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT)->pf_pending =
7074f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall	 ++intel_fb->pf_seq;
7084f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall   }
7094f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall
7104f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall   intel_flip_renderbuffers(intel_fb);
7114f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall   intel_draw_buffer(&intel->ctx, &intel_fb->Base);
7124f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall
7134f4e413f282609d4a488b44fc8669c28636a7abaJohn McCall   return GL_TRUE;
714d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall#else
715d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall   return GL_FALSE;
716d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall#endif
717d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall}
718d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall
719d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall#if 0
720d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCallvoid
721d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCallintelSwapBuffers(__DRIdrawablePrivate * dPriv)
722d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall{
723d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall   if (dPriv->driverPrivate) {
724d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall      const struct gl_framebuffer *fb
725d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall         = (struct gl_framebuffer *) dPriv->driverPrivate;
726d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall      if (fb->Visual.doubleBufferMode) {
727d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall         GET_CURRENT_CONTEXT(ctx);
728d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall         if (ctx && ctx->DrawBuffer == fb) {
729d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall            _mesa_notifySwapBuffers(ctx);       /* flush pending rendering */
730d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall         }
731d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall         if (intel->doPageFlip) {
732d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall            intelPageFlip(dPriv);
733d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall         }
734d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall         else {
735d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall            intelCopyBuffer(dPriv);
736d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall         }
737d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall      }
738d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall   }
739d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall   else {
740d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall      _mesa_problem(NULL,
741d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall                    "dPriv has no gl_framebuffer pointer in intelSwapBuffers");
742d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall   }
743d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall}
744d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall#else
745d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall/* Trunk version:
746d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall */
747d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall
748d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCallstatic GLboolean
749d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCallintelScheduleSwap(__DRIdrawablePrivate * dPriv, GLboolean *missed_target)
750d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall{
75168a51a7f9c01ccbe7232d41beeb4deb26f40b013John McCall   struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
752d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall   unsigned int interval;
753d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall   struct intel_context *intel =
754561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      intelScreenContext(dPriv->driScreenPriv->private);
755561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor   const intelScreenPrivate *intelScreen = intel->intelScreen;
756561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor   unsigned int target;
757561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor   drm_i915_vblank_swap_t swap;
758561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor   GLboolean ret;
759561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor
760561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor   if (!dPriv->vblFlags ||
761561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor       (dPriv->vblFlags & VBLANK_FLAG_NO_IRQ) ||
762561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor       intelScreen->drmMinor < (intel_fb->pf_active ? 9 : 6))
763561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      return GL_FALSE;
764561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor
765561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor   interval = driGetVBlankInterval(dPriv);
766561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor
767561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor   swap.seqtype = DRM_VBLANK_ABSOLUTE;
768561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor
769561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor   if (dPriv->vblFlags & VBLANK_FLAG_SYNC) {
770561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      swap.seqtype |= DRM_VBLANK_NEXTONMISS;
771561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor   } else if (interval == 0) {
772561f81243f665cf2001caadc45df505f826b72d6Douglas Gregor      return GL_FALSE;
77335ee32e800145a535f2676898f8f06f7ae6e9b43John McCall   }
77435ee32e800145a535f2676898f8f06f7ae6e9b43John McCall
77535ee32e800145a535f2676898f8f06f7ae6e9b43John McCall   swap.drawable = dPriv->hHWDrawable;
77635ee32e800145a535f2676898f8f06f7ae6e9b43John McCall   target = swap.sequence = dPriv->vblSeq + interval;
77735ee32e800145a535f2676898f8f06f7ae6e9b43John McCall
77835ee32e800145a535f2676898f8f06f7ae6e9b43John McCall   if ( dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) {
77935ee32e800145a535f2676898f8f06f7ae6e9b43John McCall      swap.seqtype |= DRM_VBLANK_SECONDARY;
78035ee32e800145a535f2676898f8f06f7ae6e9b43John McCall   }
78135ee32e800145a535f2676898f8f06f7ae6e9b43John McCall
78235ee32e800145a535f2676898f8f06f7ae6e9b43John McCall   LOCK_HARDWARE(intel);
78335ee32e800145a535f2676898f8f06f7ae6e9b43John McCall
78435ee32e800145a535f2676898f8f06f7ae6e9b43John McCall   intel_batchbuffer_flush(intel->batch);
78535ee32e800145a535f2676898f8f06f7ae6e9b43John McCall
78635ee32e800145a535f2676898f8f06f7ae6e9b43John McCall   if ( intel_fb->pf_active ) {
78735ee32e800145a535f2676898f8f06f7ae6e9b43John McCall      swap.seqtype |= DRM_VBLANK_FLIP;
78835ee32e800145a535f2676898f8f06f7ae6e9b43John McCall
78935ee32e800145a535f2676898f8f06f7ae6e9b43John McCall      intel_fb->pf_current_page = (((intel->sarea->pf_current_page >>
79035ee32e800145a535f2676898f8f06f7ae6e9b43John McCall				     (intel_fb->pf_planes & 0x2)) & 0x3) + 1) %
79135ee32e800145a535f2676898f8f06f7ae6e9b43John McCall				  intel_fb->pf_num_pages;
79235ee32e800145a535f2676898f8f06f7ae6e9b43John McCall   }
79335ee32e800145a535f2676898f8f06f7ae6e9b43John McCall
79435ee32e800145a535f2676898f8f06f7ae6e9b43John McCall   if (!drmCommandWriteRead(intel->driFd, DRM_I915_VBLANK_SWAP, &swap,
79535ee32e800145a535f2676898f8f06f7ae6e9b43John McCall			    sizeof(swap))) {
79635ee32e800145a535f2676898f8f06f7ae6e9b43John McCall      dPriv->vblSeq = swap.sequence;
79735ee32e800145a535f2676898f8f06f7ae6e9b43John McCall      swap.sequence -= target;
79835ee32e800145a535f2676898f8f06f7ae6e9b43John McCall      *missed_target = swap.sequence > 0 && swap.sequence <= (1 << 23);
79935ee32e800145a535f2676898f8f06f7ae6e9b43John McCall
80035ee32e800145a535f2676898f8f06f7ae6e9b43John McCall      intel_get_renderbuffer(&intel_fb->Base, BUFFER_BACK_LEFT)->vbl_pending =
80135ee32e800145a535f2676898f8f06f7ae6e9b43John McCall	 intel_get_renderbuffer(&intel_fb->Base,
80235ee32e800145a535f2676898f8f06f7ae6e9b43John McCall				BUFFER_FRONT_LEFT)->vbl_pending =
80335ee32e800145a535f2676898f8f06f7ae6e9b43John McCall	 dPriv->vblSeq;
80435ee32e800145a535f2676898f8f06f7ae6e9b43John McCall
8055e78cd43a033b3dedf741fca4fa1652f9cb3e41cDouglas Gregor      if (swap.seqtype & DRM_VBLANK_FLIP) {
8065e78cd43a033b3dedf741fca4fa1652f9cb3e41cDouglas Gregor	 intel_flip_renderbuffers(intel_fb);
807edee94b615059ad178b06a489312eca6e049609aDouglas Gregor	 intel_draw_buffer(&intel->ctx, intel->ctx.DrawBuffer);
8085e78cd43a033b3dedf741fca4fa1652f9cb3e41cDouglas Gregor      }
8095e78cd43a033b3dedf741fca4fa1652f9cb3e41cDouglas Gregor
8105e78cd43a033b3dedf741fca4fa1652f9cb3e41cDouglas Gregor      ret = GL_TRUE;
8115e78cd43a033b3dedf741fca4fa1652f9cb3e41cDouglas Gregor   } else {
8125e78cd43a033b3dedf741fca4fa1652f9cb3e41cDouglas Gregor      if (swap.seqtype & DRM_VBLANK_FLIP) {
813edee94b615059ad178b06a489312eca6e049609aDouglas Gregor	 intel_fb->pf_current_page = ((intel->sarea->pf_current_page >>
814edee94b615059ad178b06a489312eca6e049609aDouglas Gregor					(intel_fb->pf_planes & 0x2)) & 0x3) %
815edee94b615059ad178b06a489312eca6e049609aDouglas Gregor				     intel_fb->pf_num_pages;
816edee94b615059ad178b06a489312eca6e049609aDouglas Gregor      }
817edee94b615059ad178b06a489312eca6e049609aDouglas Gregor
818edee94b615059ad178b06a489312eca6e049609aDouglas Gregor      ret = GL_FALSE;
819edee94b615059ad178b06a489312eca6e049609aDouglas Gregor   }
820edee94b615059ad178b06a489312eca6e049609aDouglas Gregor
821edee94b615059ad178b06a489312eca6e049609aDouglas Gregor   UNLOCK_HARDWARE(intel);
822edee94b615059ad178b06a489312eca6e049609aDouglas Gregor
823edee94b615059ad178b06a489312eca6e049609aDouglas Gregor   return ret;
824edee94b615059ad178b06a489312eca6e049609aDouglas Gregor}
825edee94b615059ad178b06a489312eca6e049609aDouglas Gregor
826edee94b615059ad178b06a489312eca6e049609aDouglas Gregorvoid
827edee94b615059ad178b06a489312eca6e049609aDouglas GregorintelSwapBuffers(__DRIdrawablePrivate * dPriv)
8285e78cd43a033b3dedf741fca4fa1652f9cb3e41cDouglas Gregor{
8291961791626ab0ebbd8bf901a37476d527def4edbDouglas Gregor   if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
8301961791626ab0ebbd8bf901a37476d527def4edbDouglas Gregor      GET_CURRENT_CONTEXT(ctx);
8311961791626ab0ebbd8bf901a37476d527def4edbDouglas Gregor      struct intel_context *intel;
8321961791626ab0ebbd8bf901a37476d527def4edbDouglas Gregor
8331961791626ab0ebbd8bf901a37476d527def4edbDouglas Gregor      if (ctx == NULL)
8341961791626ab0ebbd8bf901a37476d527def4edbDouglas Gregor	 return;
8351961791626ab0ebbd8bf901a37476d527def4edbDouglas Gregor
8361961791626ab0ebbd8bf901a37476d527def4edbDouglas Gregor      intel = intel_context(ctx);
8371961791626ab0ebbd8bf901a37476d527def4edbDouglas Gregor
8381961791626ab0ebbd8bf901a37476d527def4edbDouglas Gregor      if (ctx->Visual.doubleBufferMode) {
8391961791626ab0ebbd8bf901a37476d527def4edbDouglas Gregor	 GLboolean missed_target;
8401961791626ab0ebbd8bf901a37476d527def4edbDouglas Gregor	 struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
8411961791626ab0ebbd8bf901a37476d527def4edbDouglas Gregor	 int64_t ust;
84291832368ef1c1158c4351bdccaa141dac818f04eDouglas Gregor
84391832368ef1c1158c4351bdccaa141dac818f04eDouglas Gregor	 _mesa_notifySwapBuffers(ctx);  /* flush pending rendering comands */
84491832368ef1c1158c4351bdccaa141dac818f04eDouglas Gregor
84591832368ef1c1158c4351bdccaa141dac818f04eDouglas Gregor         if (!intelScheduleSwap(dPriv, &missed_target)) {
84691832368ef1c1158c4351bdccaa141dac818f04eDouglas Gregor	    driWaitForVBlank(dPriv, &missed_target);
84791832368ef1c1158c4351bdccaa141dac818f04eDouglas Gregor
84891832368ef1c1158c4351bdccaa141dac818f04eDouglas Gregor	    if (!intelPageFlip(dPriv)) {
84991832368ef1c1158c4351bdccaa141dac818f04eDouglas Gregor	       intelCopyBuffer(dPriv, NULL);
85091832368ef1c1158c4351bdccaa141dac818f04eDouglas Gregor	    }
85191832368ef1c1158c4351bdccaa141dac818f04eDouglas Gregor	 }
852
853	 intel_fb->swap_count++;
854	 (*dri_interface->getUST) (&ust);
855	 if (missed_target) {
856	    intel_fb->swap_missed_count++;
857	    intel_fb->swap_missed_ust = ust - intel_fb->swap_ust;
858	 }
859
860	 intel_fb->swap_ust = ust;
861      }
862   }
863   else {
864      /* XXX this shouldn't be an error but we can't handle it for now */
865      fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__);
866   }
867}
868#endif
869
870void
871intelCopySubBuffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h)
872{
873   if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
874      struct intel_context *intel =
875         (struct intel_context *) dPriv->driContextPriv->driverPrivate;
876      GLcontext *ctx = &intel->ctx;
877
878      if (ctx->Visual.doubleBufferMode) {
879         drm_clip_rect_t rect;
880         rect.x1 = x + dPriv->x;
881         rect.y1 = (dPriv->h - y - h) + dPriv->y;
882         rect.x2 = rect.x1 + w;
883         rect.y2 = rect.y1 + h;
884         _mesa_notifySwapBuffers(ctx);  /* flush pending rendering comands */
885         intelCopyBuffer(dPriv, &rect);
886      }
887   }
888   else {
889      /* XXX this shouldn't be an error but we can't handle it for now */
890      fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__);
891   }
892}
893
894
895/**
896 * Update the hardware state for drawing into a window or framebuffer object.
897 *
898 * Called by glDrawBuffer, glBindFramebufferEXT, MakeCurrent, and other
899 * places within the driver.
900 *
901 * Basically, this needs to be called any time the current framebuffer
902 * changes, the renderbuffers change, or we need to draw into different
903 * color buffers.
904 */
905void
906intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb)
907{
908   struct intel_context *intel = intel_context(ctx);
909   struct intel_region *colorRegion, *depthRegion = NULL;
910   struct intel_renderbuffer *irbDepth = NULL, *irbStencil = NULL;
911   int front = 0;               /* drawing to front color buffer? */
912
913   if (!fb) {
914      /* this can happen during the initial context initialization */
915      return;
916   }
917
918   /* Do this here, note core Mesa, since this function is called from
919    * many places within the driver.
920    */
921   if (ctx->NewState & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) {
922      /* this updates the DrawBuffer->_NumColorDrawBuffers fields, etc */
923      _mesa_update_framebuffer(ctx);
924      /* this updates the DrawBuffer's Width/Height if it's a FBO */
925      _mesa_update_draw_buffer_bounds(ctx);
926   }
927
928   if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
929      /* this may occur when we're called by glBindFrameBuffer() during
930       * the process of someone setting up renderbuffers, etc.
931       */
932      /*_mesa_debug(ctx, "DrawBuffer: incomplete user FBO\n");*/
933      return;
934   }
935
936   if (fb->Name)
937      intel_validate_paired_depth_stencil(ctx, fb);
938
939   /*
940    * How many color buffers are we drawing into?
941    */
942   if (fb->_NumColorDrawBuffers != 1) {
943      /* writing to 0 or 2 or 4 color buffers */
944      /*_mesa_debug(ctx, "Software rendering\n");*/
945      FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE);
946      colorRegion = NULL;
947
948      if (fb->Name != 0)
949	 intelSetRenderbufferClipRects(intel);
950   }
951   else {
952      /* draw to exactly one color buffer */
953      /*_mesa_debug(ctx, "Hardware rendering\n");*/
954      FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE);
955      if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) {
956         front = 1;
957      }
958
959      /*
960       * Get the intel_renderbuffer for the colorbuffer we're drawing into.
961       * And set up cliprects.
962       */
963      if (fb->Name == 0) {
964	 /* drawing to window system buffer */
965	 if (front) {
966	    intelSetFrontClipRects(intel);
967	    colorRegion = intel_get_rb_region(fb, BUFFER_FRONT_LEFT);
968	 }
969	 else {
970	    intelSetBackClipRects(intel);
971	    colorRegion = intel_get_rb_region(fb, BUFFER_BACK_LEFT);
972	 }
973      }
974      else {
975	 /* drawing to user-created FBO */
976	 struct intel_renderbuffer *irb;
977	 intelSetRenderbufferClipRects(intel);
978	 irb = intel_renderbuffer(fb->_ColorDrawBuffers[0]);
979	 colorRegion = (irb && irb->region) ? irb->region : NULL;
980      }
981   }
982
983   /* Update culling direction which changes depending on the
984    * orientation of the buffer:
985    */
986   if (ctx->Driver.FrontFace)
987      ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace);
988   else
989      ctx->NewState |= _NEW_POLYGON;
990
991   if (!colorRegion) {
992      FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE);
993   }
994   else {
995      FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE);
996   }
997
998   /***
999    *** Get depth buffer region and check if we need a software fallback.
1000    *** Note that the depth buffer is usually a DEPTH_STENCIL buffer.
1001    ***/
1002   if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped) {
1003      irbDepth = intel_renderbuffer(fb->_DepthBuffer->Wrapped);
1004      if (irbDepth && irbDepth->region) {
1005         FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_FALSE);
1006         depthRegion = irbDepth->region;
1007      }
1008      else {
1009         FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_TRUE);
1010         depthRegion = NULL;
1011      }
1012   }
1013   else {
1014      /* not using depth buffer */
1015      FALLBACK(intel, INTEL_FALLBACK_DEPTH_BUFFER, GL_FALSE);
1016      depthRegion = NULL;
1017   }
1018
1019   /***
1020    *** Stencil buffer
1021    *** This can only be hardware accelerated if we're using a
1022    *** combined DEPTH_STENCIL buffer (for now anyway).
1023    ***/
1024   if (fb->_StencilBuffer && fb->_StencilBuffer->Wrapped) {
1025      irbStencil = intel_renderbuffer(fb->_StencilBuffer->Wrapped);
1026      if (irbStencil && irbStencil->region) {
1027         ASSERT(irbStencil->Base._ActualFormat == GL_DEPTH24_STENCIL8_EXT);
1028         FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE);
1029         /* need to re-compute stencil hw state */
1030	 if (ctx->Driver.Enable != NULL)
1031	    ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled);
1032	 else
1033	    ctx->NewState |= _NEW_STENCIL;
1034         if (!depthRegion)
1035            depthRegion = irbStencil->region;
1036      }
1037      else {
1038         FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_TRUE);
1039      }
1040   }
1041   else {
1042      /* XXX FBO: instead of FALSE, pass ctx->Stencil.Enabled ??? */
1043      FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE);
1044      /* need to re-compute stencil hw state */
1045      if (ctx->Driver.Enable != NULL)
1046	 ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled);
1047      else
1048	 ctx->NewState |= _NEW_STENCIL;
1049   }
1050
1051   /*
1052    * Update depth test state
1053    */
1054   if (ctx->Driver.Enable) {
1055      if (ctx->Depth.Test && fb->Visual.depthBits > 0) {
1056	 ctx->Driver.Enable(ctx, GL_DEPTH_TEST, GL_TRUE);
1057      } else {
1058	 ctx->Driver.Enable(ctx, GL_DEPTH_TEST, GL_FALSE);
1059      }
1060   } else {
1061      ctx->NewState |= _NEW_DEPTH;
1062   }
1063
1064   intel->vtbl.set_draw_region(intel, colorRegion, depthRegion);
1065
1066   /* update viewport since it depends on window size */
1067   if (ctx->Driver.Viewport) {
1068      ctx->Driver.Viewport(ctx, ctx->Viewport.X, ctx->Viewport.Y,
1069			   ctx->Viewport.Width, ctx->Viewport.Height);
1070   } else {
1071      ctx->NewState |= _NEW_VIEWPORT;
1072   }
1073
1074   /* Set state we know depends on drawable parameters:
1075    */
1076   if (ctx->Driver.Scissor)
1077      ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
1078			  ctx->Scissor.Width, ctx->Scissor.Height);
1079   intel->NewGLState |= _NEW_SCISSOR;
1080
1081   if (ctx->Driver.DepthRange)
1082      ctx->Driver.DepthRange(ctx,
1083			     ctx->Viewport.Near,
1084			     ctx->Viewport.Far);
1085}
1086
1087
1088static void
1089intelDrawBuffer(GLcontext * ctx, GLenum mode)
1090{
1091   intel_draw_buffer(ctx, ctx->DrawBuffer);
1092}
1093
1094
1095static void
1096intelReadBuffer(GLcontext * ctx, GLenum mode)
1097{
1098   if (ctx->ReadBuffer == ctx->DrawBuffer) {
1099      /* This will update FBO completeness status.
1100       * A framebuffer will be incomplete if the GL_READ_BUFFER setting
1101       * refers to a missing renderbuffer.  Calling glReadBuffer can set
1102       * that straight and can make the drawing buffer complete.
1103       */
1104      intel_draw_buffer(ctx, ctx->DrawBuffer);
1105   }
1106   /* Generally, functions which read pixels (glReadPixels, glCopyPixels, etc)
1107    * reference ctx->ReadBuffer and do appropriate state checks.
1108    */
1109}
1110
1111
1112void
1113intelInitBufferFuncs(struct dd_function_table *functions)
1114{
1115   functions->Clear = intelClear;
1116   functions->DrawBuffer = intelDrawBuffer;
1117   functions->ReadBuffer = intelReadBuffer;
1118}
1119