s_blit.c revision e9b86cb5d66867b66c6d453d7bd60bd56fe6587d
11eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul/* 21eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * Mesa 3-D graphics library 31eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * 41eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. 51eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * 61eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * Permission is hereby granted, free of charge, to any person obtaining a 71eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * copy of this software and associated documentation files (the "Software"), 81eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * to deal in the Software without restriction, including without limitation 91eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * the rights to use, copy, modify, merge, publish, distribute, sublicense, 101eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * and/or sell copies of the Software, and to permit persons to whom the 111eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * Software is furnished to do so, subject to the following conditions: 121eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * 131eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * The above copyright notice and this permission notice shall be included 141eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * in all copies or substantial portions of the Software. 151eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * 161eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 171eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 181eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 193d8d5b298a268b119d840bc9bae0ee9e0c9244a9Kenneth Graunke * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 203d8d5b298a268b119d840bc9bae0ee9e0c9244a9Kenneth Graunke * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 213d8d5b298a268b119d840bc9bae0ee9e0c9244a9Kenneth Graunke * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 223d8d5b298a268b119d840bc9bae0ee9e0c9244a9Kenneth Graunke * 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" 328ed42ddd7d31b6c9c65c735ad27ca2873859129eAnuj Phogat#include "main/condrender.h" 331eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul#include "s_context.h" 341eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul 351eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul 36c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul#define ABS(X) ((X) < 0 ? -(X) : (X)) 37c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 38c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 39c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul/** 40c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul * Generate a row resampler function for GL_NEAREST mode. 41c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul */ 42c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul#define RESAMPLE(NAME, PIXELTYPE, SIZE) \ 43c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paulstatic void \ 44c241d3b06a5c996cb8415a6ada23288621c1d254Brian PaulNAME(GLint srcWidth, GLint dstWidth, \ 45c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLvoid *srcBuffer, GLvoid *dstBuffer, \ 46c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLboolean flip) \ 47c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul{ \ 48c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const PIXELTYPE *src = (const PIXELTYPE *) srcBuffer;\ 49c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul PIXELTYPE *dst = (PIXELTYPE *) dstBuffer; \ 50c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint dstCol; \ 51c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul \ 52c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul if (flip) { \ 53c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul for (dstCol = 0; dstCol < dstWidth; dstCol++) { \ 54c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint srcCol = (dstCol * srcWidth) / dstWidth; \ 55c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul ASSERT(srcCol >= 0); \ 56c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul ASSERT(srcCol < srcWidth); \ 57c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcCol = srcWidth - 1 - srcCol; /* flip */ \ 58c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul if (SIZE == 1) { \ 59c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dst[dstCol] = src[srcCol]; \ 60c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } \ 61c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul else if (SIZE == 2) { \ 62c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dst[dstCol*2+0] = src[srcCol*2+0]; \ 63c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dst[dstCol*2+1] = src[srcCol*2+1]; \ 64c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } \ 65c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul else if (SIZE == 4) { \ 66c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dst[dstCol*4+0] = src[srcCol*4+0]; \ 67c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dst[dstCol*4+1] = src[srcCol*4+1]; \ 68c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dst[dstCol*4+2] = src[srcCol*4+2]; \ 69c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dst[dstCol*4+3] = src[srcCol*4+3]; \ 70c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } \ 71c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } \ 72c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } \ 73c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul else { \ 74c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul for (dstCol = 0; dstCol < dstWidth; dstCol++) { \ 75c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint srcCol = (dstCol * srcWidth) / dstWidth; \ 76c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul ASSERT(srcCol >= 0); \ 77c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul ASSERT(srcCol < srcWidth); \ 78c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul if (SIZE == 1) { \ 79c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dst[dstCol] = src[srcCol]; \ 80c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } \ 81c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul else if (SIZE == 2) { \ 82c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dst[dstCol*2+0] = src[srcCol*2+0]; \ 83c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dst[dstCol*2+1] = src[srcCol*2+1]; \ 84c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } \ 85c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul else if (SIZE == 4) { \ 86c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dst[dstCol*4+0] = src[srcCol*4+0]; \ 87c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dst[dstCol*4+1] = src[srcCol*4+1]; \ 88c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dst[dstCol*4+2] = src[srcCol*4+2]; \ 89c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dst[dstCol*4+3] = src[srcCol*4+3]; \ 90c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } \ 91c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } \ 92c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } \ 93c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul} 94c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 95c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul/** 96c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul * Resamplers for 1, 2, 4, 8 and 16-byte pixels. 97c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul */ 98c241d3b06a5c996cb8415a6ada23288621c1d254Brian PaulRESAMPLE(resample_row_1, GLubyte, 1) 99c241d3b06a5c996cb8415a6ada23288621c1d254Brian PaulRESAMPLE(resample_row_2, GLushort, 1) 100c241d3b06a5c996cb8415a6ada23288621c1d254Brian PaulRESAMPLE(resample_row_4, GLuint, 1) 101c241d3b06a5c996cb8415a6ada23288621c1d254Brian PaulRESAMPLE(resample_row_8, GLuint, 2) 102c241d3b06a5c996cb8415a6ada23288621c1d254Brian PaulRESAMPLE(resample_row_16, GLuint, 4) 103c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 104c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 105c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul/** 106c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul * Blit color, depth or stencil with GL_NEAREST filtering. 107c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul */ 108c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paulstatic void 109f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergblit_nearest(struct gl_context *ctx, 110e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand struct gl_framebuffer *readFb, 111e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand struct gl_framebuffer *drawFb, 112c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 113c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 114b15334035177fbb031f000583ef7cb31f68b248cBrian Paul GLbitfield buffer) 115c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul{ 11635aefe922660ed6e8fbad082757ae759acd711ddBrian Paul struct gl_renderbuffer *readRb, *drawRb = NULL; 11735aefe922660ed6e8fbad082757ae759acd711ddBrian Paul struct gl_renderbuffer_attachment *readAtt = NULL, *drawAtt = NULL; 11857ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul GLuint numDrawBuffers = 0; 119bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GLuint i; 120c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 121c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint srcWidth = ABS(srcX1 - srcX0); 122c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint dstWidth = ABS(dstX1 - dstX0); 123c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint srcHeight = ABS(srcY1 - srcY0); 124c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint dstHeight = ABS(dstY1 - dstY0); 125c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 126c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint srcXpos = MIN2(srcX0, srcX1); 127c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint srcYpos = MIN2(srcY0, srcY1); 128c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint dstXpos = MIN2(dstX0, dstX1); 129c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint dstYpos = MIN2(dstY0, dstY1); 130c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 131c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLboolean invertX = (srcX1 < srcX0) ^ (dstX1 < dstX0); 132c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLboolean invertY = (srcY1 < srcY0) ^ (dstY1 < dstY0); 1333786a3e644d0770e1247f24c6379388513728174Eric Anholt enum mode { 1343786a3e644d0770e1247f24c6379388513728174Eric Anholt DIRECT, 1353786a3e644d0770e1247f24c6379388513728174Eric Anholt UNPACK_RGBA_FLOAT, 1363786a3e644d0770e1247f24c6379388513728174Eric Anholt UNPACK_Z_FLOAT, 1373786a3e644d0770e1247f24c6379388513728174Eric Anholt UNPACK_Z_INT, 1383786a3e644d0770e1247f24c6379388513728174Eric Anholt UNPACK_S, 13935aefe922660ed6e8fbad082757ae759acd711ddBrian Paul } mode = DIRECT; 1403786a3e644d0770e1247f24c6379388513728174Eric Anholt GLubyte *srcMap, *dstMap; 1413786a3e644d0770e1247f24c6379388513728174Eric Anholt GLint srcRowStride, dstRowStride; 142c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint dstRow; 143c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 14435aefe922660ed6e8fbad082757ae759acd711ddBrian Paul GLint pixelSize = 0; 145c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLvoid *srcBuffer, *dstBuffer; 146c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint prevY = -1; 147c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 148c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul typedef void (*resample_func)(GLint srcWidth, GLint dstWidth, 149c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLvoid *srcBuffer, GLvoid *dstBuffer, 150c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLboolean flip); 151c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul resample_func resampleRow; 152c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 153c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul switch (buffer) { 154c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul case GL_COLOR_BUFFER_BIT: 155bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat readAtt = &readFb->Attachment[readFb->_ColorReadBufferIndex]; 156bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat readRb = readFb->_ColorReadBuffer; 15757ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul numDrawBuffers = drawFb->_NumColorDrawBuffers; 158c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul break; 159c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul case GL_DEPTH_BUFFER_BIT: 160bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat readAtt = &readFb->Attachment[BUFFER_DEPTH]; 161bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat drawAtt = &drawFb->Attachment[BUFFER_DEPTH]; 162bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat readRb = readAtt->Renderbuffer; 163bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat drawRb = drawAtt->Renderbuffer; 16457ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul numDrawBuffers = 1; 1653786a3e644d0770e1247f24c6379388513728174Eric Anholt 1663786a3e644d0770e1247f24c6379388513728174Eric Anholt /* Note that for depth/stencil, the formats of src/dst must match. By 1673786a3e644d0770e1247f24c6379388513728174Eric Anholt * using the core helpers for pack/unpack, we avoid needing to handle 1683786a3e644d0770e1247f24c6379388513728174Eric Anholt * masking for things like DEPTH copies of Z24S8. 1693786a3e644d0770e1247f24c6379388513728174Eric Anholt */ 17050a01d2acafb2a937e62b24258e2e777c0cd1489Mark Mueller if (readRb->Format == MESA_FORMAT_Z_FLOAT32 || 171eeed49f5f290793870c60b5b635b977a732a1eb4Mark Mueller readRb->Format == MESA_FORMAT_Z32_FLOAT_S8X24_UINT) { 1723786a3e644d0770e1247f24c6379388513728174Eric Anholt mode = UNPACK_Z_FLOAT; 1733786a3e644d0770e1247f24c6379388513728174Eric Anholt } else { 1743786a3e644d0770e1247f24c6379388513728174Eric Anholt mode = UNPACK_Z_INT; 1753786a3e644d0770e1247f24c6379388513728174Eric Anholt } 1763786a3e644d0770e1247f24c6379388513728174Eric Anholt pixelSize = 4; 177c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul break; 178c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul case GL_STENCIL_BUFFER_BIT: 179bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat readAtt = &readFb->Attachment[BUFFER_STENCIL]; 180bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat drawAtt = &drawFb->Attachment[BUFFER_STENCIL]; 181bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat readRb = readAtt->Renderbuffer; 182bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat drawRb = drawAtt->Renderbuffer; 18357ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul numDrawBuffers = 1; 1843786a3e644d0770e1247f24c6379388513728174Eric Anholt mode = UNPACK_S; 1853786a3e644d0770e1247f24c6379388513728174Eric Anholt pixelSize = 1; 186c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul break; 187c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul default: 188c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul _mesa_problem(ctx, "unexpected buffer in blit_nearest()"); 189c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul return; 190c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 191c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 192025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick /* allocate the src/dst row buffers */ 193025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick srcBuffer = malloc(MAX_PIXEL_BYTES * srcWidth); 194025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick dstBuffer = malloc(MAX_PIXEL_BYTES * dstWidth); 195025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick if (!srcBuffer || !dstBuffer) 196025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick goto fail_no_memory; 197025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick 198bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* Blit to all the draw buffers */ 19957ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul for (i = 0; i < numDrawBuffers; i++) { 200bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (buffer == GL_COLOR_BUFFER_BIT) { 201bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat int idx = drawFb->_ColorDrawBufferIndexes[i]; 202bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (idx == -1) 203bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat continue; 204bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat drawAtt = &drawFb->Attachment[idx]; 205bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat drawRb = drawAtt->Renderbuffer; 206bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat 20757ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul if (!drawRb) 20857ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul continue; 20957ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul 210bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (readRb->Format == drawRb->Format) { 211bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat mode = DIRECT; 212bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat pixelSize = _mesa_get_format_bytes(readRb->Format); 213bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } else { 214bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat mode = UNPACK_RGBA_FLOAT; 215bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat pixelSize = 16; 216bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 2173786a3e644d0770e1247f24c6379388513728174Eric Anholt } 2183786a3e644d0770e1247f24c6379388513728174Eric Anholt 219728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul /* choose row resampler */ 220728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul switch (pixelSize) { 221728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul case 1: 222728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul resampleRow = resample_row_1; 223728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul break; 224728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul case 2: 225728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul resampleRow = resample_row_2; 226728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul break; 227728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul case 4: 228728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul resampleRow = resample_row_4; 229728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul break; 230728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul case 8: 231728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul resampleRow = resample_row_8; 232728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul break; 233728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul case 16: 234728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul resampleRow = resample_row_16; 235728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul break; 236728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul default: 237728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul _mesa_problem(ctx, "unexpected pixel size (%d) in blit_nearest", 238728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul pixelSize); 239025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick goto fail; 240728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul } 241728bf86a23f6de137c0871ea87b09e75e55468a9Brian Paul 242bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if ((readRb == drawRb) || 243bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat (readAtt->Texture && drawAtt->Texture && 244bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat (readAtt->Texture == drawAtt->Texture))) { 245bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* map whole buffer for read/write */ 246bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* XXX we could be clever and just map the union region of the 247bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat * source and dest rects. 248bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat */ 249bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GLubyte *map; 250bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GLint rowStride; 251bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GLint formatSize = _mesa_get_format_bytes(readRb->Format); 252bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat 253bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat ctx->Driver.MapRenderbuffer(ctx, readRb, 0, 0, 254bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat readRb->Width, readRb->Height, 255bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, 256bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat &map, &rowStride); 257bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (!map) { 258025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick goto fail_no_memory; 259bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 260bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat 261bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcMap = map + srcYpos * rowStride + srcXpos * formatSize; 262bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat dstMap = map + dstYpos * rowStride + dstXpos * formatSize; 2633786a3e644d0770e1247f24c6379388513728174Eric Anholt 264bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* this handles overlapping copies */ 265bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (srcY0 < dstY0) { 266bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* copy in reverse (top->down) order */ 267bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcMap += rowStride * (readRb->Height - 1); 268bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat dstMap += rowStride * (readRb->Height - 1); 269bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcRowStride = -rowStride; 270bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat dstRowStride = -rowStride; 271bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 272bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat else { 273bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* copy in normal (bottom->up) order */ 274bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcRowStride = rowStride; 275bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat dstRowStride = rowStride; 276bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 2773786a3e644d0770e1247f24c6379388513728174Eric Anholt } 2783786a3e644d0770e1247f24c6379388513728174Eric Anholt else { 279bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* different src/dst buffers */ 280bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat ctx->Driver.MapRenderbuffer(ctx, readRb, 281bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcXpos, srcYpos, 282bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcWidth, srcHeight, 283bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GL_MAP_READ_BIT, &srcMap, &srcRowStride); 284bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (!srcMap) { 285025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick goto fail_no_memory; 286bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 287bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat ctx->Driver.MapRenderbuffer(ctx, drawRb, 288bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat dstXpos, dstYpos, 289bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat dstWidth, dstHeight, 290bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GL_MAP_WRITE_BIT, &dstMap, &dstRowStride); 291bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (!dstMap) { 292bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat ctx->Driver.UnmapRenderbuffer(ctx, readRb); 293025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick goto fail_no_memory; 294bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 2953786a3e644d0770e1247f24c6379388513728174Eric Anholt } 296bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat 297bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat for (dstRow = 0; dstRow < dstHeight; dstRow++) { 298547a418888c455a3f5158c147a155292f398ea34Brian Paul GLfloat srcRowF = (dstRow + 0.5F) / dstHeight * srcHeight - 0.5F; 299547a418888c455a3f5158c147a155292f398ea34Brian Paul GLint srcRow = IROUND(srcRowF); 300bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GLubyte *dstRowStart = dstMap + dstRowStride * dstRow; 301c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 302bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat ASSERT(srcRow >= 0); 303bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat ASSERT(srcRow < srcHeight); 304c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 305bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (invertY) { 306bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcRow = srcHeight - 1 - srcRow; 307bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 308c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 309bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* get pixel row from source and resample to match dest width */ 310bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (prevY != srcRow) { 311bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GLubyte *srcRowStart = srcMap + srcRowStride * srcRow; 312bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat 313bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat switch (mode) { 314bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat case DIRECT: 315bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat memcpy(srcBuffer, srcRowStart, pixelSize * srcWidth); 316bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat break; 317bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat case UNPACK_RGBA_FLOAT: 318bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat _mesa_unpack_rgba_row(readRb->Format, srcWidth, srcRowStart, 319bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcBuffer); 320bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat break; 321bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat case UNPACK_Z_FLOAT: 322bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat _mesa_unpack_float_z_row(readRb->Format, srcWidth, srcRowStart, 323bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcBuffer); 324bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat break; 325bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat case UNPACK_Z_INT: 326bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat _mesa_unpack_uint_z_row(readRb->Format, srcWidth, srcRowStart, 327bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcBuffer); 328bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat break; 329bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat case UNPACK_S: 330bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat _mesa_unpack_ubyte_stencil_row(readRb->Format, srcWidth, 331bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcRowStart, srcBuffer); 332bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat break; 333bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 334c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 335bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat (*resampleRow)(srcWidth, dstWidth, srcBuffer, dstBuffer, invertX); 336bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat prevY = srcRow; 337bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 338c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 339bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* store pixel row in destination */ 340bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat switch (mode) { 341bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat case DIRECT: 342b70b4862491121d5cc4444cea34f2f86a3aa5dedBrian Paul memcpy(dstRowStart, dstBuffer, pixelSize * dstWidth); 343bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat break; 344bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat case UNPACK_RGBA_FLOAT: 345bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat _mesa_pack_float_rgba_row(drawRb->Format, dstWidth, dstBuffer, 346bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat dstRowStart); 347bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat break; 348bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat case UNPACK_Z_FLOAT: 349bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat _mesa_pack_float_z_row(drawRb->Format, dstWidth, dstBuffer, 350bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat dstRowStart); 351bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat break; 352bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat case UNPACK_Z_INT: 353bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat _mesa_pack_uint_z_row(drawRb->Format, dstWidth, dstBuffer, 354bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat dstRowStart); 355bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat break; 356bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat case UNPACK_S: 357bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat _mesa_pack_ubyte_stencil_row(drawRb->Format, dstWidth, dstBuffer, 358bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat dstRowStart); 359bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat break; 360bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 3613786a3e644d0770e1247f24c6379388513728174Eric Anholt } 362c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 363bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat ctx->Driver.UnmapRenderbuffer(ctx, readRb); 364bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (drawRb != readRb) { 365bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat ctx->Driver.UnmapRenderbuffer(ctx, drawRb); 366bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 3673786a3e644d0770e1247f24c6379388513728174Eric Anholt } 368025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick 369025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanickfail: 370025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick free(srcBuffer); 371025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick free(dstBuffer); 372025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick return; 373025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick 374025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanickfail_no_memory: 375025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick free(srcBuffer); 376025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick free(dstBuffer); 377025f03f3b70989d27a20fea42763e3ccac946aa4Ian Romanick _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFrameBuffer"); 378c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul} 379c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 380c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 381c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 382c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul#define LERP(T, A, B) ( (A) + (T) * ((B) - (A)) ) 383c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 3849520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline GLfloat 385c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paullerp_2d(GLfloat a, GLfloat b, 386c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLfloat v00, GLfloat v10, GLfloat v01, GLfloat v11) 387c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul{ 388c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLfloat temp0 = LERP(a, v00, v10); 389c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLfloat temp1 = LERP(a, v01, v11); 390c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul return LERP(b, temp0, temp1); 391c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul} 392c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 393c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 394c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul/** 395c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul * Bilinear interpolation of two source rows. 396c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul * GLubyte pixels. 397c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul */ 398c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paulstatic void 399c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paulresample_linear_row_ub(GLint srcWidth, GLint dstWidth, 400c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLvoid *srcBuffer0, const GLvoid *srcBuffer1, 401c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLvoid *dstBuffer, GLboolean flip, GLfloat rowWeight) 402c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul{ 403c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLubyte (*srcColor0)[4] = (const GLubyte (*)[4]) srcBuffer0; 404c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLubyte (*srcColor1)[4] = (const GLubyte (*)[4]) srcBuffer1; 405c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLubyte (*dstColor)[4] = (GLubyte (*)[4]) dstBuffer; 406c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint dstCol; 407c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 408c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul for (dstCol = 0; dstCol < dstWidth; dstCol++) { 409547a418888c455a3f5158c147a155292f398ea34Brian Paul const GLfloat srcCol = (dstCol + 0.5F) / dstWidth * srcWidth - 0.5F; 410547a418888c455a3f5158c147a155292f398ea34Brian Paul GLint srcCol0 = MAX2(0, IFLOOR(srcCol)); 411c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint srcCol1 = srcCol0 + 1; 412c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLfloat colWeight = srcCol - srcCol0; /* fractional part of srcCol */ 413c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLfloat red, green, blue, alpha; 414c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 415c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul ASSERT(srcCol0 < srcWidth); 416c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul ASSERT(srcCol1 <= srcWidth); 417c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 418c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul if (srcCol1 == srcWidth) { 419c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul /* last column fudge */ 420c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcCol1--; 421c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul colWeight = 0.0; 422c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 423c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 424c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul if (flip) { 425c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcCol0 = srcWidth - 1 - srcCol0; 426c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcCol1 = srcWidth - 1 - srcCol1; 427c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 428c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 429c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul red = lerp_2d(colWeight, rowWeight, 430c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcColor0[srcCol0][RCOMP], srcColor0[srcCol1][RCOMP], 431c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcColor1[srcCol0][RCOMP], srcColor1[srcCol1][RCOMP]); 432c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul green = lerp_2d(colWeight, rowWeight, 433c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcColor0[srcCol0][GCOMP], srcColor0[srcCol1][GCOMP], 434c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcColor1[srcCol0][GCOMP], srcColor1[srcCol1][GCOMP]); 435c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul blue = lerp_2d(colWeight, rowWeight, 436c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcColor0[srcCol0][BCOMP], srcColor0[srcCol1][BCOMP], 437c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcColor1[srcCol0][BCOMP], srcColor1[srcCol1][BCOMP]); 438c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul alpha = lerp_2d(colWeight, rowWeight, 439c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcColor0[srcCol0][ACOMP], srcColor0[srcCol1][ACOMP], 440c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcColor1[srcCol0][ACOMP], srcColor1[srcCol1][ACOMP]); 441c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 442c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dstColor[dstCol][RCOMP] = IFLOOR(red); 443c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dstColor[dstCol][GCOMP] = IFLOOR(green); 444c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dstColor[dstCol][BCOMP] = IFLOOR(blue); 445c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dstColor[dstCol][ACOMP] = IFLOOR(alpha); 446c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 447c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul} 448c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 449c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 450edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul/** 451edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul * Bilinear interpolation of two source rows. floating point pixels. 452edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul */ 453edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paulstatic void 454edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paulresample_linear_row_float(GLint srcWidth, GLint dstWidth, 455edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul const GLvoid *srcBuffer0, const GLvoid *srcBuffer1, 456edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLvoid *dstBuffer, GLboolean flip, GLfloat rowWeight) 457edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul{ 458edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul const GLfloat (*srcColor0)[4] = (const GLfloat (*)[4]) srcBuffer0; 459edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul const GLfloat (*srcColor1)[4] = (const GLfloat (*)[4]) srcBuffer1; 460edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLfloat (*dstColor)[4] = (GLfloat (*)[4]) dstBuffer; 461edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLint dstCol; 462edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 463edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul for (dstCol = 0; dstCol < dstWidth; dstCol++) { 464547a418888c455a3f5158c147a155292f398ea34Brian Paul const GLfloat srcCol = (dstCol + 0.5F) / dstWidth * srcWidth - 0.5F; 465547a418888c455a3f5158c147a155292f398ea34Brian Paul GLint srcCol0 = MAX2(0, IFLOOR(srcCol)); 466edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLint srcCol1 = srcCol0 + 1; 467edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLfloat colWeight = srcCol - srcCol0; /* fractional part of srcCol */ 468edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLfloat red, green, blue, alpha; 469edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 470edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul ASSERT(srcCol0 < srcWidth); 471edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul ASSERT(srcCol1 <= srcWidth); 472edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 473edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul if (srcCol1 == srcWidth) { 474edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul /* last column fudge */ 475edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul srcCol1--; 476edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul colWeight = 0.0; 477edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 478edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 479edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul if (flip) { 480edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul srcCol0 = srcWidth - 1 - srcCol0; 481edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul srcCol1 = srcWidth - 1 - srcCol1; 482edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 483edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 484edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul red = lerp_2d(colWeight, rowWeight, 485edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul srcColor0[srcCol0][RCOMP], srcColor0[srcCol1][RCOMP], 486edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul srcColor1[srcCol0][RCOMP], srcColor1[srcCol1][RCOMP]); 487edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul green = lerp_2d(colWeight, rowWeight, 488edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul srcColor0[srcCol0][GCOMP], srcColor0[srcCol1][GCOMP], 489edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul srcColor1[srcCol0][GCOMP], srcColor1[srcCol1][GCOMP]); 490edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul blue = lerp_2d(colWeight, rowWeight, 491edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul srcColor0[srcCol0][BCOMP], srcColor0[srcCol1][BCOMP], 492edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul srcColor1[srcCol0][BCOMP], srcColor1[srcCol1][BCOMP]); 493edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul alpha = lerp_2d(colWeight, rowWeight, 494edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul srcColor0[srcCol0][ACOMP], srcColor0[srcCol1][ACOMP], 495edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul srcColor1[srcCol0][ACOMP], srcColor1[srcCol1][ACOMP]); 496edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 497edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul dstColor[dstCol][RCOMP] = red; 498edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul dstColor[dstCol][GCOMP] = green; 499edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul dstColor[dstCol][BCOMP] = blue; 500edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul dstColor[dstCol][ACOMP] = alpha; 501edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 502edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul} 503edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 504edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 505c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 506c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul/** 507edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul * Bilinear filtered blit (color only, non-integer values). 508c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul */ 509c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paulstatic void 510f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergblit_linear(struct gl_context *ctx, 511e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand struct gl_framebuffer *readFb, 512e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand struct gl_framebuffer *drawFb, 513c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 514c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1) 515c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul{ 516bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat struct gl_renderbuffer *readRb = readFb->_ColorReadBuffer; 517bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat struct gl_renderbuffer_attachment *readAtt = 518bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat &readFb->Attachment[readFb->_ColorReadBufferIndex]; 519c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 520c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint srcWidth = ABS(srcX1 - srcX0); 521c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint dstWidth = ABS(dstX1 - dstX0); 522c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint srcHeight = ABS(srcY1 - srcY0); 523c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint dstHeight = ABS(dstY1 - dstY0); 524c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 525c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint srcXpos = MIN2(srcX0, srcX1); 526c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint srcYpos = MIN2(srcY0, srcY1); 527c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint dstXpos = MIN2(dstX0, dstX1); 528c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLint dstYpos = MIN2(dstY0, dstY1); 529c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 530c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLboolean invertX = (srcX1 < srcX0) ^ (dstX1 < dstX0); 531c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul const GLboolean invertY = (srcY1 < srcY0) ^ (dstY1 < dstY0); 532c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 533c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint dstRow; 534c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 535c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint pixelSize; 536c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLvoid *srcBuffer0, *srcBuffer1; 537c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint srcBufferY0 = -1, srcBufferY1 = -1; 538c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLvoid *dstBuffer; 539c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 54071fe9437169cfdafda8814aa814bb85429fb6cfcMark Mueller mesa_format readFormat = _mesa_get_srgb_format_linear(readRb->Format); 541edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLuint bpp = _mesa_get_format_bytes(readFormat); 542edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 543edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLenum pixelType; 544edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 545edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLubyte *srcMap, *dstMap; 546edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul GLint srcRowStride, dstRowStride; 547bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GLuint i; 548edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 549edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 550edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul /* Determine datatype for resampling */ 551edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul if (_mesa_get_format_max_bits(readFormat) == 8 && 552edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul _mesa_get_format_datatype(readFormat) == GL_UNSIGNED_NORMALIZED) { 553edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul pixelType = GL_UNSIGNED_BYTE; 554c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul pixelSize = 4 * sizeof(GLubyte); 555edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 556edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul else { 557edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul pixelType = GL_FLOAT; 558c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul pixelSize = 4 * sizeof(GLfloat); 559c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 560c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 561c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul /* Allocate the src/dst row buffers. 562c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul * Keep two adjacent src rows around for bilinear sampling. 563c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul */ 56432f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg srcBuffer0 = malloc(pixelSize * srcWidth); 56532f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg srcBuffer1 = malloc(pixelSize * srcWidth); 56632f2fd1c5d6088692551c80352b7d6fa35b0cd09Kristian Høgsberg dstBuffer = malloc(pixelSize * dstWidth); 5676758498eb79287fe5d67cd5c869e9fd387f95defIan Romanick if (!srcBuffer0 || !srcBuffer1 || !dstBuffer) { 5686758498eb79287fe5d67cd5c869e9fd387f95defIan Romanick goto fail_no_memory; 569c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 570c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 571bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat for (i = 0; i < drawFb->_NumColorDrawBuffers; i++) { 57257ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul GLint idx = drawFb->_ColorDrawBufferIndexes[i]; 57357ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul struct gl_renderbuffer_attachment *drawAtt; 57457ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul struct gl_renderbuffer *drawRb; 57571fe9437169cfdafda8814aa814bb85429fb6cfcMark Mueller mesa_format drawFormat; 57657ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul 577bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (idx == -1) 578bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat continue; 57957ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul 580bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat drawAtt = &drawFb->Attachment[idx]; 581bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat drawRb = drawAtt->Renderbuffer; 58257ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul if (!drawRb) 58357ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul continue; 58457ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul 58557ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul drawFormat = _mesa_get_srgb_format_linear(drawRb->Format); 58657ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul 587bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* 588bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat * Map src / dst renderbuffers 589edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul */ 590bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if ((readRb == drawRb) || 591bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat (readAtt->Texture && drawAtt->Texture && 59257ddf1227fffbfda52c9310f9092c036ad4558b6Brian Paul (readAtt->Texture == drawAtt->Texture))) { 593bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* map whole buffer for read/write */ 594bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat ctx->Driver.MapRenderbuffer(ctx, readRb, 595bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat 0, 0, readRb->Width, readRb->Height, 596bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, 597bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat &srcMap, &srcRowStride); 598bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (!srcMap) { 5996758498eb79287fe5d67cd5c869e9fd387f95defIan Romanick goto fail_no_memory; 600bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 601bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat 602bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat dstMap = srcMap; 603bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat dstRowStride = srcRowStride; 604edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 605bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat else { 606bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* different src/dst buffers */ 607bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* XXX with a bit of work we could just map the regions to be 608bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat * read/written instead of the whole buffers. 609bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat */ 610bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat ctx->Driver.MapRenderbuffer(ctx, readRb, 611bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat 0, 0, readRb->Width, readRb->Height, 612bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GL_MAP_READ_BIT, &srcMap, &srcRowStride); 613bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (!srcMap) { 6146758498eb79287fe5d67cd5c869e9fd387f95defIan Romanick goto fail_no_memory; 615bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 616bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat ctx->Driver.MapRenderbuffer(ctx, drawRb, 617bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat 0, 0, drawRb->Width, drawRb->Height, 618bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GL_MAP_WRITE_BIT, &dstMap, &dstRowStride); 619bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (!dstMap) { 620bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat ctx->Driver.UnmapRenderbuffer(ctx, readRb); 6216758498eb79287fe5d67cd5c869e9fd387f95defIan Romanick goto fail_no_memory; 622bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 623edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 624edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 625bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat for (dstRow = 0; dstRow < dstHeight; dstRow++) { 626bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat const GLint dstY = dstYpos + dstRow; 627547a418888c455a3f5158c147a155292f398ea34Brian Paul GLfloat srcRow = (dstRow + 0.5F) / dstHeight * srcHeight - 0.5F; 628547a418888c455a3f5158c147a155292f398ea34Brian Paul GLint srcRow0 = MAX2(0, IFLOOR(srcRow)); 629bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GLint srcRow1 = srcRow0 + 1; 630bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GLfloat rowWeight = srcRow - srcRow0; /* fractional part of srcRow */ 631c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 632bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (srcRow1 == srcHeight) { 633bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* last row fudge */ 634bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcRow1 = srcRow0; 635bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat rowWeight = 0.0; 636bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 637c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 638bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (invertY) { 639bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcRow0 = srcHeight - 1 - srcRow0; 640bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcRow1 = srcHeight - 1 - srcRow1; 641bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 642c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 643bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcY0 = srcYpos + srcRow0; 644bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcY1 = srcYpos + srcRow1; 645c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 646bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* get the two source rows */ 647bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (srcY0 == srcBufferY0 && srcY1 == srcBufferY1) { 648bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* use same source row buffers again */ 649bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 650bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat else if (srcY0 == srcBufferY1) { 651bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* move buffer1 into buffer0 by swapping pointers */ 652bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GLvoid *tmp = srcBuffer0; 653bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcBuffer0 = srcBuffer1; 654bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcBuffer1 = tmp; 655bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* get y1 row */ 656bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat { 657bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GLubyte *src = srcMap + srcY1 * srcRowStride + srcXpos * bpp; 658bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (pixelType == GL_UNSIGNED_BYTE) { 659bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat _mesa_unpack_ubyte_rgba_row(readFormat, srcWidth, 660bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat src, srcBuffer1); 661bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 662bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat else { 663bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat _mesa_unpack_rgba_row(readFormat, srcWidth, 664bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat src, srcBuffer1); 665bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 666edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 667bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcBufferY0 = srcY0; 668bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcBufferY1 = srcY1; 669bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 670bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat else { 671bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* get both new rows */ 672bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat { 673bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GLubyte *src0 = srcMap + srcY0 * srcRowStride + srcXpos * bpp; 674bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GLubyte *src1 = srcMap + srcY1 * srcRowStride + srcXpos * bpp; 675bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (pixelType == GL_UNSIGNED_BYTE) { 676bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat _mesa_unpack_ubyte_rgba_row(readFormat, srcWidth, 677bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat src0, srcBuffer0); 678bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat _mesa_unpack_ubyte_rgba_row(readFormat, srcWidth, 679bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat src1, srcBuffer1); 680bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 681bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat else { 682bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat _mesa_unpack_rgba_row(readFormat, srcWidth, src0, srcBuffer0); 683bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat _mesa_unpack_rgba_row(readFormat, srcWidth, src1, srcBuffer1); 684bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 685edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 686bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcBufferY0 = srcY0; 687bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat srcBufferY1 = srcY1; 688bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 689bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat 690bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (pixelType == GL_UNSIGNED_BYTE) { 691bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat resample_linear_row_ub(srcWidth, dstWidth, srcBuffer0, srcBuffer1, 692bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat dstBuffer, invertX, rowWeight); 693bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 694bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat else { 695bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat resample_linear_row_float(srcWidth, dstWidth, srcBuffer0, srcBuffer1, 696bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat dstBuffer, invertX, rowWeight); 697bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat } 698bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat 699bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat /* store pixel row in destination */ 700edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul { 701bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat GLubyte *dst = dstMap + dstY * dstRowStride + dstXpos * bpp; 702edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul if (pixelType == GL_UNSIGNED_BYTE) { 703bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat _mesa_pack_ubyte_rgba_row(drawFormat, dstWidth, dstBuffer, dst); 704edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 705edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul else { 706bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat _mesa_pack_float_rgba_row(drawFormat, dstWidth, dstBuffer, dst); 707edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 708edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 709c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 710c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 711bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat ctx->Driver.UnmapRenderbuffer(ctx, readRb); 712bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat if (drawRb != readRb) { 713bed997dabaada5e7c8081db08f93a6f1b5932e8bAnuj Phogat ctx->Driver.UnmapRenderbuffer(ctx, drawRb); 714edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul } 715c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 7166758498eb79287fe5d67cd5c869e9fd387f95defIan Romanick 717a27c6e1aea1d048e0c701ca59c3c5bcf12b69d7bIan Romanick free(srcBuffer0); 718a27c6e1aea1d048e0c701ca59c3c5bcf12b69d7bIan Romanick free(srcBuffer1); 719a27c6e1aea1d048e0c701ca59c3c5bcf12b69d7bIan Romanick free(dstBuffer); 720a27c6e1aea1d048e0c701ca59c3c5bcf12b69d7bIan Romanick return; 721a27c6e1aea1d048e0c701ca59c3c5bcf12b69d7bIan Romanick 7226758498eb79287fe5d67cd5c869e9fd387f95defIan Romanickfail_no_memory: 7236758498eb79287fe5d67cd5c869e9fd387f95defIan Romanick free(srcBuffer0); 7246758498eb79287fe5d67cd5c869e9fd387f95defIan Romanick free(srcBuffer1); 7256758498eb79287fe5d67cd5c869e9fd387f95defIan Romanick free(dstBuffer); 7266758498eb79287fe5d67cd5c869e9fd387f95defIan Romanick _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBlitFramebuffer"); 727c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul} 728c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 729edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 730edca96547a2063c38d65a96e80fe6ad7144b5796Brian Paul 731c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul/** 7321eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul * Software fallback for glBlitFramebufferEXT(). 7331eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul */ 7341eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paulvoid 735f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_swrast_BlitFramebuffer(struct gl_context *ctx, 736e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand struct gl_framebuffer *readFb, 737e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand struct gl_framebuffer *drawFb, 738c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 739c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 740c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLbitfield mask, GLenum filter) 7411eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul{ 742b15334035177fbb031f000583ef7cb31f68b248cBrian Paul static const GLbitfield buffers[3] = { 743c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GL_COLOR_BUFFER_BIT, 744c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GL_DEPTH_BUFFER_BIT, 745c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GL_STENCIL_BUFFER_BIT 746c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul }; 747fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt static const GLenum buffer_enums[3] = { 748fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt GL_COLOR, 749fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt GL_DEPTH, 750fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt GL_STENCIL, 751fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt }; 752c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul GLint i; 753c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 7548ed42ddd7d31b6c9c65c735ad27ca2873859129eAnuj Phogat /* Page 679 of OpenGL 4.4 spec says: 7558ed42ddd7d31b6c9c65c735ad27ca2873859129eAnuj Phogat * "Added BlitFramebuffer to commands affected by conditional rendering in 7568ed42ddd7d31b6c9c65c735ad27ca2873859129eAnuj Phogat * section 10.10 (Bug 9562)." 7578ed42ddd7d31b6c9c65c735ad27ca2873859129eAnuj Phogat */ 7588ed42ddd7d31b6c9c65c735ad27ca2873859129eAnuj Phogat if (!_mesa_check_conditional_render(ctx)) 7598ed42ddd7d31b6c9c65c735ad27ca2873859129eAnuj Phogat return; /* Do not blit */ 7608ed42ddd7d31b6c9c65c735ad27ca2873859129eAnuj Phogat 761e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand if (!_mesa_clip_blit(ctx, readFb, drawFb, &srcX0, &srcY0, &srcX1, &srcY1, 762727b2d747e13fed78bf62cfbf4a31427eed0ef29Brian Paul &dstX0, &dstY0, &dstX1, &dstY1)) { 763c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul return; 764c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 765c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 76622e806f57013b2c116b5bfab228e0f28e25198f4Brian Paul if (SWRAST_CONTEXT(ctx)->NewState) 76722e806f57013b2c116b5bfab228e0f28e25198f4Brian Paul _swrast_validate_derived(ctx); 76822e806f57013b2c116b5bfab228e0f28e25198f4Brian Paul 769fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt /* First, try covering whatever buffers possible using the fast 1:1 copy 770fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt * path. 771fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt */ 772c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul if (srcX1 - srcX0 == dstX1 - dstX0 && 773c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcY1 - srcY0 == dstY1 - dstY0 && 774c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcX0 < srcX1 && 775c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul srcY0 < srcY1 && 776c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dstX0 < dstX1 && 777c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul dstY0 < dstY1) { 778c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul for (i = 0; i < 3; i++) { 779c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul if (mask & buffers[i]) { 780e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand if (swrast_fast_copy_pixels(ctx, 781e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand readFb, drawFb, 782e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand srcX0, srcY0, 783e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand srcX1 - srcX0, srcY1 - srcY0, 784e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand dstX0, dstY0, 785e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand buffer_enums[i])) { 786e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand mask &= ~buffers[i]; 787e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand } 788e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand } 789c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 790fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt 791fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt if (!mask) 792e9b86cb5d66867b66c6d453d7bd60bd56fe6587dLaura Ekstrand return; 793c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 794fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt 795fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt if (filter == GL_NEAREST) { 796fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt for (i = 0; i < 3; i++) { 797e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand if (mask & buffers[i]) { 798e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand blit_nearest(ctx, readFb, drawFb, srcX0, srcY0, srcX1, srcY1, 799e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand dstX0, dstY0, dstX1, dstY1, buffers[i]); 800e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand } 801c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 802fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt } 803fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt else { 804fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt ASSERT(filter == GL_LINEAR); 805fb5252a3518dadd51e88e87382e6510998e9e2f4Eric Anholt if (mask & GL_COLOR_BUFFER_BIT) { /* depth/stencil not allowed */ 806e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand blit_linear(ctx, readFb, drawFb, srcX0, srcY0, srcX1, srcY1, 807e187c2f5432466c7b49dba266026fb9b01f5f667Laura Ekstrand dstX0, dstY0, dstX1, dstY1); 808c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 809c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul } 810c241d3b06a5c996cb8415a6ada23288621c1d254Brian Paul 8111eca891dbe39a4aad7a6ed267ce7cd55589073feBrian Paul} 812