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