11eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul/* 21eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * Mesa 3-D graphics library 31eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * Version: 6.5 41eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * 51eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. 61eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * 71eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * Permission is hereby granted, free of charge, to any person obtaining a 81eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * copy of this software and associated documentation files (the "Software"), 91eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * to deal in the Software without restriction, including without limitation 101eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * the rights to use, copy, modify, merge, publish, distribute, sublicense, 111eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * and/or sell copies of the Software, and to permit persons to whom the 121eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * Software is furnished to do so, subject to the following conditions: 131eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * 141eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * The above copyright notice and this permission notice shall be included 151eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * in all copies or substantial portions of the Software. 161eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * 171eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 181eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 191eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 201eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 211eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 221eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 231eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul */ 241eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul 251eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul 26bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/glheader.h" 27ab26682eb4db0dbe160b13f1e320ec9164c3afc5Brian Paul#include "main/condrender.h" 28727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul#include "main/image.h" 29bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/macros.h" 303786a3e644d0770e1247f24c6379388513728174Eric Anholt#include "main/format_unpack.h" 313786a3e644d0770e1247f24c6379388513728174Eric Anholt#include "main/format_pack.h" 321eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul#include "s_context.h" 331eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul 341eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul 35c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul#define ABS(X) ((X) < 0 ? -(X) : (X)) 36c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 37c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 38c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul/** 39c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul * Generate a row resampler function for GL_NEAREST mode. 40c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul */ 41c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul#define RESAMPLE(NAME, PIXELTYPE, SIZE) \ 42c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paulstatic void \ 43c241d3b06a5c996cb8415a6ada23288621c1d254Brian PaulNAME(GLint srcWidth, GLint dstWidth, \ 44c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLvoid *srcBuffer, GLvoid *dstBuffer, \ 45c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLboolean flip) \ 46c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul{ \ 47c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const PIXELTYPE *src = (const PIXELTYPE *) srcBuffer;\ 48c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul PIXELTYPE *dst = (PIXELTYPE *) dstBuffer; \ 49c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint dstCol; \ 50c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul \ 51c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul if (flip) { \ 52c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul for (dstCol = 0; dstCol < dstWidth; dstCol++) { \ 53c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint srcCol = (dstCol * srcWidth) / dstWidth; \ 54c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul ASSERT(srcCol >= 0); \ 55c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul ASSERT(srcCol < srcWidth); \ 56c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcCol = srcWidth - 1 - srcCol; /* flip */ \ 57c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul if (SIZE == 1) { \ 58c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dst[dstCol] = src[srcCol]; \ 59c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } \ 60c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul else if (SIZE == 2) { \ 61c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dst[dstCol*2+0] = src[srcCol*2+0]; \ 62c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dst[dstCol*2+1] = src[srcCol*2+1]; \ 63c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } \ 64c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul else if (SIZE == 4) { \ 65c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dst[dstCol*4+0] = src[srcCol*4+0]; \ 66c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dst[dstCol*4+1] = src[srcCol*4+1]; \ 67c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dst[dstCol*4+2] = src[srcCol*4+2]; \ 68c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dst[dstCol*4+3] = src[srcCol*4+3]; \ 69c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } \ 70c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } \ 71c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } \ 72c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul else { \ 73c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul for (dstCol = 0; dstCol < dstWidth; dstCol++) { \ 74c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint srcCol = (dstCol * srcWidth) / dstWidth; \ 75c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul ASSERT(srcCol >= 0); \ 76c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul ASSERT(srcCol < srcWidth); \ 77c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul if (SIZE == 1) { \ 78c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dst[dstCol] = src[srcCol]; \ 79c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } \ 80c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul else if (SIZE == 2) { \ 81c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dst[dstCol*2+0] = src[srcCol*2+0]; \ 82c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dst[dstCol*2+1] = src[srcCol*2+1]; \ 83c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } \ 84c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul else if (SIZE == 4) { \ 85c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dst[dstCol*4+0] = src[srcCol*4+0]; \ 86c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dst[dstCol*4+1] = src[srcCol*4+1]; \ 87c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dst[dstCol*4+2] = src[srcCol*4+2]; \ 88c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dst[dstCol*4+3] = src[srcCol*4+3]; \ 89c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } \ 90c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } \ 91c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } \ 92c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul} 93c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 94c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul/** 95c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul * Resamplers for 1, 2, 4, 8 and 16-byte pixels. 96c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul */ 97c241d3b06a5c996cb8415a6ada23288621c1d254Brian PaulRESAMPLE(resample_row_1, GLubyte, 1) 98c241d3b06a5c996cb8415a6ada23288621c1d254Brian PaulRESAMPLE(resample_row_2, GLushort, 1) 99c241d3b06a5c996cb8415a6ada23288621c1d254Brian PaulRESAMPLE(resample_row_4, GLuint, 1) 100c241d3b06a5c996cb8415a6ada23288621c1d254Brian PaulRESAMPLE(resample_row_8, GLuint, 2) 101c241d3b06a5c996cb8415a6ada23288621c1d254Brian PaulRESAMPLE(resample_row_16, GLuint, 4) 102c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 103c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 104c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul/** 105c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul * Blit color, depth or stencil with GL_NEAREST filtering. 106c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul */ 107c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paulstatic void 108f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergblit_nearest(struct gl_context *ctx, 109c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 110c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 111b15334035177fbb031f000583ef7cb31f68b248cBrian Paul GLbitfield buffer) 112c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul{ 113c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul struct gl_renderbuffer *readRb, *drawRb; 114c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 115c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint srcWidth = ABS(srcX1 - srcX0); 116c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint dstWidth = ABS(dstX1 - dstX0); 117c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint srcHeight = ABS(srcY1 - srcY0); 118c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint dstHeight = ABS(dstY1 - dstY0); 119c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 120c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint srcXpos = MIN2(srcX0, srcX1); 121c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint srcYpos = MIN2(srcY0, srcY1); 122c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint dstXpos = MIN2(dstX0, dstX1); 123c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint dstYpos = MIN2(dstY0, dstY1); 124c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 125c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLboolean invertX = (srcX1 < srcX0) ^ (dstX1 < dstX0); 126c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLboolean invertY = (srcY1 < srcY0) ^ (dstY1 < dstY0); 1273786a3e644d0770e1247f24c6379388513728174Eric Anholt enum mode { 1283786a3e644d0770e1247f24c6379388513728174Eric Anholt DIRECT, 1293786a3e644d0770e1247f24c6379388513728174Eric Anholt UNPACK_RGBA_FLOAT, 1303786a3e644d0770e1247f24c6379388513728174Eric Anholt UNPACK_Z_FLOAT, 1313786a3e644d0770e1247f24c6379388513728174Eric Anholt UNPACK_Z_INT, 1323786a3e644d0770e1247f24c6379388513728174Eric Anholt UNPACK_S, 1333786a3e644d0770e1247f24c6379388513728174Eric Anholt } mode; 1343786a3e644d0770e1247f24c6379388513728174Eric Anholt GLubyte *srcMap, *dstMap; 1353786a3e644d0770e1247f24c6379388513728174Eric Anholt GLint srcRowStride, dstRowStride; 136c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint dstRow; 137c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 1383786a3e644d0770e1247f24c6379388513728174Eric Anholt GLint pixelSize; 139c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLvoid *srcBuffer, *dstBuffer; 140c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint prevY = -1; 141c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 142c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul typedef void (*resample_func)(GLint srcWidth, GLint dstWidth, 143c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLvoid *srcBuffer, GLvoid *dstBuffer, 144c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLboolean flip); 145c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul resample_func resampleRow; 146c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 147c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul switch (buffer) { 148c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul case GL_COLOR_BUFFER_BIT: 149c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul readRb = ctx->ReadBuffer->_ColorReadBuffer; 150ff73c783cc47361ff0dd819c82d067b4b85870ddBrian drawRb = ctx->DrawBuffer->_ColorDrawBuffers[0]; 1513786a3e644d0770e1247f24c6379388513728174Eric Anholt 1523786a3e644d0770e1247f24c6379388513728174Eric Anholt if (readRb->Format == drawRb->Format) { 1533786a3e644d0770e1247f24c6379388513728174Eric Anholt mode = DIRECT; 1543786a3e644d0770e1247f24c6379388513728174Eric Anholt pixelSize = _mesa_get_format_bytes(readRb->Format); 1553786a3e644d0770e1247f24c6379388513728174Eric Anholt } else { 1563786a3e644d0770e1247f24c6379388513728174Eric Anholt mode = UNPACK_RGBA_FLOAT; 1573786a3e644d0770e1247f24c6379388513728174Eric Anholt pixelSize = 16; 1583786a3e644d0770e1247f24c6379388513728174Eric Anholt } 1593786a3e644d0770e1247f24c6379388513728174Eric Anholt 160c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul break; 161c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul case GL_DEPTH_BUFFER_BIT: 1623786a3e644d0770e1247f24c6379388513728174Eric Anholt readRb = ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; 1633786a3e644d0770e1247f24c6379388513728174Eric Anholt drawRb = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; 1643786a3e644d0770e1247f24c6379388513728174Eric Anholt 1653786a3e644d0770e1247f24c6379388513728174Eric Anholt /* Note that for depth/stencil, the formats of src/dst must match. By 1663786a3e644d0770e1247f24c6379388513728174Eric Anholt * using the core helpers for pack/unpack, we avoid needing to handle 1673786a3e644d0770e1247f24c6379388513728174Eric Anholt * masking for things like DEPTH copies of Z24S8. 1683786a3e644d0770e1247f24c6379388513728174Eric Anholt */ 1693786a3e644d0770e1247f24c6379388513728174Eric Anholt if (readRb->Format == MESA_FORMAT_Z32_FLOAT || 1703786a3e644d0770e1247f24c6379388513728174Eric Anholt readRb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) { 1713786a3e644d0770e1247f24c6379388513728174Eric Anholt mode = UNPACK_Z_FLOAT; 1723786a3e644d0770e1247f24c6379388513728174Eric Anholt } else { 1733786a3e644d0770e1247f24c6379388513728174Eric Anholt mode = UNPACK_Z_INT; 1743786a3e644d0770e1247f24c6379388513728174Eric Anholt } 1753786a3e644d0770e1247f24c6379388513728174Eric Anholt pixelSize = 4; 176c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul break; 177c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul case GL_STENCIL_BUFFER_BIT: 1783786a3e644d0770e1247f24c6379388513728174Eric Anholt readRb = ctx->ReadBuffer->Attachment[BUFFER_STENCIL].Renderbuffer; 1793786a3e644d0770e1247f24c6379388513728174Eric Anholt drawRb = ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer; 1803786a3e644d0770e1247f24c6379388513728174Eric Anholt mode = UNPACK_S; 1813786a3e644d0770e1247f24c6379388513728174Eric Anholt pixelSize = 1; 182c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul break; 183c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul default: 184c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul _mesa_problem(ctx, "unexpected buffer in blit_nearest()"); 185c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul return; 186c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 187c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 188c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul /* choose row resampler */ 189c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul switch (pixelSize) { 190c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul case 1: 191c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul resampleRow = resample_row_1; 192c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul break; 193c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul case 2: 194c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul resampleRow = resample_row_2; 195c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul break; 196c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul case 4: 197c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul resampleRow = resample_row_4; 198c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul break; 199c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul case 8: 200c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul resampleRow = resample_row_8; 201c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul break; 202c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul case 16: 203c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul resampleRow = resample_row_16; 204c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul break; 205c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul default: 206c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul _mesa_problem(ctx, "unexpected pixel size (%d) in blit_nearest", 207c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul pixelSize); 208c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul return; 209c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 210c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 2113786a3e644d0770e1247f24c6379388513728174Eric Anholt if (readRb == drawRb) { 2123786a3e644d0770e1247f24c6379388513728174Eric Anholt /* map whole buffer for read/write */ 2133786a3e644d0770e1247f24c6379388513728174Eric Anholt /* XXX we could be clever and just map the union region of the 2143786a3e644d0770e1247f24c6379388513728174Eric Anholt * source and dest rects. 2153786a3e644d0770e1247f24c6379388513728174Eric Anholt */ 2163786a3e644d0770e1247f24c6379388513728174Eric Anholt GLubyte *map; 2173786a3e644d0770e1247f24c6379388513728174Eric Anholt GLint rowStride; 2183786a3e644d0770e1247f24c6379388513728174Eric Anholt GLint formatSize = _mesa_get_format_bytes(readRb->Format); 2193786a3e644d0770e1247f24c6379388513728174Eric Anholt 2203786a3e644d0770e1247f24c6379388513728174Eric Anholt ctx->Driver.MapRenderbuffer(ctx, readRb, 0, 0, 2213786a3e644d0770e1247f24c6379388513728174Eric Anholt readRb->Width, readRb->Height, 2223786a3e644d0770e1247f24c6379388513728174Eric Anholt GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, 2233786a3e644d0770e1247f24c6379388513728174Eric Anholt &map, &rowStride); 2243786a3e644d0770e1247f24c6379388513728174Eric Anholt if (!map) { 2253786a3e644d0770e1247f24c6379388513728174Eric Anholt _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer"); 2263786a3e644d0770e1247f24c6379388513728174Eric Anholt return; 2273786a3e644d0770e1247f24c6379388513728174Eric Anholt } 2283786a3e644d0770e1247f24c6379388513728174Eric Anholt 2293786a3e644d0770e1247f24c6379388513728174Eric Anholt srcMap = map + srcYpos * rowStride + srcXpos * formatSize; 2303786a3e644d0770e1247f24c6379388513728174Eric Anholt dstMap = map + dstYpos * rowStride + dstXpos * formatSize; 2313786a3e644d0770e1247f24c6379388513728174Eric Anholt 2323786a3e644d0770e1247f24c6379388513728174Eric Anholt /* this handles overlapping copies */ 2333786a3e644d0770e1247f24c6379388513728174Eric Anholt if (srcY0 < dstY0) { 2343786a3e644d0770e1247f24c6379388513728174Eric Anholt /* copy in reverse (top->down) order */ 2353786a3e644d0770e1247f24c6379388513728174Eric Anholt srcMap += rowStride * (readRb->Height - 1); 2363786a3e644d0770e1247f24c6379388513728174Eric Anholt dstMap += rowStride * (readRb->Height - 1); 2373786a3e644d0770e1247f24c6379388513728174Eric Anholt srcRowStride = -rowStride; 2383786a3e644d0770e1247f24c6379388513728174Eric Anholt dstRowStride = -rowStride; 2393786a3e644d0770e1247f24c6379388513728174Eric Anholt } 2403786a3e644d0770e1247f24c6379388513728174Eric Anholt else { 2413786a3e644d0770e1247f24c6379388513728174Eric Anholt /* copy in normal (bottom->up) order */ 2423786a3e644d0770e1247f24c6379388513728174Eric Anholt srcRowStride = rowStride; 2433786a3e644d0770e1247f24c6379388513728174Eric Anholt dstRowStride = rowStride; 2443786a3e644d0770e1247f24c6379388513728174Eric Anholt } 2453786a3e644d0770e1247f24c6379388513728174Eric Anholt } 2463786a3e644d0770e1247f24c6379388513728174Eric Anholt else { 2473786a3e644d0770e1247f24c6379388513728174Eric Anholt /* different src/dst buffers */ 2483786a3e644d0770e1247f24c6379388513728174Eric Anholt ctx->Driver.MapRenderbuffer(ctx, readRb, 2493786a3e644d0770e1247f24c6379388513728174Eric Anholt srcXpos, srcYpos, 2503786a3e644d0770e1247f24c6379388513728174Eric Anholt srcWidth, srcHeight, 2513786a3e644d0770e1247f24c6379388513728174Eric Anholt GL_MAP_READ_BIT, &srcMap, &srcRowStride); 2523786a3e644d0770e1247f24c6379388513728174Eric Anholt if (!srcMap) { 2533786a3e644d0770e1247f24c6379388513728174Eric Anholt _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer"); 2543786a3e644d0770e1247f24c6379388513728174Eric Anholt return; 2553786a3e644d0770e1247f24c6379388513728174Eric Anholt } 2563786a3e644d0770e1247f24c6379388513728174Eric Anholt ctx->Driver.MapRenderbuffer(ctx, drawRb, 2573786a3e644d0770e1247f24c6379388513728174Eric Anholt dstXpos, dstYpos, 2583786a3e644d0770e1247f24c6379388513728174Eric Anholt dstWidth, dstHeight, 2593786a3e644d0770e1247f24c6379388513728174Eric Anholt GL_MAP_WRITE_BIT, &dstMap, &dstRowStride); 2603786a3e644d0770e1247f24c6379388513728174Eric Anholt if (!dstMap) { 2613786a3e644d0770e1247f24c6379388513728174Eric Anholt ctx->Driver.UnmapRenderbuffer(ctx, readRb); 2623786a3e644d0770e1247f24c6379388513728174Eric Anholt _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer"); 2633786a3e644d0770e1247f24c6379388513728174Eric Anholt return; 2643786a3e644d0770e1247f24c6379388513728174Eric Anholt } 2653786a3e644d0770e1247f24c6379388513728174Eric Anholt } 2663786a3e644d0770e1247f24c6379388513728174Eric Anholt 267c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul /* allocate the src/dst row buffers */ 26832f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg srcBuffer = malloc(pixelSize * srcWidth); 269c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul if (!srcBuffer) { 270c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT"); 271c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul return; 272c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 27332f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg dstBuffer = malloc(pixelSize * dstWidth); 274c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul if (!dstBuffer) { 27532f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg free(srcBuffer); 276c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT"); 277c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul return; 278c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 279c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 280c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul for (dstRow = 0; dstRow < dstHeight; dstRow++) { 281c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint srcRow = (dstRow * srcHeight) / dstHeight; 2823786a3e644d0770e1247f24c6379388513728174Eric Anholt GLubyte *dstRowStart = dstMap + dstRowStride * dstRow; 283c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 284c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul ASSERT(srcRow >= 0); 285c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul ASSERT(srcRow < srcHeight); 286c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 287c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul if (invertY) { 288c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcRow = srcHeight - 1 - srcRow; 289c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 290c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 291c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul /* get pixel row from source and resample to match dest width */ 2923786a3e644d0770e1247f24c6379388513728174Eric Anholt if (prevY != srcRow) { 2933786a3e644d0770e1247f24c6379388513728174Eric Anholt GLubyte *srcRowStart = srcMap + srcRowStride * srcRow; 2943786a3e644d0770e1247f24c6379388513728174Eric Anholt 2953786a3e644d0770e1247f24c6379388513728174Eric Anholt switch (mode) { 2963786a3e644d0770e1247f24c6379388513728174Eric Anholt case DIRECT: 2973786a3e644d0770e1247f24c6379388513728174Eric Anholt memcpy(srcBuffer, srcRowStart, pixelSize * srcWidth); 2983786a3e644d0770e1247f24c6379388513728174Eric Anholt break; 2993786a3e644d0770e1247f24c6379388513728174Eric Anholt case UNPACK_RGBA_FLOAT: 3003786a3e644d0770e1247f24c6379388513728174Eric Anholt _mesa_unpack_rgba_row(readRb->Format, srcWidth, srcRowStart, 3013786a3e644d0770e1247f24c6379388513728174Eric Anholt srcBuffer); 3023786a3e644d0770e1247f24c6379388513728174Eric Anholt break; 3033786a3e644d0770e1247f24c6379388513728174Eric Anholt case UNPACK_Z_FLOAT: 3043786a3e644d0770e1247f24c6379388513728174Eric Anholt _mesa_unpack_float_z_row(readRb->Format, srcWidth, srcRowStart, 3053786a3e644d0770e1247f24c6379388513728174Eric Anholt srcBuffer); 3063786a3e644d0770e1247f24c6379388513728174Eric Anholt break; 3073786a3e644d0770e1247f24c6379388513728174Eric Anholt case UNPACK_Z_INT: 3083786a3e644d0770e1247f24c6379388513728174Eric Anholt _mesa_unpack_uint_z_row(readRb->Format, srcWidth, srcRowStart, 3093786a3e644d0770e1247f24c6379388513728174Eric Anholt srcBuffer); 3103786a3e644d0770e1247f24c6379388513728174Eric Anholt break; 3113786a3e644d0770e1247f24c6379388513728174Eric Anholt case UNPACK_S: 3123786a3e644d0770e1247f24c6379388513728174Eric Anholt _mesa_unpack_ubyte_stencil_row(readRb->Format, srcWidth, 3133786a3e644d0770e1247f24c6379388513728174Eric Anholt srcRowStart, srcBuffer); 3143786a3e644d0770e1247f24c6379388513728174Eric Anholt break; 3153786a3e644d0770e1247f24c6379388513728174Eric Anholt } 3163786a3e644d0770e1247f24c6379388513728174Eric Anholt 317c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul (*resampleRow)(srcWidth, dstWidth, srcBuffer, dstBuffer, invertX); 3183786a3e644d0770e1247f24c6379388513728174Eric Anholt prevY = srcRow; 319c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 320c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 321c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul /* store pixel row in destination */ 3223786a3e644d0770e1247f24c6379388513728174Eric Anholt switch (mode) { 3233786a3e644d0770e1247f24c6379388513728174Eric Anholt case DIRECT: 3243786a3e644d0770e1247f24c6379388513728174Eric Anholt memcpy(dstRowStart, dstBuffer, pixelSize * srcWidth); 3253786a3e644d0770e1247f24c6379388513728174Eric Anholt break; 3263786a3e644d0770e1247f24c6379388513728174Eric Anholt case UNPACK_RGBA_FLOAT: 3273786a3e644d0770e1247f24c6379388513728174Eric Anholt _mesa_pack_float_rgba_row(drawRb->Format, dstWidth, dstBuffer, 3283786a3e644d0770e1247f24c6379388513728174Eric Anholt dstRowStart); 3293786a3e644d0770e1247f24c6379388513728174Eric Anholt break; 3303786a3e644d0770e1247f24c6379388513728174Eric Anholt case UNPACK_Z_FLOAT: 3313786a3e644d0770e1247f24c6379388513728174Eric Anholt _mesa_pack_float_z_row(drawRb->Format, dstWidth, dstBuffer, 3323786a3e644d0770e1247f24c6379388513728174Eric Anholt dstRowStart); 3333786a3e644d0770e1247f24c6379388513728174Eric Anholt break; 3343786a3e644d0770e1247f24c6379388513728174Eric Anholt case UNPACK_Z_INT: 3353786a3e644d0770e1247f24c6379388513728174Eric Anholt _mesa_pack_uint_z_row(drawRb->Format, dstWidth, dstBuffer, 3363786a3e644d0770e1247f24c6379388513728174Eric Anholt dstRowStart); 3373786a3e644d0770e1247f24c6379388513728174Eric Anholt break; 3383786a3e644d0770e1247f24c6379388513728174Eric Anholt case UNPACK_S: 3393786a3e644d0770e1247f24c6379388513728174Eric Anholt _mesa_pack_ubyte_stencil_row(drawRb->Format, dstWidth, dstBuffer, 3403786a3e644d0770e1247f24c6379388513728174Eric Anholt dstRowStart); 3413786a3e644d0770e1247f24c6379388513728174Eric Anholt break; 3423786a3e644d0770e1247f24c6379388513728174Eric Anholt } 343c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 344c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 34532f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg free(srcBuffer); 34632f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg free(dstBuffer); 3473786a3e644d0770e1247f24c6379388513728174Eric Anholt 3483786a3e644d0770e1247f24c6379388513728174Eric Anholt ctx->Driver.UnmapRenderbuffer(ctx, readRb); 3493786a3e644d0770e1247f24c6379388513728174Eric Anholt if (drawRb != readRb) { 3503786a3e644d0770e1247f24c6379388513728174Eric Anholt ctx->Driver.UnmapRenderbuffer(ctx, drawRb); 3513786a3e644d0770e1247f24c6379388513728174Eric Anholt } 352c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul} 353c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 354c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 355c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 356c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul#define LERP(T, A, B) ( (A) + (T) * ((B) - (A)) ) 357c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 3589520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLfloat 359c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paullerp_2d(GLfloat a, GLfloat b, 360c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLfloat v00, GLfloat v10, GLfloat v01, GLfloat v11) 361c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul{ 362c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLfloat temp0 = LERP(a, v00, v10); 363c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLfloat temp1 = LERP(a, v01, v11); 364c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul return LERP(b, temp0, temp1); 365c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul} 366c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 367c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 368c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul/** 369c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul * Bilinear interpolation of two source rows. 370c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul * GLubyte pixels. 371c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul */ 372c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paulstatic void 373c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paulresample_linear_row_ub(GLint srcWidth, GLint dstWidth, 374c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLvoid *srcBuffer0, const GLvoid *srcBuffer1, 375c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLvoid *dstBuffer, GLboolean flip, GLfloat rowWeight) 376c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul{ 377c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLubyte (*srcColor0)[4] = (const GLubyte (*)[4]) srcBuffer0; 378c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLubyte (*srcColor1)[4] = (const GLubyte (*)[4]) srcBuffer1; 379c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLubyte (*dstColor)[4] = (GLubyte (*)[4]) dstBuffer; 380c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLfloat dstWidthF = (GLfloat) dstWidth; 381c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint dstCol; 382c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 383c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul for (dstCol = 0; dstCol < dstWidth; dstCol++) { 384c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLfloat srcCol = (dstCol * srcWidth) / dstWidthF; 385c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint srcCol0 = IFLOOR(srcCol); 386c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint srcCol1 = srcCol0 + 1; 387c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLfloat colWeight = srcCol - srcCol0; /* fractional part of srcCol */ 388c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLfloat red, green, blue, alpha; 389c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 390c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul ASSERT(srcCol0 >= 0); 391c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul ASSERT(srcCol0 < srcWidth); 392c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul ASSERT(srcCol1 <= srcWidth); 393c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 394c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul if (srcCol1 == srcWidth) { 395c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul /* last column fudge */ 396c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcCol1--; 397c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul colWeight = 0.0; 398c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 399c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 400c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul if (flip) { 401c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcCol0 = srcWidth - 1 - srcCol0; 402c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcCol1 = srcWidth - 1 - srcCol1; 403c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 404c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 405c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul red = lerp_2d(colWeight, rowWeight, 406c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcColor0[srcCol0][RCOMP], srcColor0[srcCol1][RCOMP], 407c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcColor1[srcCol0][RCOMP], srcColor1[srcCol1][RCOMP]); 408c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul green = lerp_2d(colWeight, rowWeight, 409c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcColor0[srcCol0][GCOMP], srcColor0[srcCol1][GCOMP], 410c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcColor1[srcCol0][GCOMP], srcColor1[srcCol1][GCOMP]); 411c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul blue = lerp_2d(colWeight, rowWeight, 412c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcColor0[srcCol0][BCOMP], srcColor0[srcCol1][BCOMP], 413c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcColor1[srcCol0][BCOMP], srcColor1[srcCol1][BCOMP]); 414c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul alpha = lerp_2d(colWeight, rowWeight, 415c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcColor0[srcCol0][ACOMP], srcColor0[srcCol1][ACOMP], 416c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcColor1[srcCol0][ACOMP], srcColor1[srcCol1][ACOMP]); 417c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 418c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dstColor[dstCol][RCOMP] = IFLOOR(red); 419c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dstColor[dstCol][GCOMP] = IFLOOR(green); 420c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dstColor[dstCol][BCOMP] = IFLOOR(blue); 421c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dstColor[dstCol][ACOMP] = IFLOOR(alpha); 422c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 423c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul} 424c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 425c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 426edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul/** 427edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul * Bilinear interpolation of two source rows. floating point pixels. 428edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul */ 429edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paulstatic void 430edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paulresample_linear_row_float(GLint srcWidth, GLint dstWidth, 431edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul const GLvoid *srcBuffer0, const GLvoid *srcBuffer1, 432edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLvoid *dstBuffer, GLboolean flip, GLfloat rowWeight) 433edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul{ 434edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul const GLfloat (*srcColor0)[4] = (const GLfloat (*)[4]) srcBuffer0; 435edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul const GLfloat (*srcColor1)[4] = (const GLfloat (*)[4]) srcBuffer1; 436edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLfloat (*dstColor)[4] = (GLfloat (*)[4]) dstBuffer; 437edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul const GLfloat dstWidthF = (GLfloat) dstWidth; 438edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLint dstCol; 439edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 440edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul for (dstCol = 0; dstCol < dstWidth; dstCol++) { 441edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul const GLfloat srcCol = (dstCol * srcWidth) / dstWidthF; 442edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLint srcCol0 = IFLOOR(srcCol); 443edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLint srcCol1 = srcCol0 + 1; 444edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLfloat colWeight = srcCol - srcCol0; /* fractional part of srcCol */ 445edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLfloat red, green, blue, alpha; 446edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 447edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul ASSERT(srcCol0 >= 0); 448edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul ASSERT(srcCol0 < srcWidth); 449edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul ASSERT(srcCol1 <= srcWidth); 450edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 451edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul if (srcCol1 == srcWidth) { 452edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul /* last column fudge */ 453edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul srcCol1--; 454edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul colWeight = 0.0; 455edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 456edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 457edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul if (flip) { 458edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul srcCol0 = srcWidth - 1 - srcCol0; 459edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul srcCol1 = srcWidth - 1 - srcCol1; 460edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 461edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 462edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul red = lerp_2d(colWeight, rowWeight, 463edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul srcColor0[srcCol0][RCOMP], srcColor0[srcCol1][RCOMP], 464edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul srcColor1[srcCol0][RCOMP], srcColor1[srcCol1][RCOMP]); 465edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul green = lerp_2d(colWeight, rowWeight, 466edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul srcColor0[srcCol0][GCOMP], srcColor0[srcCol1][GCOMP], 467edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul srcColor1[srcCol0][GCOMP], srcColor1[srcCol1][GCOMP]); 468edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul blue = lerp_2d(colWeight, rowWeight, 469edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul srcColor0[srcCol0][BCOMP], srcColor0[srcCol1][BCOMP], 470edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul srcColor1[srcCol0][BCOMP], srcColor1[srcCol1][BCOMP]); 471edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul alpha = lerp_2d(colWeight, rowWeight, 472edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul srcColor0[srcCol0][ACOMP], srcColor0[srcCol1][ACOMP], 473edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul srcColor1[srcCol0][ACOMP], srcColor1[srcCol1][ACOMP]); 474edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 475edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul dstColor[dstCol][RCOMP] = red; 476edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul dstColor[dstCol][GCOMP] = green; 477edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul dstColor[dstCol][BCOMP] = blue; 478edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul dstColor[dstCol][ACOMP] = alpha; 479edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 480edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul} 481edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 482edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 483c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 484c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul/** 485edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul * Bilinear filtered blit (color only, non-integer values). 486c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul */ 487c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paulstatic void 488f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergblit_linear(struct gl_context *ctx, 489c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 490c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1) 491c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul{ 492c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul struct gl_renderbuffer *readRb = ctx->ReadBuffer->_ColorReadBuffer; 493ff73c783cc47361ff0dd819c82d067b4b85870ddBrian struct gl_renderbuffer *drawRb = ctx->DrawBuffer->_ColorDrawBuffers[0]; 494c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 495c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint srcWidth = ABS(srcX1 - srcX0); 496c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint dstWidth = ABS(dstX1 - dstX0); 497c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint srcHeight = ABS(srcY1 - srcY0); 498c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint dstHeight = ABS(dstY1 - dstY0); 499c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLfloat dstHeightF = (GLfloat) dstHeight; 500c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 501c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint srcXpos = MIN2(srcX0, srcX1); 502c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint srcYpos = MIN2(srcY0, srcY1); 503c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint dstXpos = MIN2(dstX0, dstX1); 504c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint dstYpos = MIN2(dstY0, dstY1); 505c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 506c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLboolean invertX = (srcX1 < srcX0) ^ (dstX1 < dstX0); 507c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLboolean invertY = (srcY1 < srcY0) ^ (dstY1 < dstY0); 508c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 509c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint dstRow; 510c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 511c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint pixelSize; 512c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLvoid *srcBuffer0, *srcBuffer1; 513c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint srcBufferY0 = -1, srcBufferY1 = -1; 514c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLvoid *dstBuffer; 515c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 516edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul gl_format readFormat = _mesa_get_srgb_format_linear(readRb->Format); 517edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul gl_format drawFormat = _mesa_get_srgb_format_linear(drawRb->Format); 518edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLuint bpp = _mesa_get_format_bytes(readFormat); 519edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 520edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLenum pixelType; 521edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 522edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLubyte *srcMap, *dstMap; 523edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLint srcRowStride, dstRowStride; 524edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 525edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 526edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul /* Determine datatype for resampling */ 527edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul if (_mesa_get_format_max_bits(readFormat) == 8 && 528edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul _mesa_get_format_datatype(readFormat) == GL_UNSIGNED_NORMALIZED) { 529edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul pixelType = GL_UNSIGNED_BYTE; 530c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul pixelSize = 4 * sizeof(GLubyte); 531edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 532edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul else { 533edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul pixelType = GL_FLOAT; 534c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul pixelSize = 4 * sizeof(GLfloat); 535c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 536c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 537c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul /* Allocate the src/dst row buffers. 538c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul * Keep two adjacent src rows around for bilinear sampling. 539c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul */ 54032f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg srcBuffer0 = malloc(pixelSize * srcWidth); 541c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul if (!srcBuffer0) { 542c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT"); 543c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul return; 544c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 54532f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg srcBuffer1 = malloc(pixelSize * srcWidth); 546c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul if (!srcBuffer1) { 54732f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg free(srcBuffer0); 548c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT"); 549c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul return; 550c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 55132f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg dstBuffer = malloc(pixelSize * dstWidth); 552c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul if (!dstBuffer) { 55332f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg free(srcBuffer0); 55432f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg free(srcBuffer1); 555c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBufferEXT"); 556c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul return; 557c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 558c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 559edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul /* 560edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul * Map src / dst renderbuffers 561edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul */ 562edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul if (readRb == drawRb) { 563edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul /* map whole buffer for read/write */ 564edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul ctx->Driver.MapRenderbuffer(ctx, readRb, 565edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 0, 0, readRb->Width, readRb->Height, 566edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, 567edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul &srcMap, &srcRowStride); 568edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul if (!srcMap) { 569431b458f24f05db612e276e12528ce0e62707b65Vinson Lee free(srcBuffer0); 570431b458f24f05db612e276e12528ce0e62707b65Vinson Lee free(srcBuffer1); 571431b458f24f05db612e276e12528ce0e62707b65Vinson Lee free(dstBuffer); 572edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer"); 573edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul return; 574edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 575edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 576edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul dstMap = srcMap; 577edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul dstRowStride = srcRowStride; 578edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 579edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul else { 580edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul /* different src/dst buffers */ 581edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul /* XXX with a bit of work we could just map the regions to be 582edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul * read/written instead of the whole buffers. 583edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul */ 584edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul ctx->Driver.MapRenderbuffer(ctx, readRb, 585edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 0, 0, readRb->Width, readRb->Height, 586edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GL_MAP_READ_BIT, &srcMap, &srcRowStride); 587edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul if (!srcMap) { 588431b458f24f05db612e276e12528ce0e62707b65Vinson Lee free(srcBuffer0); 589431b458f24f05db612e276e12528ce0e62707b65Vinson Lee free(srcBuffer1); 590431b458f24f05db612e276e12528ce0e62707b65Vinson Lee free(dstBuffer); 591edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer"); 592edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul return; 593edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 594edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul ctx->Driver.MapRenderbuffer(ctx, drawRb, 595edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 0, 0, drawRb->Width, drawRb->Height, 596edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GL_MAP_WRITE_BIT, &dstMap, &dstRowStride); 597edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul if (!dstMap) { 598edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul ctx->Driver.UnmapRenderbuffer(ctx, readRb); 599431b458f24f05db612e276e12528ce0e62707b65Vinson Lee free(srcBuffer0); 600431b458f24f05db612e276e12528ce0e62707b65Vinson Lee free(srcBuffer1); 601431b458f24f05db612e276e12528ce0e62707b65Vinson Lee free(dstBuffer); 602edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer"); 603edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul return; 604edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 605edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 606edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 607c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul for (dstRow = 0; dstRow < dstHeight; dstRow++) { 608c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint dstY = dstYpos + dstRow; 609c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLfloat srcRow = (dstRow * srcHeight) / dstHeightF; 610c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint srcRow0 = IFLOOR(srcRow); 611c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint srcRow1 = srcRow0 + 1; 612c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLfloat rowWeight = srcRow - srcRow0; /* fractional part of srcRow */ 613c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 614c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul ASSERT(srcRow >= 0); 615c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul ASSERT(srcRow < srcHeight); 616c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 617c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul if (srcRow1 == srcHeight) { 618c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul /* last row fudge */ 619c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcRow1 = srcRow0; 620c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul rowWeight = 0.0; 621c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 622c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 623c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul if (invertY) { 624c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcRow0 = srcHeight - 1 - srcRow0; 625c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcRow1 = srcHeight - 1 - srcRow1; 626c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 627c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 628c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcY0 = srcYpos + srcRow0; 629c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcY1 = srcYpos + srcRow1; 630c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 631c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul /* get the two source rows */ 632c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul if (srcY0 == srcBufferY0 && srcY1 == srcBufferY1) { 633c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul /* use same source row buffers again */ 634c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 635c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul else if (srcY0 == srcBufferY1) { 636c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul /* move buffer1 into buffer0 by swapping pointers */ 637c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLvoid *tmp = srcBuffer0; 638c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcBuffer0 = srcBuffer1; 639c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcBuffer1 = tmp; 640c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul /* get y1 row */ 641edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul { 642edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLubyte *src = srcMap + srcY1 * srcRowStride + srcXpos * bpp; 643edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul if (pixelType == GL_UNSIGNED_BYTE) { 644edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul _mesa_unpack_ubyte_rgba_row(readFormat, srcWidth, 645edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul src, srcBuffer1); 646edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 647edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul else { 648edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul _mesa_unpack_rgba_row(readFormat, srcWidth, 649edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul src, srcBuffer1); 650edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 651edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 652c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcBufferY0 = srcY0; 653c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcBufferY1 = srcY1; 654c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 655c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul else { 656c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul /* get both new rows */ 657edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul { 658edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLubyte *src0 = srcMap + srcY0 * srcRowStride + srcXpos * bpp; 659edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLubyte *src1 = srcMap + srcY1 * srcRowStride + srcXpos * bpp; 660edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul if (pixelType == GL_UNSIGNED_BYTE) { 661edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul _mesa_unpack_ubyte_rgba_row(readFormat, srcWidth, 662edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul src0, srcBuffer0); 663edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul _mesa_unpack_ubyte_rgba_row(readFormat, srcWidth, 664edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul src1, srcBuffer1); 665edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 666edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul else { 667edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul _mesa_unpack_rgba_row(readFormat, srcWidth, src0, srcBuffer0); 668edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul _mesa_unpack_rgba_row(readFormat, srcWidth, src1, srcBuffer1); 669edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 670edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 671c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcBufferY0 = srcY0; 672c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcBufferY1 = srcY1; 673c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 674c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 675edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul if (pixelType == GL_UNSIGNED_BYTE) { 676c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul resample_linear_row_ub(srcWidth, dstWidth, srcBuffer0, srcBuffer1, 677c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dstBuffer, invertX, rowWeight); 678c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 679c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul else { 680edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul resample_linear_row_float(srcWidth, dstWidth, srcBuffer0, srcBuffer1, 681edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul dstBuffer, invertX, rowWeight); 682c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 683c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 684c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul /* store pixel row in destination */ 685edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul { 686edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLubyte *dst = dstMap + dstY * dstRowStride + dstXpos * bpp; 687edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul if (pixelType == GL_UNSIGNED_BYTE) { 688edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul _mesa_pack_ubyte_rgba_row(drawFormat, dstWidth, dstBuffer, dst); 689edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 690edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul else { 691edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul _mesa_pack_float_rgba_row(drawFormat, dstWidth, dstBuffer, dst); 692edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 693edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 694c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 695c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 69632f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg free(srcBuffer0); 69732f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg free(srcBuffer1); 69832f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg free(dstBuffer); 699edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 700edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul ctx->Driver.UnmapRenderbuffer(ctx, readRb); 701edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul if (drawRb != readRb) { 702edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul ctx->Driver.UnmapRenderbuffer(ctx, drawRb); 703edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 704c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul} 705c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 706edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 707edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 708c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul/** 7091eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * Software fallback for glBlitFramebufferEXT(). 7101eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul */ 7111eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paulvoid 712f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_swrast_BlitFramebuffer(struct gl_context *ctx, 713c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 714c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 715c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLbitfield mask, GLenum filter) 7161eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul{ 717b15334035177fbb031f000583ef7cb31f68b248cBrian Paul static const GLbitfield buffers[3] = { 718c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GL_COLOR_BUFFER_BIT, 719c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GL_DEPTH_BUFFER_BIT, 720c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GL_STENCIL_BUFFER_BIT 721c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul }; 722fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt static const GLenum buffer_enums[3] = { 723fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt GL_COLOR, 724fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt GL_DEPTH, 725fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt GL_STENCIL, 726fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt }; 727c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint i; 728c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 729727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul if (!_mesa_clip_blit(ctx, &srcX0, &srcY0, &srcX1, &srcY1, 730727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul &dstX0, &dstY0, &dstX1, &dstY1)) { 731c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul return; 732c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 733c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 73422e806f57013b2c116b5bfab228e0f28e25198f4Brian Paul if (SWRAST_CONTEXT(ctx)->NewState) 73522e806f57013b2c116b5bfab228e0f28e25198f4Brian Paul _swrast_validate_derived(ctx); 73622e806f57013b2c116b5bfab228e0f28e25198f4Brian Paul 737fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt /* First, try covering whatever buffers possible using the fast 1:1 copy 738fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt * path. 739fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt */ 740c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul if (srcX1 - srcX0 == dstX1 - dstX0 && 741c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcY1 - srcY0 == dstY1 - dstY0 && 742c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcX0 < srcX1 && 743c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcY0 < srcY1 && 744c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dstX0 < dstX1 && 745c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dstY0 < dstY1) { 746c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul for (i = 0; i < 3; i++) { 747c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul if (mask & buffers[i]) { 748fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt if (swrast_fast_copy_pixels(ctx, 749fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt srcX0, srcY0, 750fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt srcX1 - srcX0, srcY1 - srcY0, 751fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt dstX0, dstY0, 752fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt buffer_enums[i])) { 753fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt mask &= ~buffers[i]; 754fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt } 755fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt } 756c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 757fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt 758fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt if (!mask) 759fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt return; 760c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 761fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt 762fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt if (filter == GL_NEAREST) { 763fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt for (i = 0; i < 3; i++) { 764fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt if (mask & buffers[i]) { 765fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt blit_nearest(ctx, srcX0, srcY0, srcX1, srcY1, 766fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt dstX0, dstY0, dstX1, dstY1, buffers[i]); 767fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt } 768c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 769fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt } 770fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt else { 771fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt ASSERT(filter == GL_LINEAR); 772fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt if (mask & GL_COLOR_BUFFER_BIT) { /* depth/stencil not allowed */ 773fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt blit_linear(ctx, srcX0, srcY0, srcX1, srcY1, 774fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt dstX0, dstY0, dstX1, dstY1); 775c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 776c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 777c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 7781eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul} 779