1afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach/* 2afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach * Mesa 3-D graphics library 35e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen * 4e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. 55e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen * 6afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach * Permission is hereby granted, free of charge, to any person obtaining a 7afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach * copy of this software and associated documentation files (the "Software"), 8afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach * to deal in the Software without restriction, including without limitation 9afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach * and/or sell copies of the Software, and to permit persons to whom the 11afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach * Software is furnished to do so, subject to the following conditions: 125e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen * 13afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach * The above copyright notice and this permission notice shall be included 14afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach * in all copies or substantial portions of the Software. 155e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen * 16afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach * 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. 23afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach */ 24afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach 25fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul#include "glheader.h" 26afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach#include "accum.h" 27122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul#include "condrender.h" 28afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach#include "context.h" 29122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul#include "format_unpack.h" 30122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul#include "format_pack.h" 313c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul#include "imports.h" 32ebb248aa5c018dc676d389221d76ed329059789eBrian Paul#include "macros.h" 33ea39f042c378c234b573ceead4c5194020d949c4Brian Paul#include "state.h" 345e3bc0c2a2bcdf59949410f94c9b705fc1281ce8Jouk Jansen#include "mtypes.h" 352cf44390d1e819f23e1d7ceb3199276c9148c647Chia-I Wu#include "main/dispatch.h" 36a833ff0f53da6e365d917bb0081d909a809b6ec1Chia-I Wu 37a833ff0f53da6e365d917bb0081d909a809b6ec1Chia-I Wu 38c40d1dd62dd9bcbb97128e37a75d991a8d3b2d8cKendall Bennettvoid GLAPIENTRY 39fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul_mesa_ClearAccum( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha ) 40afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach{ 41cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell GLfloat tmp[4]; 42fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul GET_CURRENT_CONTEXT(ctx); 43afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach 447c276329e815c84ea2403bb08c44ff60179c0cd6Brian Paul tmp[0] = CLAMP( red, -1.0F, 1.0F ); 457c276329e815c84ea2403bb08c44ff60179c0cd6Brian Paul tmp[1] = CLAMP( green, -1.0F, 1.0F ); 467c276329e815c84ea2403bb08c44ff60179c0cd6Brian Paul tmp[2] = CLAMP( blue, -1.0F, 1.0F ); 477c276329e815c84ea2403bb08c44ff60179c0cd6Brian Paul tmp[3] = CLAMP( alpha, -1.0F, 1.0F ); 48cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell 49cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell if (TEST_EQ_4V(tmp, ctx->Accum.ClearColor)) 50cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell return; 51afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach 52cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell COPY_4FV( ctx->Accum.ClearColor, tmp ); 53cab974cf6c2dbfbf5dd5d291e1aae0f8eeb34290Keith Whitwell} 54afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach 553a0e0b284fd74aa6cb7b380a59cf20e62f8f8ffdBrian Paul 56f7fa946d1da96178e63e42dd8d8739d3e0f66e1dPaul Berryvoid GLAPIENTRY 57fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul_mesa_Accum( GLenum op, GLfloat value ) 58afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach{ 59fbd8f212c3866ec98c1d8c9d3db3ddb7e7c479a5Brian Paul GET_CURRENT_CONTEXT(ctx); 60a9754793dab4b24c09cae21c29f902ce0e53319aEric Anholt FLUSH_VERTICES(ctx, 0); 61afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach 62e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul switch (op) { 63e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul case GL_ADD: 64e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul case GL_MULT: 65e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul case GL_ACCUM: 66e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul case GL_LOAD: 67e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul case GL_RETURN: 68e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul /* OK */ 69e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul break; 70e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul default: 71e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul _mesa_error(ctx, GL_INVALID_ENUM, "glAccum(op)"); 72e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul return; 73e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul } 74e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 75b4269c07f8fe51912a01a36ff6239f1565d0639cBrian Paul if (ctx->DrawBuffer->Visual.haveAccumBuffer == 0) { 76dbd0fa920effdceacec34fa0d5ae9ab7a2f09614Brian Paul _mesa_error(ctx, GL_INVALID_OPERATION, "glAccum(no accum buffer)"); 77dbd0fa920effdceacec34fa0d5ae9ab7a2f09614Brian Paul return; 78dbd0fa920effdceacec34fa0d5ae9ab7a2f09614Brian Paul } 79dbd0fa920effdceacec34fa0d5ae9ab7a2f09614Brian Paul 8078b3b667b5fc7dbd7f723682f8ffaa0091286abbBrian Paul if (ctx->DrawBuffer != ctx->ReadBuffer) { 819b8059e53610d6d9d217f331b0671354e62ad47fBrian Paul /* See GLX_SGI_make_current_read or WGL_ARB_make_current_read, 829b8059e53610d6d9d217f331b0671354e62ad47fBrian Paul * or GL_EXT_framebuffer_blit. 839b8059e53610d6d9d217f331b0671354e62ad47fBrian Paul */ 8478b3b667b5fc7dbd7f723682f8ffaa0091286abbBrian Paul _mesa_error(ctx, GL_INVALID_OPERATION, 8578b3b667b5fc7dbd7f723682f8ffaa0091286abbBrian Paul "glAccum(different read/draw buffers)"); 8678b3b667b5fc7dbd7f723682f8ffaa0091286abbBrian Paul return; 8778b3b667b5fc7dbd7f723682f8ffaa0091286abbBrian Paul } 8878b3b667b5fc7dbd7f723682f8ffaa0091286abbBrian Paul 89afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach if (ctx->NewState) 90d95000da2fdad78f25618fe9703f23806587b65aBrian Paul _mesa_update_state(ctx); 91afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach 92d95000da2fdad78f25618fe9703f23806587b65aBrian Paul if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { 93d95000da2fdad78f25618fe9703f23806587b65aBrian Paul _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, 94d95000da2fdad78f25618fe9703f23806587b65aBrian Paul "glAccum(incomplete framebuffer)"); 953a0e0b284fd74aa6cb7b380a59cf20e62f8f8ffdBrian Paul return; 963a0e0b284fd74aa6cb7b380a59cf20e62f8f8ffdBrian Paul } 973a0e0b284fd74aa6cb7b380a59cf20e62f8f8ffdBrian Paul 98aee96806f049c17384a8edc11acce76257d98a57Paul Berry if (ctx->RasterDiscard) 99e7c2b711a3b01cbeb0bf93d5442599457e7f8f51Eric Anholt return; 100e7c2b711a3b01cbeb0bf93d5442599457e7f8f51Eric Anholt 101d95000da2fdad78f25618fe9703f23806587b65aBrian Paul if (ctx->RenderMode == GL_RENDER) { 102122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul _mesa_accum(ctx, op, value); 103afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach } 104afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cJochen Gerlach} 1056dc85575000127630489b407c50a4b3ea87c9acbKeith Whitwell 106e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul 107122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul/** 108122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul * Clear the accumulation buffer by mapping the renderbuffer and 109122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul * writing the clear color to it. Called by the driver's implementation 110122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul * of the glClear function. 111122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul */ 112122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paulvoid 113122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul_mesa_clear_accum_buffer(struct gl_context *ctx) 114122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul{ 115122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul GLuint x, y, width, height; 116122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul GLubyte *accMap; 117122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul GLint accRowStride; 118122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul struct gl_renderbuffer *accRb; 119122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 120122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul if (!ctx->DrawBuffer) 121122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul return; 122122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 123122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul accRb = ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer; 124122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul if (!accRb) 125122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul return; /* missing accum buffer, not an error */ 126122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 127122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul /* bounds, with scissor */ 128122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul x = ctx->DrawBuffer->_Xmin; 129122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul y = ctx->DrawBuffer->_Ymin; 130122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; 131122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; 132122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 133122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul ctx->Driver.MapRenderbuffer(ctx, accRb, x, y, width, height, 134122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul GL_MAP_WRITE_BIT, &accMap, &accRowStride); 135122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 136122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul if (!accMap) { 137122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum"); 138122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul return; 139122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 140122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 1418b47b6bc32b595ee1a37cde279d44a6ac84403c0Mark Mueller if (accRb->Format == MESA_FORMAT_RGBA_SNORM16) { 142122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul const GLshort clearR = FLOAT_TO_SHORT(ctx->Accum.ClearColor[0]); 143122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul const GLshort clearG = FLOAT_TO_SHORT(ctx->Accum.ClearColor[1]); 144122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul const GLshort clearB = FLOAT_TO_SHORT(ctx->Accum.ClearColor[2]); 145122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul const GLshort clearA = FLOAT_TO_SHORT(ctx->Accum.ClearColor[3]); 146122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul GLuint i, j; 147122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 148122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul for (j = 0; j < height; j++) { 149122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul GLshort *row = (GLshort *) accMap; 150122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 151122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul for (i = 0; i < width; i++) { 152122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul row[i * 4 + 0] = clearR; 153122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul row[i * 4 + 1] = clearG; 154122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul row[i * 4 + 2] = clearB; 155122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul row[i * 4 + 3] = clearA; 156122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 157122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul accMap += accRowStride; 158122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 159122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 160122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul else { 161122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul /* other types someday? */ 162122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul _mesa_warning(ctx, "unexpected accum buffer type"); 163122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 164122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 165122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul ctx->Driver.UnmapRenderbuffer(ctx, accRb); 166122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul} 167122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 168122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 169122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul/** 170122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul * if (bias) 171122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul * Accum += value 172122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul * else 173122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul * Accum *= value 174122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul */ 175122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paulstatic void 176122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paulaccum_scale_or_bias(struct gl_context *ctx, GLfloat value, 177122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul GLint xpos, GLint ypos, GLint width, GLint height, 178122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul GLboolean bias) 179122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul{ 180122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul struct gl_renderbuffer *accRb = 181122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer; 182122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul GLubyte *accMap; 183122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul GLint accRowStride; 184122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 185122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul assert(accRb); 186122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 187122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul ctx->Driver.MapRenderbuffer(ctx, accRb, xpos, ypos, width, height, 188122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, 189122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul &accMap, &accRowStride); 190122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 191122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul if (!accMap) { 192122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum"); 193122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul return; 194122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 195122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 1968b47b6bc32b595ee1a37cde279d44a6ac84403c0Mark Mueller if (accRb->Format == MESA_FORMAT_RGBA_SNORM16) { 197122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul const GLshort incr = (GLshort) (value * 32767.0f); 19803503daa2118c760fb2963c6ac5a813f58941fa1Brian Paul GLint i, j; 199122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul if (bias) { 200122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul for (j = 0; j < height; j++) { 201122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul GLshort *acc = (GLshort *) accMap; 202122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul for (i = 0; i < 4 * width; i++) { 203122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul acc[i] += incr; 204122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 205122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul accMap += accRowStride; 206122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 207122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 208122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul else { 209122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul /* scale */ 210122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul for (j = 0; j < height; j++) { 211122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul GLshort *acc = (GLshort *) accMap; 212122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul for (i = 0; i < 4 * width; i++) { 213122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul acc[i] = (GLshort) (acc[i] * value); 214122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 215122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul accMap += accRowStride; 216122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 217122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 218122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 219122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul else { 220122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul /* other types someday? */ 221122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 222122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 223122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul ctx->Driver.UnmapRenderbuffer(ctx, accRb); 224122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul} 225122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 226122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 227122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul/** 228122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul * if (load) 229122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul * Accum = ColorBuf * value 230122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul * else 231122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul * Accum += ColorBuf * value 232122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul */ 233122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paulstatic void 234122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paulaccum_or_load(struct gl_context *ctx, GLfloat value, 235122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul GLint xpos, GLint ypos, GLint width, GLint height, 236122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul GLboolean load) 237122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul{ 238122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul struct gl_renderbuffer *accRb = 239122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer; 240122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul struct gl_renderbuffer *colorRb = ctx->ReadBuffer->_ColorReadBuffer; 241122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul GLubyte *accMap, *colorMap; 242122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul GLint accRowStride, colorRowStride; 243122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul GLbitfield mappingFlags; 244122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 245122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul if (!colorRb) { 246122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul /* no read buffer - OK */ 247122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul return; 248122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 249122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 250122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul assert(accRb); 251122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 252122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul mappingFlags = GL_MAP_WRITE_BIT; 253122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul if (!load) /* if we're accumulating */ 254122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul mappingFlags |= GL_MAP_READ_BIT; 255122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 256122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul /* Map accum buffer */ 257122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul ctx->Driver.MapRenderbuffer(ctx, accRb, xpos, ypos, width, height, 258122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul mappingFlags, &accMap, &accRowStride); 259122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul if (!accMap) { 260122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum"); 261122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul return; 262122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 263122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 264122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul /* Map color buffer */ 265122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul ctx->Driver.MapRenderbuffer(ctx, colorRb, xpos, ypos, width, height, 266122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul GL_MAP_READ_BIT, 267122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul &colorMap, &colorRowStride); 268122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul if (!colorMap) { 269122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul ctx->Driver.UnmapRenderbuffer(ctx, accRb); 270122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum"); 271122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul return; 272122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 273122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 2748b47b6bc32b595ee1a37cde279d44a6ac84403c0Mark Mueller if (accRb->Format == MESA_FORMAT_RGBA_SNORM16) { 275122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul const GLfloat scale = value * 32767.0f; 27603503daa2118c760fb2963c6ac5a813f58941fa1Brian Paul GLint i, j; 277122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul GLfloat (*rgba)[4]; 278122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 2792b7a972e3f36bfcdc6fbe2b59d7ffdcde49c9405Matt Turner rgba = malloc(width * 4 * sizeof(GLfloat)); 280122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul if (rgba) { 281122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul for (j = 0; j < height; j++) { 282122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul GLshort *acc = (GLshort *) accMap; 283122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 284122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul /* read colors from source color buffer */ 285122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul _mesa_unpack_rgba_row(colorRb->Format, width, colorMap, rgba); 286122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 287122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul if (load) { 288122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul for (i = 0; i < width; i++) { 289122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul acc[i * 4 + 0] = (GLshort) (rgba[i][RCOMP] * scale); 290122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul acc[i * 4 + 1] = (GLshort) (rgba[i][GCOMP] * scale); 291122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul acc[i * 4 + 2] = (GLshort) (rgba[i][BCOMP] * scale); 292122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul acc[i * 4 + 3] = (GLshort) (rgba[i][ACOMP] * scale); 293122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 294122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 295122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul else { 296122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul /* accumulate */ 297122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul for (i = 0; i < width; i++) { 298122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul acc[i * 4 + 0] += (GLshort) (rgba[i][RCOMP] * scale); 299122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul acc[i * 4 + 1] += (GLshort) (rgba[i][GCOMP] * scale); 300122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul acc[i * 4 + 2] += (GLshort) (rgba[i][BCOMP] * scale); 301122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul acc[i * 4 + 3] += (GLshort) (rgba[i][ACOMP] * scale); 302122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 303122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 304122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 305122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul colorMap += colorRowStride; 306122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul accMap += accRowStride; 307122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 308122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 309122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul free(rgba); 310122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 311122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul else { 312122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum"); 313122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 314122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 315122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul else { 316122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul /* other types someday? */ 317122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 318122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 319122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul ctx->Driver.UnmapRenderbuffer(ctx, accRb); 320122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul ctx->Driver.UnmapRenderbuffer(ctx, colorRb); 321122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul} 322122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 323122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 324122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul/** 325122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul * ColorBuffer = Accum * value 326122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul */ 327122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paulstatic void 328122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paulaccum_return(struct gl_context *ctx, GLfloat value, 329122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul GLint xpos, GLint ypos, GLint width, GLint height) 330122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul{ 331122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul struct gl_framebuffer *fb = ctx->DrawBuffer; 332122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul struct gl_renderbuffer *accRb = fb->Attachment[BUFFER_ACCUM].Renderbuffer; 333122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul GLubyte *accMap, *colorMap; 334122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul GLint accRowStride, colorRowStride; 335122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul GLuint buffer; 336122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 337122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul /* Map accum buffer */ 338122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul ctx->Driver.MapRenderbuffer(ctx, accRb, xpos, ypos, width, height, 339122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul GL_MAP_READ_BIT, 340122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul &accMap, &accRowStride); 341122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul if (!accMap) { 342122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum"); 343122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul return; 344122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 345122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 346122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul /* Loop over destination buffers */ 347122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul for (buffer = 0; buffer < fb->_NumColorDrawBuffers; buffer++) { 348122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul struct gl_renderbuffer *colorRb = fb->_ColorDrawBuffers[buffer]; 349122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul const GLboolean masking = (!ctx->Color.ColorMask[buffer][RCOMP] || 350122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul !ctx->Color.ColorMask[buffer][GCOMP] || 351122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul !ctx->Color.ColorMask[buffer][BCOMP] || 352122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul !ctx->Color.ColorMask[buffer][ACOMP]); 353122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul GLbitfield mappingFlags = GL_MAP_WRITE_BIT; 354122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 355122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul if (masking) 356122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul mappingFlags |= GL_MAP_READ_BIT; 357122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 358122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul /* Map color buffer */ 359122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul ctx->Driver.MapRenderbuffer(ctx, colorRb, xpos, ypos, width, height, 360122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul mappingFlags, &colorMap, &colorRowStride); 361122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul if (!colorMap) { 362122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum"); 363122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul continue; 364122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 365122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 3668b47b6bc32b595ee1a37cde279d44a6ac84403c0Mark Mueller if (accRb->Format == MESA_FORMAT_RGBA_SNORM16) { 367122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul const GLfloat scale = value / 32767.0f; 368122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul GLint i, j; 369122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul GLfloat (*rgba)[4], (*dest)[4]; 370122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 3712b7a972e3f36bfcdc6fbe2b59d7ffdcde49c9405Matt Turner rgba = malloc(width * 4 * sizeof(GLfloat)); 3722b7a972e3f36bfcdc6fbe2b59d7ffdcde49c9405Matt Turner dest = malloc(width * 4 * sizeof(GLfloat)); 373122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 374122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul if (rgba && dest) { 375122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul for (j = 0; j < height; j++) { 376122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul GLshort *acc = (GLshort *) accMap; 377122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 378122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul for (i = 0; i < width; i++) { 379122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul rgba[i][0] = acc[i * 4 + 0] * scale; 380122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul rgba[i][1] = acc[i * 4 + 1] * scale; 381122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul rgba[i][2] = acc[i * 4 + 2] * scale; 382122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul rgba[i][3] = acc[i * 4 + 3] * scale; 383122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 384122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 385122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul if (masking) { 386122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 387122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul /* get existing colors from dest buffer */ 388122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul _mesa_unpack_rgba_row(colorRb->Format, width, colorMap, dest); 389122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 390122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul /* use the dest colors where mask[channel] = 0 */ 391122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul if (ctx->Color.ColorMask[buffer][RCOMP] == 0) { 392122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul for (i = 0; i < width; i++) 393122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul rgba[i][RCOMP] = dest[i][RCOMP]; 394122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 395122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul if (ctx->Color.ColorMask[buffer][GCOMP] == 0) { 396122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul for (i = 0; i < width; i++) 397122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul rgba[i][GCOMP] = dest[i][GCOMP]; 398122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 399122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul if (ctx->Color.ColorMask[buffer][BCOMP] == 0) { 400122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul for (i = 0; i < width; i++) 401122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul rgba[i][BCOMP] = dest[i][BCOMP]; 402122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 403122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul if (ctx->Color.ColorMask[buffer][ACOMP] == 0) { 404122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul for (i = 0; i < width; i++) 405122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul rgba[i][ACOMP] = dest[i][ACOMP]; 406122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 407122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 408122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 409122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul _mesa_pack_float_rgba_row(colorRb->Format, width, 410122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul (const GLfloat (*)[4]) rgba, colorMap); 411122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 412122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul accMap += accRowStride; 413122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul colorMap += colorRowStride; 414122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 415122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 416122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul else { 417122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum"); 418122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 419122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul free(rgba); 420122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul free(dest); 421122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 422122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul else { 423122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul /* other types someday? */ 424122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 425122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 426122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul ctx->Driver.UnmapRenderbuffer(ctx, colorRb); 427122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 428122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 429122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul ctx->Driver.UnmapRenderbuffer(ctx, accRb); 430122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul} 431122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 432122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 433122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 434122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul/** 435122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul * Software fallback for glAccum. A hardware driver that supports 436122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul * signed 16-bit color channels could implement hardware accumulation 437122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul * operations, but no driver does so at this time. 438122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul */ 439122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paulvoid 440122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul_mesa_accum(struct gl_context *ctx, GLenum op, GLfloat value) 441122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul{ 442122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul GLint xpos, ypos, width, height; 443122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 444122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul if (!ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer) { 445122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul _mesa_warning(ctx, "Calling glAccum() without an accumulation buffer"); 446122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul return; 447122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 448122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 449122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul if (!_mesa_check_conditional_render(ctx)) 450122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul return; 451122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 452122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul xpos = ctx->DrawBuffer->_Xmin; 453122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul ypos = ctx->DrawBuffer->_Ymin; 454122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; 455122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; 456122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul 457122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul switch (op) { 458122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul case GL_ADD: 459122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul if (value != 0.0F) { 460122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul accum_scale_or_bias(ctx, value, xpos, ypos, width, height, GL_TRUE); 461122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 462122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul break; 463122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul case GL_MULT: 464122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul if (value != 1.0F) { 465122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul accum_scale_or_bias(ctx, value, xpos, ypos, width, height, GL_FALSE); 466122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 467122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul break; 468122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul case GL_ACCUM: 469122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul if (value != 0.0F) { 470122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul accum_or_load(ctx, value, xpos, ypos, width, height, GL_FALSE); 471122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 472122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul break; 473122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul case GL_LOAD: 474122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul accum_or_load(ctx, value, xpos, ypos, width, height, GL_TRUE); 475122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul break; 476122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul case GL_RETURN: 477122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul accum_return(ctx, value, xpos, ypos, width, height); 478122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul break; 479122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul default: 480122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul _mesa_problem(ctx, "invalid mode in _mesa_accum()"); 481122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul break; 482122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul } 483122c6768e3d4c1d1b57203eca70569f9301baab5Brian Paul} 4848fe6755ed52acfb88a7a787c3406b64fcdd80e6eBrian Paul 4858fe6755ed52acfb88a7a787c3406b64fcdd80e6eBrian Paul 4868fe6755ed52acfb88a7a787c3406b64fcdd80e6eBrian Paulvoid 4878fe6755ed52acfb88a7a787c3406b64fcdd80e6eBrian Paul_mesa_init_accum( struct gl_context *ctx ) 4888fe6755ed52acfb88a7a787c3406b64fcdd80e6eBrian Paul{ 4898fe6755ed52acfb88a7a787c3406b64fcdd80e6eBrian Paul /* Accumulate buffer group */ 4908fe6755ed52acfb88a7a787c3406b64fcdd80e6eBrian Paul ASSIGN_4V( ctx->Accum.ClearColor, 0.0, 0.0, 0.0, 0.0 ); 4918fe6755ed52acfb88a7a787c3406b64fcdd80e6eBrian Paul} 492