1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Mesa 3-D graphics library 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Version: 7.1 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"), 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions: 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice shall be included 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * in all copies or substantial portions of the Software. 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/glheader.h" 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/context.h" 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/colormac.h" 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/condrender.h" 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/macros.h" 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/pixeltransfer.h" 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/imports.h" 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "s_context.h" 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "s_depth.h" 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "s_span.h" 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "s_stencil.h" 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "s_zoom.h" 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Determine if there's overlap in an image copy. 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This test also compensates for the fact that copies are done from 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * bottom to top and overlaps can sometimes be handled correctly 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without making a temporary image copy. 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \return GL_TRUE if the regions overlap, GL_FALSE otherwise. 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic GLboolean 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgregions_overlap(GLint srcx, GLint srcy, 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint dstx, GLint dsty, 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint width, GLint height, 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat zoomX, GLfloat zoomY) 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (zoomX == 1.0 && zoomY == 1.0) { 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* no zoom */ 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (srcx >= dstx + width || (srcx + width <= dstx)) { 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_FALSE; 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (srcy < dsty) { /* this is OK */ 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_FALSE; 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (srcy > dsty + height) { 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_FALSE; 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* add one pixel of slop when zooming, just to be safe */ 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (srcx > (dstx + ((zoomX > 0.0F) ? (width * zoomX + 1.0F) : 0.0F))) { 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* src is completely right of dest */ 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_FALSE; 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (srcx + width + 1.0F < dstx + ((zoomX > 0.0F) ? 0.0F : (width * zoomX))) { 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* src is completely left of dest */ 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_FALSE; 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if ((srcy < dsty) && (srcy + height < dsty + (height * zoomY))) { 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* src is completely below dest */ 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_FALSE; 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if ((srcy > dsty) && (srcy + height > dsty + (height * zoomY))) { 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* src is completely above dest */ 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_FALSE; 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * RGBA copypixels 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcopy_rgba_pixels(struct gl_context *ctx, GLint srcx, GLint srcy, 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint width, GLint height, GLint destx, GLint desty) 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat *tmpImage, *p; 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint sy, dy, stepy, row; 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F; 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint overlapping; 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint transferOps = ctx->_ImageTransferState; 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SWspan span; 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!ctx->ReadBuffer->_ColorReadBuffer) { 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* no readbuffer - OK */ 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ctx->DrawBuffer == ctx->ReadBuffer) { 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org overlapping = regions_overlap(srcx, srcy, destx, desty, width, height, 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Pixel.ZoomX, ctx->Pixel.ZoomY); 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org overlapping = GL_FALSE; 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Determine if copy should be done bottom-to-top or top-to-bottom */ 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!overlapping && srcy < desty) { 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* top-down max-to-min */ 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sy = srcy + height - 1; 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dy = desty + height - 1; 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stepy = -1; 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* bottom-up min-to-max */ 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sy = srcy; 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dy = desty; 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stepy = 1; 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org INIT_SPAN(span, GL_BITMAP); 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _swrast_span_default_attribs(ctx, &span); 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org span.arrayMask = SPAN_RGBA; 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org span.arrayAttribs = FRAG_BIT_COL0; /* we'll fill in COL0 attrib values */ 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (overlapping) { 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmpImage = (GLfloat *) malloc(width * height * sizeof(GLfloat) * 4); 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!tmpImage) { 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" ); 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* read the source image as RGBA/float */ 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p = tmpImage; 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (row = 0; row < height; row++) { 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _swrast_read_rgba_span( ctx, ctx->ReadBuffer->_ColorReadBuffer, 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org width, srcx, sy + row, p ); 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p += width * 4; 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p = tmpImage; 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmpImage = NULL; /* silence compiler warnings */ 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p = NULL; 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(width < SWRAST_MAX_WIDTH); 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (row = 0; row < height; row++, sy += stepy, dy += stepy) { 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLvoid *rgba = span.array->attribs[FRAG_ATTRIB_COL0]; 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Get row/span of source pixels */ 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (overlapping) { 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* get from buffered image */ 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(rgba, p, width * sizeof(GLfloat) * 4); 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p += width * 4; 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* get from framebuffer */ 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _swrast_read_rgba_span( ctx, ctx->ReadBuffer->_ColorReadBuffer, 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org width, srcx, sy, rgba ); 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (transferOps) { 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_apply_rgba_transfer_ops(ctx, transferOps, width, 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (GLfloat (*)[4]) rgba); 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Write color span */ 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org span.x = destx; 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org span.y = dy; 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org span.end = width; 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org span.array->ChanType = GL_FLOAT; 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (zoom) { 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _swrast_write_zoomed_rgba_span(ctx, destx, desty, &span, rgba); 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _swrast_write_rgba_span(ctx, &span); 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org span.array->ChanType = CHAN_TYPE; /* restore */ 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (overlapping) 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(tmpImage); 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Convert floating point Z values to integer Z values with pixel transfer's 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Z scale and bias. 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgscale_and_bias_z(struct gl_context *ctx, GLuint width, 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLfloat depth[], GLuint z[]) 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLuint depthMax = ctx->DrawBuffer->_DepthMax; 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint i; 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (depthMax <= 0xffffff && 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Pixel.DepthScale == 1.0 && 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Pixel.DepthBias == 0.0) { 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* no scale or bias and no clamping and no worry of overflow */ 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLfloat depthMaxF = ctx->DrawBuffer->_DepthMaxF; 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < width; i++) { 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org z[i] = (GLuint) (depth[i] * depthMaxF); 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* need to be careful with overflow */ 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLdouble depthMaxF = ctx->DrawBuffer->_DepthMaxF; 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < width; i++) { 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLdouble d = depth[i] * ctx->Pixel.DepthScale + ctx->Pixel.DepthBias; 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org d = CLAMP(d, 0.0, 1.0) * depthMaxF; 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (d >= depthMaxF) 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org z[i] = depthMax; 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org z[i] = (GLuint) d; 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TODO: Optimize!!!! 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcopy_depth_pixels( struct gl_context *ctx, GLint srcx, GLint srcy, 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint width, GLint height, 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint destx, GLint desty ) 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_framebuffer *fb = ctx->ReadBuffer; 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_renderbuffer *readRb = fb->Attachment[BUFFER_DEPTH].Renderbuffer; 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLfloat *p, *tmpImage, *depth; 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint sy, dy, stepy; 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint j; 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F; 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint overlapping; 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SWspan span; 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!readRb) { 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* no readbuffer - OK */ 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org INIT_SPAN(span, GL_BITMAP); 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _swrast_span_default_attribs(ctx, &span); 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org span.arrayMask = SPAN_Z; 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ctx->DrawBuffer == ctx->ReadBuffer) { 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org overlapping = regions_overlap(srcx, srcy, destx, desty, width, height, 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Pixel.ZoomX, ctx->Pixel.ZoomY); 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org overlapping = GL_FALSE; 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Determine if copy should be bottom-to-top or top-to-bottom */ 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!overlapping && srcy < desty) { 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* top-down max-to-min */ 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sy = srcy + height - 1; 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dy = desty + height - 1; 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stepy = -1; 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* bottom-up min-to-max */ 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sy = srcy; 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dy = desty; 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stepy = 1; 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (overlapping) { 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint ssy = sy; 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmpImage = (GLfloat *) malloc(width * height * sizeof(GLfloat)); 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!tmpImage) { 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" ); 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p = tmpImage; 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (j = 0; j < height; j++, ssy += stepy) { 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _swrast_read_depth_span_float(ctx, readRb, width, srcx, ssy, p); 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p += width; 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p = tmpImage; 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmpImage = NULL; /* silence compiler warning */ 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p = NULL; 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org depth = (GLfloat *) malloc(width * sizeof(GLfloat)); 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!depth) { 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels()"); 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto end; 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (j = 0; j < height; j++, sy += stepy, dy += stepy) { 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* get depth values */ 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (overlapping) { 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(depth, p, width * sizeof(GLfloat)); 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p += width; 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _swrast_read_depth_span_float(ctx, readRb, width, srcx, sy, depth); 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* apply scale and bias */ 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scale_and_bias_z(ctx, width, depth, span.array->z); 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* write depth values */ 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org span.x = destx; 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org span.y = dy; 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org span.end = width; 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (zoom) 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _swrast_write_zoomed_depth_span(ctx, destx, desty, &span); 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _swrast_write_rgba_span(ctx, &span); 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(depth); 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgend: 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (overlapping) 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(tmpImage); 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgcopy_stencil_pixels( struct gl_context *ctx, GLint srcx, GLint srcy, 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint width, GLint height, 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint destx, GLint desty ) 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_framebuffer *fb = ctx->ReadBuffer; 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_renderbuffer *rb = fb->Attachment[BUFFER_STENCIL].Renderbuffer; 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint sy, dy, stepy; 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint j; 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte *p, *tmpImage, *stencil; 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F; 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint overlapping; 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!rb) { 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* no readbuffer - OK */ 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ctx->DrawBuffer == ctx->ReadBuffer) { 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org overlapping = regions_overlap(srcx, srcy, destx, desty, width, height, 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Pixel.ZoomX, ctx->Pixel.ZoomY); 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org overlapping = GL_FALSE; 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Determine if copy should be bottom-to-top or top-to-bottom */ 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!overlapping && srcy < desty) { 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* top-down max-to-min */ 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sy = srcy + height - 1; 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dy = desty + height - 1; 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stepy = -1; 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* bottom-up min-to-max */ 379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org sy = srcy; 380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dy = desty; 381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stepy = 1; 382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (overlapping) { 385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint ssy = sy; 386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmpImage = (GLubyte *) malloc(width * height * sizeof(GLubyte)); 387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!tmpImage) { 388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" ); 389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p = tmpImage; 392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (j = 0; j < height; j++, ssy += stepy) { 393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _swrast_read_stencil_span( ctx, rb, width, srcx, ssy, p ); 394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p += width; 395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p = tmpImage; 397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmpImage = NULL; /* silence compiler warning */ 400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p = NULL; 401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org stencil = (GLubyte *) malloc(width * sizeof(GLubyte)); 404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!stencil) { 405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels()"); 406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org goto end; 407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (j = 0; j < height; j++, sy += stepy, dy += stepy) { 410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Get stencil values */ 411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (overlapping) { 412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy(stencil, p, width * sizeof(GLubyte)); 413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org p += width; 414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _swrast_read_stencil_span( ctx, rb, width, srcx, sy, stencil ); 417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_apply_stencil_transfer_ops(ctx, width, stencil); 420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Write stencil values */ 422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (zoom) { 423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _swrast_write_zoomed_stencil_span(ctx, destx, desty, width, 424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org destx, dy, stencil); 425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _swrast_write_stencil_span( ctx, width, destx, dy, stencil ); 428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(stencil); 432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgend: 434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (overlapping) 435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(tmpImage); 436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Try to do a fast 1:1 blit with memcpy. 441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \return GL_TRUE if successful, GL_FALSE otherwise. 442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgGLboolean 444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgswrast_fast_copy_pixels(struct gl_context *ctx, 445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint srcX, GLint srcY, GLsizei width, GLsizei height, 446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint dstX, GLint dstY, GLenum type) 447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_framebuffer *srcFb = ctx->ReadBuffer; 449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_framebuffer *dstFb = ctx->DrawBuffer; 450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_renderbuffer *srcRb, *dstRb; 451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint row; 452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint pixelBytes, widthInBytes; 453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte *srcMap, *dstMap; 454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint srcRowStride, dstRowStride; 455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type == GL_COLOR) { 457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (dstFb->_NumColorDrawBuffers != 1) 458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_FALSE; 459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org srcRb = srcFb->_ColorReadBuffer; 460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dstRb = dstFb->_ColorDrawBuffers[0]; 461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (type == GL_STENCIL) { 463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org srcRb = srcFb->Attachment[BUFFER_STENCIL].Renderbuffer; 464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dstRb = dstFb->Attachment[BUFFER_STENCIL].Renderbuffer; 465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (type == GL_DEPTH) { 467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org srcRb = srcFb->Attachment[BUFFER_DEPTH].Renderbuffer; 468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dstRb = dstFb->Attachment[BUFFER_DEPTH].Renderbuffer; 469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ASSERT(type == GL_DEPTH_STENCIL_EXT); 472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* XXX correct? */ 473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org srcRb = srcFb->Attachment[BUFFER_DEPTH].Renderbuffer; 474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dstRb = dstFb->Attachment[BUFFER_DEPTH].Renderbuffer; 475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* src and dst renderbuffers must be same format */ 478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!srcRb || !dstRb || srcRb->Format != dstRb->Format) { 479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_FALSE; 480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (type == GL_STENCIL || type == GL_DEPTH_COMPONENT) { 483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* can't handle packed depth+stencil here */ 484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (_mesa_is_format_packed_depth_stencil(srcRb->Format) || 485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_is_format_packed_depth_stencil(dstRb->Format)) 486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_FALSE; 487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else if (type == GL_DEPTH_STENCIL) { 489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* can't handle separate depth/stencil buffers */ 490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (srcRb != srcFb->Attachment[BUFFER_STENCIL].Renderbuffer || 491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dstRb != dstFb->Attachment[BUFFER_STENCIL].Renderbuffer) 492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_FALSE; 493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* clipping not supported */ 496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (srcX < 0 || srcX + width > (GLint) srcFb->Width || 497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org srcY < 0 || srcY + height > (GLint) srcFb->Height || 498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dstX < dstFb->_Xmin || dstX + width > dstFb->_Xmax || 499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dstY < dstFb->_Ymin || dstY + height > dstFb->_Ymax) { 500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_FALSE; 501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pixelBytes = _mesa_get_format_bytes(srcRb->Format); 504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org widthInBytes = width * pixelBytes; 505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (srcRb == dstRb) { 507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* map whole buffer for read/write */ 508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* XXX we could be clever and just map the union region of the 509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * source and dest rects. 510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLubyte *map; 512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint rowStride; 513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.MapRenderbuffer(ctx, srcRb, 0, 0, 515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org srcRb->Width, srcRb->Height, 516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, 517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &map, &rowStride); 518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!map) { 519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels"); 520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; /* don't retry with slow path */ 521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org srcMap = map + srcY * rowStride + srcX * pixelBytes; 524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dstMap = map + dstY * rowStride + dstX * pixelBytes; 525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* this handles overlapping copies */ 527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (srcY < dstY) { 528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* copy in reverse (top->down) order */ 529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org srcMap += rowStride * (height - 1); 530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dstMap += rowStride * (height - 1); 531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org srcRowStride = -rowStride; 532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dstRowStride = -rowStride; 533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* copy in normal (bottom->up) order */ 536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org srcRowStride = rowStride; 537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dstRowStride = rowStride; 538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* different src/dst buffers */ 542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.MapRenderbuffer(ctx, srcRb, srcX, srcY, 543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org width, height, 544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GL_MAP_READ_BIT, &srcMap, &srcRowStride); 545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!srcMap) { 546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels"); 547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; /* don't retry with slow path */ 548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.MapRenderbuffer(ctx, dstRb, dstX, dstY, 550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org width, height, 551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GL_MAP_WRITE_BIT, &dstMap, &dstRowStride); 552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!dstMap) { 553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.UnmapRenderbuffer(ctx, srcRb); 554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels"); 555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; /* don't retry with slow path */ 556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (row = 0; row < height; row++) { 560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* memmove() in case of overlap */ 561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memmove(dstMap, srcMap, widthInBytes); 562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org dstMap += dstRowStride; 563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org srcMap += srcRowStride; 564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.UnmapRenderbuffer(ctx, srcRb); 567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (dstRb != srcRb) { 568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.UnmapRenderbuffer(ctx, dstRb); 569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return GL_TRUE; 572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Find/map the renderbuffer that we'll be reading from. 577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The swrast_render_start() function only maps the drawing buffers, 578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * not the read buffer. 579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct gl_renderbuffer * 581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgmap_readbuffer(struct gl_context *ctx, GLenum type) 582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_framebuffer *fb = ctx->ReadBuffer; 584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_renderbuffer *rb; 585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct swrast_renderbuffer *srb; 586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (type) { 588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_COLOR: 589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rb = fb->Attachment[fb->_ColorReadBufferIndex].Renderbuffer; 590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_DEPTH: 592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_DEPTH_STENCIL: 593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer; 594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_STENCIL: 596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rb = fb->Attachment[BUFFER_STENCIL].Renderbuffer; 597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 599f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 600f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 601f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 602f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org srb = swrast_renderbuffer(rb); 603f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 604f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!srb || srb->Map) { 605f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* no buffer, or buffer is mapped already, we're done */ 606f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 607f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 608f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 609f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.MapRenderbuffer(ctx, rb, 610f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 0, 0, rb->Width, rb->Height, 611f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GL_MAP_READ_BIT, 612f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org &srb->Map, &srb->RowStride); 613f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 614f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return rb; 615f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 616f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 617f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 618f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 619f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Do software-based glCopyPixels. 620f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * By time we get here, all parameters will have been error-checked. 621f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 622f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 623f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_swrast_CopyPixels( struct gl_context *ctx, 624f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint srcx, GLint srcy, GLsizei width, GLsizei height, 625f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLint destx, GLint desty, GLenum type ) 626f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 627f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SWcontext *swrast = SWRAST_CONTEXT(ctx); 628f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct gl_renderbuffer *rb; 629f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 630f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!_mesa_check_conditional_render(ctx)) 631f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; /* don't copy */ 632f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 633f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (swrast->NewState) 634f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _swrast_validate_derived( ctx ); 635f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 636f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!(SWRAST_CONTEXT(ctx)->_RasterMask != 0x0 || 637f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Pixel.ZoomX != 1.0F || 638f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Pixel.ZoomY != 1.0F || 639f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->_ImageTransferState) && 640f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org swrast_fast_copy_pixels(ctx, srcx, srcy, width, height, destx, desty, 641f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org type)) { 642f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* all done */ 643f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 644f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 645f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 646f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org swrast_render_start(ctx); 647f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rb = map_readbuffer(ctx, type); 648f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 649f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (type) { 650f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_COLOR: 651f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org copy_rgba_pixels( ctx, srcx, srcy, width, height, destx, desty ); 652f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 653f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_DEPTH: 654f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org copy_depth_pixels( ctx, srcx, srcy, width, height, destx, desty ); 655f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 656f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_STENCIL: 657f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org copy_stencil_pixels( ctx, srcx, srcy, width, height, destx, desty ); 658f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 659f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case GL_DEPTH_STENCIL_EXT: 660f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Copy buffers separately (if the fast copy path wasn't taken) */ 661f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org copy_depth_pixels(ctx, srcx, srcy, width, height, destx, desty); 662f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org copy_stencil_pixels(ctx, srcx, srcy, width, height, destx, desty); 663f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 664f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 665f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_problem(ctx, "unexpected type in _swrast_CopyPixels"); 666f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 667f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 668f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org swrast_render_finish(ctx); 669f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 670f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (rb) { 671f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct swrast_renderbuffer *srb = swrast_renderbuffer(rb); 672f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Driver.UnmapRenderbuffer(ctx, rb); 673f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org srb->Map = NULL; 674f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 675f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 676