s_blit.c revision 025f03f3b70989d27a20fea42763e3ccac946aa4
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{ 11335aefe922660ed6e8fbad082757ae759acd711ddBrian Paul struct gl_renderbuffer *readRb, *drawRb = NULL; 11435aefe922660ed6e8fbad082757ae759acd711ddBrian Paul struct gl_renderbuffer_attachment *readAtt = NULL, *drawAtt = NULL; 115bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat struct gl_framebuffer *readFb = ctx->ReadBuffer; 116bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat struct gl_framebuffer *drawFb = ctx->DrawBuffer; 11757ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul GLuint numDrawBuffers = 0; 118bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GLuint i; 119c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 120c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint srcWidth = ABS(srcX1 - srcX0); 121c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint dstWidth = ABS(dstX1 - dstX0); 122c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint srcHeight = ABS(srcY1 - srcY0); 123c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint dstHeight = ABS(dstY1 - dstY0); 124c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 125c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint srcXpos = MIN2(srcX0, srcX1); 126c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint srcYpos = MIN2(srcY0, srcY1); 127c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint dstXpos = MIN2(dstX0, dstX1); 128c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint dstYpos = MIN2(dstY0, dstY1); 129c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 130c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLboolean invertX = (srcX1 < srcX0) ^ (dstX1 < dstX0); 131c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLboolean invertY = (srcY1 < srcY0) ^ (dstY1 < dstY0); 1323786a3e644d0770e1247f24c6379388513728174Eric Anholt enum mode { 1333786a3e644d0770e1247f24c6379388513728174Eric Anholt DIRECT, 1343786a3e644d0770e1247f24c6379388513728174Eric Anholt UNPACK_RGBA_FLOAT, 1353786a3e644d0770e1247f24c6379388513728174Eric Anholt UNPACK_Z_FLOAT, 1363786a3e644d0770e1247f24c6379388513728174Eric Anholt UNPACK_Z_INT, 1373786a3e644d0770e1247f24c6379388513728174Eric Anholt UNPACK_S, 13835aefe922660ed6e8fbad082757ae759acd711ddBrian Paul } mode = DIRECT; 1393786a3e644d0770e1247f24c6379388513728174Eric Anholt GLubyte *srcMap, *dstMap; 1403786a3e644d0770e1247f24c6379388513728174Eric Anholt GLint srcRowStride, dstRowStride; 141c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint dstRow; 142c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 14335aefe922660ed6e8fbad082757ae759acd711ddBrian Paul GLint pixelSize = 0; 144c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLvoid *srcBuffer, *dstBuffer; 145c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint prevY = -1; 146c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 147c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul typedef void (*resample_func)(GLint srcWidth, GLint dstWidth, 148c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLvoid *srcBuffer, GLvoid *dstBuffer, 149c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLboolean flip); 150c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul resample_func resampleRow; 151c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 152c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul switch (buffer) { 153c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul case GL_COLOR_BUFFER_BIT: 154bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat readAtt = &readFb->Attachment[readFb->_ColorReadBufferIndex]; 155bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat readRb = readFb->_ColorReadBuffer; 15657ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul numDrawBuffers = drawFb->_NumColorDrawBuffers; 157c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul break; 158c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul case GL_DEPTH_BUFFER_BIT: 159bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat readAtt = &readFb->Attachment[BUFFER_DEPTH]; 160bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat drawAtt = &drawFb->Attachment[BUFFER_DEPTH]; 161bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat readRb = readAtt->Renderbuffer; 162bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat drawRb = drawAtt->Renderbuffer; 16357ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul numDrawBuffers = 1; 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: 178bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat readAtt = &readFb->Attachment[BUFFER_STENCIL]; 179bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat drawAtt = &drawFb->Attachment[BUFFER_STENCIL]; 180bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat readRb = readAtt->Renderbuffer; 181bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat drawRb = drawAtt->Renderbuffer; 18257ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul numDrawBuffers = 1; 1833786a3e644d0770e1247f24c6379388513728174Eric Anholt mode = UNPACK_S; 1843786a3e644d0770e1247f24c6379388513728174Eric Anholt pixelSize = 1; 185c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul break; 186c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul default: 187c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul _mesa_problem(ctx, "unexpected buffer in blit_nearest()"); 188c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul return; 189c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 190c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 191025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick /* allocate the src/dst row buffers */ 192025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick srcBuffer = malloc(MAX_PIXEL_BYTES * srcWidth); 193025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick dstBuffer = malloc(MAX_PIXEL_BYTES * dstWidth); 194025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick if (!srcBuffer || !dstBuffer) 195025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick goto fail_no_memory; 196025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick 197bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* Blit to all the draw buffers */ 19857ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul for (i = 0; i < numDrawBuffers; i++) { 199bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (buffer == GL_COLOR_BUFFER_BIT) { 200bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat int idx = drawFb->_ColorDrawBufferIndexes[i]; 201bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (idx == -1) 202bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat continue; 203bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat drawAtt = &drawFb->Attachment[idx]; 204bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat drawRb = drawAtt->Renderbuffer; 205bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat 20657ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul if (!drawRb) 20757ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul continue; 20857ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul 209bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (readRb->Format == drawRb->Format) { 210bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat mode = DIRECT; 211bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat pixelSize = _mesa_get_format_bytes(readRb->Format); 212bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } else { 213bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat mode = UNPACK_RGBA_FLOAT; 214bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat pixelSize = 16; 215bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 2163786a3e644d0770e1247f24c6379388513728174Eric Anholt } 2173786a3e644d0770e1247f24c6379388513728174Eric Anholt 218728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul /* choose row resampler */ 219728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul switch (pixelSize) { 220728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul case 1: 221728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul resampleRow = resample_row_1; 222728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul break; 223728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul case 2: 224728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul resampleRow = resample_row_2; 225728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul break; 226728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul case 4: 227728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul resampleRow = resample_row_4; 228728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul break; 229728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul case 8: 230728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul resampleRow = resample_row_8; 231728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul break; 232728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul case 16: 233728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul resampleRow = resample_row_16; 234728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul break; 235728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul default: 236728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul _mesa_problem(ctx, "unexpected pixel size (%d) in blit_nearest", 237728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul pixelSize); 238025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick goto fail; 239728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul } 240728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul 241bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if ((readRb == drawRb) || 242bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat (readAtt->Texture && drawAtt->Texture && 243bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat (readAtt->Texture == drawAtt->Texture))) { 244bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* map whole buffer for read/write */ 245bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* XXX we could be clever and just map the union region of the 246bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat * source and dest rects. 247bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat */ 248bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GLubyte *map; 249bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GLint rowStride; 250bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GLint formatSize = _mesa_get_format_bytes(readRb->Format); 251bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat 252bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat ctx->Driver.MapRenderbuffer(ctx, readRb, 0, 0, 253bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat readRb->Width, readRb->Height, 254bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, 255bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat &map, &rowStride); 256bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (!map) { 257025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick goto fail_no_memory; 258bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 259bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat 260bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcMap = map + srcYpos * rowStride + srcXpos * formatSize; 261bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat dstMap = map + dstYpos * rowStride + dstXpos * formatSize; 2623786a3e644d0770e1247f24c6379388513728174Eric Anholt 263bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* this handles overlapping copies */ 264bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (srcY0 < dstY0) { 265bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* copy in reverse (top->down) order */ 266bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcMap += rowStride * (readRb->Height - 1); 267bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat dstMap += rowStride * (readRb->Height - 1); 268bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcRowStride = -rowStride; 269bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat dstRowStride = -rowStride; 270bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 271bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat else { 272bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* copy in normal (bottom->up) order */ 273bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcRowStride = rowStride; 274bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat dstRowStride = rowStride; 275bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 2763786a3e644d0770e1247f24c6379388513728174Eric Anholt } 2773786a3e644d0770e1247f24c6379388513728174Eric Anholt else { 278bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* different src/dst buffers */ 279bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat ctx->Driver.MapRenderbuffer(ctx, readRb, 280bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcXpos, srcYpos, 281bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcWidth, srcHeight, 282bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GL_MAP_READ_BIT, &srcMap, &srcRowStride); 283bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (!srcMap) { 284025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick goto fail_no_memory; 285bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 286bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat ctx->Driver.MapRenderbuffer(ctx, drawRb, 287bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat dstXpos, dstYpos, 288bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat dstWidth, dstHeight, 289bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GL_MAP_WRITE_BIT, &dstMap, &dstRowStride); 290bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (!dstMap) { 291bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat ctx->Driver.UnmapRenderbuffer(ctx, readRb); 292025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick goto fail_no_memory; 293bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 2943786a3e644d0770e1247f24c6379388513728174Eric Anholt } 295bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat 296bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat for (dstRow = 0; dstRow < dstHeight; dstRow++) { 297547a418888c455a3f5158c147a155292f398ea34Brian Paul GLfloat srcRowF = (dstRow + 0.5F) / dstHeight * srcHeight - 0.5F; 298547a418888c455a3f5158c147a155292f398ea34Brian Paul GLint srcRow = IROUND(srcRowF); 299bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GLubyte *dstRowStart = dstMap + dstRowStride * dstRow; 300c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 301bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat ASSERT(srcRow >= 0); 302bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat ASSERT(srcRow < srcHeight); 303c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 304bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (invertY) { 305bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcRow = srcHeight - 1 - srcRow; 306bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 307c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 308bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* get pixel row from source and resample to match dest width */ 309bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (prevY != srcRow) { 310bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GLubyte *srcRowStart = srcMap + srcRowStride * srcRow; 311bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat 312bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat switch (mode) { 313bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat case DIRECT: 314bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat memcpy(srcBuffer, srcRowStart, pixelSize * srcWidth); 315bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat break; 316bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat case UNPACK_RGBA_FLOAT: 317bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat _mesa_unpack_rgba_row(readRb->Format, srcWidth, srcRowStart, 318bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcBuffer); 319bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat break; 320bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat case UNPACK_Z_FLOAT: 321bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat _mesa_unpack_float_z_row(readRb->Format, srcWidth, srcRowStart, 322bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcBuffer); 323bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat break; 324bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat case UNPACK_Z_INT: 325bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat _mesa_unpack_uint_z_row(readRb->Format, srcWidth, srcRowStart, 326bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcBuffer); 327bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat break; 328bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat case UNPACK_S: 329bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat _mesa_unpack_ubyte_stencil_row(readRb->Format, srcWidth, 330bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcRowStart, srcBuffer); 331bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat break; 332bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 333c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 334bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat (*resampleRow)(srcWidth, dstWidth, srcBuffer, dstBuffer, invertX); 335bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat prevY = srcRow; 336bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 337c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 338bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* store pixel row in destination */ 339bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat switch (mode) { 340bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat case DIRECT: 341b70b4862491121d5cc4444cea34f2f86a3aa5dedBrian Paul memcpy(dstRowStart, dstBuffer, pixelSize * dstWidth); 342bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat break; 343bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat case UNPACK_RGBA_FLOAT: 344bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat _mesa_pack_float_rgba_row(drawRb->Format, dstWidth, dstBuffer, 345bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat dstRowStart); 346bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat break; 347bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat case UNPACK_Z_FLOAT: 348bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat _mesa_pack_float_z_row(drawRb->Format, dstWidth, dstBuffer, 349bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat dstRowStart); 350bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat break; 351bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat case UNPACK_Z_INT: 352bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat _mesa_pack_uint_z_row(drawRb->Format, dstWidth, dstBuffer, 353bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat dstRowStart); 354bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat break; 355bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat case UNPACK_S: 356bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat _mesa_pack_ubyte_stencil_row(drawRb->Format, dstWidth, dstBuffer, 357bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat dstRowStart); 358bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat break; 359bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 3603786a3e644d0770e1247f24c6379388513728174Eric Anholt } 361c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 362bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat ctx->Driver.UnmapRenderbuffer(ctx, readRb); 363bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (drawRb != readRb) { 364bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat ctx->Driver.UnmapRenderbuffer(ctx, drawRb); 365bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 3663786a3e644d0770e1247f24c6379388513728174Eric Anholt } 367025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick 368025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanickfail: 369025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick free(srcBuffer); 370025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick free(dstBuffer); 371025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick return; 372025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick 373025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanickfail_no_memory: 374025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick free(srcBuffer); 375025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick free(dstBuffer); 376025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBuffer"); 377c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul} 378c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 379c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 380c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 381c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul#define LERP(T, A, B) ( (A) + (T) * ((B) - (A)) ) 382c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 3839520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLfloat 384c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paullerp_2d(GLfloat a, GLfloat b, 385c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLfloat v00, GLfloat v10, GLfloat v01, GLfloat v11) 386c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul{ 387c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLfloat temp0 = LERP(a, v00, v10); 388c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLfloat temp1 = LERP(a, v01, v11); 389c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul return LERP(b, temp0, temp1); 390c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul} 391c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 392c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 393c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul/** 394c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul * Bilinear interpolation of two source rows. 395c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul * GLubyte pixels. 396c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul */ 397c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paulstatic void 398c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paulresample_linear_row_ub(GLint srcWidth, GLint dstWidth, 399c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLvoid *srcBuffer0, const GLvoid *srcBuffer1, 400c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLvoid *dstBuffer, GLboolean flip, GLfloat rowWeight) 401c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul{ 402c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLubyte (*srcColor0)[4] = (const GLubyte (*)[4]) srcBuffer0; 403c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLubyte (*srcColor1)[4] = (const GLubyte (*)[4]) srcBuffer1; 404c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLubyte (*dstColor)[4] = (GLubyte (*)[4]) dstBuffer; 405c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint dstCol; 406c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 407c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul for (dstCol = 0; dstCol < dstWidth; dstCol++) { 408547a418888c455a3f5158c147a155292f398ea34Brian Paul const GLfloat srcCol = (dstCol + 0.5F) / dstWidth * srcWidth - 0.5F; 409547a418888c455a3f5158c147a155292f398ea34Brian Paul GLint srcCol0 = MAX2(0, IFLOOR(srcCol)); 410c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint srcCol1 = srcCol0 + 1; 411c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLfloat colWeight = srcCol - srcCol0; /* fractional part of srcCol */ 412c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLfloat red, green, blue, alpha; 413c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 414c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul ASSERT(srcCol0 < srcWidth); 415c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul ASSERT(srcCol1 <= srcWidth); 416c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 417c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul if (srcCol1 == srcWidth) { 418c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul /* last column fudge */ 419c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcCol1--; 420c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul colWeight = 0.0; 421c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 422c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 423c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul if (flip) { 424c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcCol0 = srcWidth - 1 - srcCol0; 425c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcCol1 = srcWidth - 1 - srcCol1; 426c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 427c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 428c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul red = lerp_2d(colWeight, rowWeight, 429c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcColor0[srcCol0][RCOMP], srcColor0[srcCol1][RCOMP], 430c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcColor1[srcCol0][RCOMP], srcColor1[srcCol1][RCOMP]); 431c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul green = lerp_2d(colWeight, rowWeight, 432c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcColor0[srcCol0][GCOMP], srcColor0[srcCol1][GCOMP], 433c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcColor1[srcCol0][GCOMP], srcColor1[srcCol1][GCOMP]); 434c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul blue = lerp_2d(colWeight, rowWeight, 435c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcColor0[srcCol0][BCOMP], srcColor0[srcCol1][BCOMP], 436c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcColor1[srcCol0][BCOMP], srcColor1[srcCol1][BCOMP]); 437c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul alpha = lerp_2d(colWeight, rowWeight, 438c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcColor0[srcCol0][ACOMP], srcColor0[srcCol1][ACOMP], 439c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcColor1[srcCol0][ACOMP], srcColor1[srcCol1][ACOMP]); 440c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 441c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dstColor[dstCol][RCOMP] = IFLOOR(red); 442c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dstColor[dstCol][GCOMP] = IFLOOR(green); 443c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dstColor[dstCol][BCOMP] = IFLOOR(blue); 444c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dstColor[dstCol][ACOMP] = IFLOOR(alpha); 445c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 446c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul} 447c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 448c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 449edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul/** 450edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul * Bilinear interpolation of two source rows. floating point pixels. 451edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul */ 452edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paulstatic void 453edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paulresample_linear_row_float(GLint srcWidth, GLint dstWidth, 454edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul const GLvoid *srcBuffer0, const GLvoid *srcBuffer1, 455edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLvoid *dstBuffer, GLboolean flip, GLfloat rowWeight) 456edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul{ 457edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul const GLfloat (*srcColor0)[4] = (const GLfloat (*)[4]) srcBuffer0; 458edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul const GLfloat (*srcColor1)[4] = (const GLfloat (*)[4]) srcBuffer1; 459edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLfloat (*dstColor)[4] = (GLfloat (*)[4]) dstBuffer; 460edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLint dstCol; 461edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 462edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul for (dstCol = 0; dstCol < dstWidth; dstCol++) { 463547a418888c455a3f5158c147a155292f398ea34Brian Paul const GLfloat srcCol = (dstCol + 0.5F) / dstWidth * srcWidth - 0.5F; 464547a418888c455a3f5158c147a155292f398ea34Brian Paul GLint srcCol0 = MAX2(0, IFLOOR(srcCol)); 465edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLint srcCol1 = srcCol0 + 1; 466edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLfloat colWeight = srcCol - srcCol0; /* fractional part of srcCol */ 467edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLfloat red, green, blue, alpha; 468edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 469edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul ASSERT(srcCol0 < srcWidth); 470edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul ASSERT(srcCol1 <= srcWidth); 471edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 472edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul if (srcCol1 == srcWidth) { 473edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul /* last column fudge */ 474edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul srcCol1--; 475edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul colWeight = 0.0; 476edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 477edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 478edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul if (flip) { 479edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul srcCol0 = srcWidth - 1 - srcCol0; 480edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul srcCol1 = srcWidth - 1 - srcCol1; 481edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 482edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 483edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul red = lerp_2d(colWeight, rowWeight, 484edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul srcColor0[srcCol0][RCOMP], srcColor0[srcCol1][RCOMP], 485edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul srcColor1[srcCol0][RCOMP], srcColor1[srcCol1][RCOMP]); 486edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul green = lerp_2d(colWeight, rowWeight, 487edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul srcColor0[srcCol0][GCOMP], srcColor0[srcCol1][GCOMP], 488edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul srcColor1[srcCol0][GCOMP], srcColor1[srcCol1][GCOMP]); 489edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul blue = lerp_2d(colWeight, rowWeight, 490edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul srcColor0[srcCol0][BCOMP], srcColor0[srcCol1][BCOMP], 491edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul srcColor1[srcCol0][BCOMP], srcColor1[srcCol1][BCOMP]); 492edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul alpha = lerp_2d(colWeight, rowWeight, 493edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul srcColor0[srcCol0][ACOMP], srcColor0[srcCol1][ACOMP], 494edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul srcColor1[srcCol0][ACOMP], srcColor1[srcCol1][ACOMP]); 495edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 496edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul dstColor[dstCol][RCOMP] = red; 497edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul dstColor[dstCol][GCOMP] = green; 498edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul dstColor[dstCol][BCOMP] = blue; 499edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul dstColor[dstCol][ACOMP] = alpha; 500edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 501edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul} 502edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 503edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 504c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 505c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul/** 506edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul * Bilinear filtered blit (color only, non-integer values). 507c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul */ 508c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paulstatic void 509f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergblit_linear(struct gl_context *ctx, 510c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 511c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1) 512c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul{ 513bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat struct gl_framebuffer *drawFb = ctx->DrawBuffer; 514bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat struct gl_framebuffer *readFb = ctx->ReadBuffer; 515bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat struct gl_renderbuffer *readRb = readFb->_ColorReadBuffer; 516bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat struct gl_renderbuffer_attachment *readAtt = 517bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat &readFb->Attachment[readFb->_ColorReadBufferIndex]; 518c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 519c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint srcWidth = ABS(srcX1 - srcX0); 520c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint dstWidth = ABS(dstX1 - dstX0); 521c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint srcHeight = ABS(srcY1 - srcY0); 522c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint dstHeight = ABS(dstY1 - dstY0); 523c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 524c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint srcXpos = MIN2(srcX0, srcX1); 525c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint srcYpos = MIN2(srcY0, srcY1); 526c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint dstXpos = MIN2(dstX0, dstX1); 527c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint dstYpos = MIN2(dstY0, dstY1); 528c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 529c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLboolean invertX = (srcX1 < srcX0) ^ (dstX1 < dstX0); 530c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLboolean invertY = (srcY1 < srcY0) ^ (dstY1 < dstY0); 531c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 532c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint dstRow; 533c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 534c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint pixelSize; 535c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLvoid *srcBuffer0, *srcBuffer1; 536c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint srcBufferY0 = -1, srcBufferY1 = -1; 537c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLvoid *dstBuffer; 538c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 539edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul gl_format readFormat = _mesa_get_srgb_format_linear(readRb->Format); 540edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLuint bpp = _mesa_get_format_bytes(readFormat); 541edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 542edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLenum pixelType; 543edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 544edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLubyte *srcMap, *dstMap; 545edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLint srcRowStride, dstRowStride; 546bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GLuint i; 547edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 548edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 549edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul /* Determine datatype for resampling */ 550edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul if (_mesa_get_format_max_bits(readFormat) == 8 && 551edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul _mesa_get_format_datatype(readFormat) == GL_UNSIGNED_NORMALIZED) { 552edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul pixelType = GL_UNSIGNED_BYTE; 553c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul pixelSize = 4 * sizeof(GLubyte); 554edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 555edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul else { 556edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul pixelType = GL_FLOAT; 557c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul pixelSize = 4 * sizeof(GLfloat); 558c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 559c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 560c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul /* Allocate the src/dst row buffers. 561c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul * Keep two adjacent src rows around for bilinear sampling. 562c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul */ 56332f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg srcBuffer0 = malloc(pixelSize * srcWidth); 56432f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg srcBuffer1 = malloc(pixelSize * srcWidth); 56532f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg dstBuffer = malloc(pixelSize * dstWidth); 5666758498eb79287fe5d67cd5c869e9fd387f95defIan Romanick if (!srcBuffer0 || !srcBuffer1 || !dstBuffer) { 5676758498eb79287fe5d67cd5c869e9fd387f95defIan Romanick goto fail_no_memory; 568c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 569c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 570bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat for (i = 0; i < drawFb->_NumColorDrawBuffers; i++) { 57157ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul GLint idx = drawFb->_ColorDrawBufferIndexes[i]; 57257ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul struct gl_renderbuffer_attachment *drawAtt; 57357ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul struct gl_renderbuffer *drawRb; 57457ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul gl_format drawFormat; 57557ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul 576bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (idx == -1) 577bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat continue; 57857ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul 579bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat drawAtt = &drawFb->Attachment[idx]; 580bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat drawRb = drawAtt->Renderbuffer; 58157ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul if (!drawRb) 58257ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul continue; 58357ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul 58457ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul drawFormat = _mesa_get_srgb_format_linear(drawRb->Format); 58557ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul 586bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* 587bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat * Map src / dst renderbuffers 588edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul */ 589bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if ((readRb == drawRb) || 590bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat (readAtt->Texture && drawAtt->Texture && 59157ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul (readAtt->Texture == drawAtt->Texture))) { 592bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* map whole buffer for read/write */ 593bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat ctx->Driver.MapRenderbuffer(ctx, readRb, 594bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat 0, 0, readRb->Width, readRb->Height, 595bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, 596bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat &srcMap, &srcRowStride); 597bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (!srcMap) { 5986758498eb79287fe5d67cd5c869e9fd387f95defIan Romanick goto fail_no_memory; 599bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 600bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat 601bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat dstMap = srcMap; 602bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat dstRowStride = srcRowStride; 603edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 604bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat else { 605bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* different src/dst buffers */ 606bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* XXX with a bit of work we could just map the regions to be 607bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat * read/written instead of the whole buffers. 608bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat */ 609bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat ctx->Driver.MapRenderbuffer(ctx, readRb, 610bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat 0, 0, readRb->Width, readRb->Height, 611bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GL_MAP_READ_BIT, &srcMap, &srcRowStride); 612bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (!srcMap) { 6136758498eb79287fe5d67cd5c869e9fd387f95defIan Romanick goto fail_no_memory; 614bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 615bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat ctx->Driver.MapRenderbuffer(ctx, drawRb, 616bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat 0, 0, drawRb->Width, drawRb->Height, 617bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GL_MAP_WRITE_BIT, &dstMap, &dstRowStride); 618bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (!dstMap) { 619bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat ctx->Driver.UnmapRenderbuffer(ctx, readRb); 6206758498eb79287fe5d67cd5c869e9fd387f95defIan Romanick goto fail_no_memory; 621bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 622edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 623edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 624bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat for (dstRow = 0; dstRow < dstHeight; dstRow++) { 625bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat const GLint dstY = dstYpos + dstRow; 626547a418888c455a3f5158c147a155292f398ea34Brian Paul GLfloat srcRow = (dstRow + 0.5F) / dstHeight * srcHeight - 0.5F; 627547a418888c455a3f5158c147a155292f398ea34Brian Paul GLint srcRow0 = MAX2(0, IFLOOR(srcRow)); 628bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GLint srcRow1 = srcRow0 + 1; 629bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GLfloat rowWeight = srcRow - srcRow0; /* fractional part of srcRow */ 630c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 631bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (srcRow1 == srcHeight) { 632bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* last row fudge */ 633bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcRow1 = srcRow0; 634bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat rowWeight = 0.0; 635bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 636c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 637bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (invertY) { 638bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcRow0 = srcHeight - 1 - srcRow0; 639bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcRow1 = srcHeight - 1 - srcRow1; 640bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 641c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 642bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcY0 = srcYpos + srcRow0; 643bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcY1 = srcYpos + srcRow1; 644c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 645bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* get the two source rows */ 646bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (srcY0 == srcBufferY0 && srcY1 == srcBufferY1) { 647bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* use same source row buffers again */ 648bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 649bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat else if (srcY0 == srcBufferY1) { 650bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* move buffer1 into buffer0 by swapping pointers */ 651bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GLvoid *tmp = srcBuffer0; 652bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcBuffer0 = srcBuffer1; 653bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcBuffer1 = tmp; 654bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* get y1 row */ 655bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat { 656bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GLubyte *src = srcMap + srcY1 * srcRowStride + srcXpos * bpp; 657bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (pixelType == GL_UNSIGNED_BYTE) { 658bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat _mesa_unpack_ubyte_rgba_row(readFormat, srcWidth, 659bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat src, srcBuffer1); 660bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 661bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat else { 662bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat _mesa_unpack_rgba_row(readFormat, srcWidth, 663bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat src, srcBuffer1); 664bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 665edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 666bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcBufferY0 = srcY0; 667bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcBufferY1 = srcY1; 668bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 669bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat else { 670bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* get both new rows */ 671bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat { 672bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GLubyte *src0 = srcMap + srcY0 * srcRowStride + srcXpos * bpp; 673bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GLubyte *src1 = srcMap + srcY1 * srcRowStride + srcXpos * bpp; 674bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (pixelType == GL_UNSIGNED_BYTE) { 675bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat _mesa_unpack_ubyte_rgba_row(readFormat, srcWidth, 676bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat src0, srcBuffer0); 677bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat _mesa_unpack_ubyte_rgba_row(readFormat, srcWidth, 678bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat src1, srcBuffer1); 679bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 680bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat else { 681bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat _mesa_unpack_rgba_row(readFormat, srcWidth, src0, srcBuffer0); 682bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat _mesa_unpack_rgba_row(readFormat, srcWidth, src1, srcBuffer1); 683bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 684edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 685bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcBufferY0 = srcY0; 686bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcBufferY1 = srcY1; 687bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 688bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat 689bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (pixelType == GL_UNSIGNED_BYTE) { 690bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat resample_linear_row_ub(srcWidth, dstWidth, srcBuffer0, srcBuffer1, 691bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat dstBuffer, invertX, rowWeight); 692bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 693bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat else { 694bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat resample_linear_row_float(srcWidth, dstWidth, srcBuffer0, srcBuffer1, 695bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat dstBuffer, invertX, rowWeight); 696bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 697bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat 698bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* store pixel row in destination */ 699edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul { 700bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GLubyte *dst = dstMap + dstY * dstRowStride + dstXpos * bpp; 701edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul if (pixelType == GL_UNSIGNED_BYTE) { 702bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat _mesa_pack_ubyte_rgba_row(drawFormat, dstWidth, dstBuffer, dst); 703edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 704edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul else { 705bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat _mesa_pack_float_rgba_row(drawFormat, dstWidth, dstBuffer, dst); 706edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 707edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 708c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 709c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 710bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat ctx->Driver.UnmapRenderbuffer(ctx, readRb); 711bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (drawRb != readRb) { 712bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat ctx->Driver.UnmapRenderbuffer(ctx, drawRb); 713edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 714c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 7156758498eb79287fe5d67cd5c869e9fd387f95defIan Romanick 716a27c6e1aea1d048e0c701ca59c3c5bcf12b69d7bIan Romanick free(srcBuffer0); 717a27c6e1aea1d048e0c701ca59c3c5bcf12b69d7bIan Romanick free(srcBuffer1); 718a27c6e1aea1d048e0c701ca59c3c5bcf12b69d7bIan Romanick free(dstBuffer); 719a27c6e1aea1d048e0c701ca59c3c5bcf12b69d7bIan Romanick return; 720a27c6e1aea1d048e0c701ca59c3c5bcf12b69d7bIan Romanick 7216758498eb79287fe5d67cd5c869e9fd387f95defIan Romanickfail_no_memory: 7226758498eb79287fe5d67cd5c869e9fd387f95defIan Romanick free(srcBuffer0); 7236758498eb79287fe5d67cd5c869e9fd387f95defIan Romanick free(srcBuffer1); 7246758498eb79287fe5d67cd5c869e9fd387f95defIan Romanick free(dstBuffer); 7256758498eb79287fe5d67cd5c869e9fd387f95defIan Romanick _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer"); 726c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul} 727c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 728edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 729edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 730c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul/** 7311eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * Software fallback for glBlitFramebufferEXT(). 7321eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul */ 7331eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paulvoid 734f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_swrast_BlitFramebuffer(struct gl_context *ctx, 735c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 736c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 737c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLbitfield mask, GLenum filter) 7381eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul{ 739b15334035177fbb031f000583ef7cb31f68b248cBrian Paul static const GLbitfield buffers[3] = { 740c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GL_COLOR_BUFFER_BIT, 741c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GL_DEPTH_BUFFER_BIT, 742c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GL_STENCIL_BUFFER_BIT 743c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul }; 744fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt static const GLenum buffer_enums[3] = { 745fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt GL_COLOR, 746fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt GL_DEPTH, 747fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt GL_STENCIL, 748fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt }; 749c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint i; 750c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 751727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul if (!_mesa_clip_blit(ctx, &srcX0, &srcY0, &srcX1, &srcY1, 752727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul &dstX0, &dstY0, &dstX1, &dstY1)) { 753c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul return; 754c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 755c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 75622e806f57013b2c116b5bfab228e0f28e25198f4Brian Paul if (SWRAST_CONTEXT(ctx)->NewState) 75722e806f57013b2c116b5bfab228e0f28e25198f4Brian Paul _swrast_validate_derived(ctx); 75822e806f57013b2c116b5bfab228e0f28e25198f4Brian Paul 759fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt /* First, try covering whatever buffers possible using the fast 1:1 copy 760fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt * path. 761fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt */ 762c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul if (srcX1 - srcX0 == dstX1 - dstX0 && 763c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcY1 - srcY0 == dstY1 - dstY0 && 764c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcX0 < srcX1 && 765c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcY0 < srcY1 && 766c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dstX0 < dstX1 && 767c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dstY0 < dstY1) { 768c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul for (i = 0; i < 3; i++) { 769c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul if (mask & buffers[i]) { 770fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt if (swrast_fast_copy_pixels(ctx, 771fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt srcX0, srcY0, 772fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt srcX1 - srcX0, srcY1 - srcY0, 773fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt dstX0, dstY0, 774fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt buffer_enums[i])) { 775fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt mask &= ~buffers[i]; 776fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt } 777fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt } 778c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 779fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt 780fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt if (!mask) 781fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt return; 782c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 783fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt 784fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt if (filter == GL_NEAREST) { 785fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt for (i = 0; i < 3; i++) { 786fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt if (mask & buffers[i]) { 787fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt blit_nearest(ctx, srcX0, srcY0, srcX1, srcY1, 788fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt dstX0, dstY0, dstX1, dstY1, buffers[i]); 789fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt } 790c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 791fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt } 792fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt else { 793fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt ASSERT(filter == GL_LINEAR); 794fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt if (mask & GL_COLOR_BUFFER_BIT) { /* depth/stencil not allowed */ 795fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt blit_linear(ctx, srcX0, srcY0, srcX1, srcY1, 796fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt dstX0, dstY0, dstX1, dstY1); 797c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 798c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 799c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 8001eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul} 801