1e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell/* 2e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Mesa 3-D graphics library 3a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * Version: 6.5.2 422144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * 5a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. 622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * 7e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a 8e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * copy of this software and associated documentation files (the "Software"), 9e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * to deal in the Software without restriction, including without limitation 10e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * and/or sell copies of the Software, and to permit persons to whom the 12e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * Software is furnished to do so, subject to the following conditions: 1322144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * 14e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * The above copyright notice and this permission notice shall be included 15e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * in all copies or substantial portions of the Software. 1622144ab7552f0799bcfca506bf4ffa7f70a06649Gareth Hughes * 17e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell */ 24e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 25bf80e1ed620836e2ca0dd3f7d2d4cb187d17563dBrian Paul/** 26bf80e1ed620836e2ca0dd3f7d2d4cb187d17563dBrian Paul * \file swrast/s_alpha.c 27bf80e1ed620836e2ca0dd3f7d2d4cb187d17563dBrian Paul * \brief Functions to apply alpha test. 28bf80e1ed620836e2ca0dd3f7d2d4cb187d17563dBrian Paul */ 29e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 30bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/glheader.h" 31bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/context.h" 32bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/colormac.h" 33bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/macros.h" 34e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 35e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell#include "s_alpha.h" 36ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul#include "s_context.h" 37e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 38e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 39a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul#define ALPHA_TEST(ALPHA, LOOP_CODE) \ 40a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Pauldo { \ 41a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul switch (ctx->Color.AlphaFunc) { \ 42a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul case GL_LESS: \ 43a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul for (i = 0; i < n; i++) { \ 44a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul mask[i] &= (ALPHA < ref); \ 45a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul LOOP_CODE; \ 46a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul } \ 47a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul break; \ 48a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul case GL_LEQUAL: \ 49a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul for (i = 0; i < n; i++) { \ 50a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul mask[i] &= (ALPHA <= ref); \ 51a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul LOOP_CODE; \ 52a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul } \ 53a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul break; \ 54a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul case GL_GEQUAL: \ 55a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul for (i = 0; i < n; i++) { \ 56a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul mask[i] &= (ALPHA >= ref); \ 57a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul LOOP_CODE; \ 58a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul } \ 59a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul break; \ 60a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul case GL_GREATER: \ 61a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul for (i = 0; i < n; i++) { \ 62a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul mask[i] &= (ALPHA > ref); \ 63a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul LOOP_CODE; \ 64a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul } \ 65a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul break; \ 66a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul case GL_NOTEQUAL: \ 67a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul for (i = 0; i < n; i++) { \ 68a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul mask[i] &= (ALPHA != ref); \ 69a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul LOOP_CODE; \ 70a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul } \ 71a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul break; \ 72a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul case GL_EQUAL: \ 73a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul for (i = 0; i < n; i++) { \ 74a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul mask[i] &= (ALPHA == ref); \ 75a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul LOOP_CODE; \ 76a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul } \ 77a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul break; \ 78a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul default: \ 79a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul _mesa_problem(ctx, "Invalid alpha test in _swrast_alpha_test" ); \ 80a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul return 0; \ 81a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul } \ 82a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul} while (0) 83a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul 84a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul 85a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul 86bf80e1ed620836e2ca0dd3f7d2d4cb187d17563dBrian Paul/** 87a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * Perform the alpha test for an array of pixels. 88a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * For pixels that fail the test, mask[i] will be set to 0. 89a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * \return 0 if all pixels in the span failed the alpha test, 90a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * 1 if one or more pixels passed the alpha test. 912ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul */ 922ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian PaulGLint 93f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_swrast_alpha_test(const struct gl_context *ctx, SWspan *span) 942ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul{ 95ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul const GLuint n = span->end; 9677df88727cb0a423dd5cb41498c2302d9df4fce7Brian Paul GLubyte *mask = span->array->mask; 97ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul GLuint i; 982ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul 99a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul if (ctx->Color.AlphaFunc == GL_ALWAYS) { 100a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul /* do nothing */ 101a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul return 1; 102a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul } 103a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul else if (ctx->Color.AlphaFunc == GL_NEVER) { 104a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul /* All pixels failed - caller should check for this return value and 105a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul * act accordingly. 106a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul */ 107a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul span->writeAll = GL_FALSE; 108a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul return 0; 109a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul } 110fc80ad6e62fb2b53d53756593099330477a44c52Brian Paul 111ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul if (span->arrayMask & SPAN_RGBA) { 112a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul /* Use array's alpha values */ 113a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul if (span->array->ChanType == GL_UNSIGNED_BYTE) { 1149e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLubyte (*rgba)[4] = span->array->rgba8; 115a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul GLubyte ref; 116a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul CLAMPED_FLOAT_TO_UBYTE(ref, ctx->Color.AlphaRef); 117a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul ALPHA_TEST(rgba[i][ACOMP], ;); 118a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul } 119a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul else if (span->array->ChanType == GL_UNSIGNED_SHORT) { 1209e8a961dd7d7b717a9fb4ecdea1c1b60ea355efeBrian GLushort (*rgba)[4] = span->array->rgba16; 121a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul GLushort ref; 122a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul CLAMPED_FLOAT_TO_USHORT(ref, ctx->Color.AlphaRef); 123a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul ALPHA_TEST(rgba[i][ACOMP], ;); 124a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul } 125a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul else { 126f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; 127a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul const GLfloat ref = ctx->Color.AlphaRef; 128a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul ALPHA_TEST(rgba[i][ACOMP], ;); 129ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul } 130ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul } 131ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul else { 132a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul /* Interpolate alpha values */ 133ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul ASSERT(span->interpMask & SPAN_RGBA); 134a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul if (span->array->ChanType == GL_UNSIGNED_BYTE) { 135a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul const GLfixed alphaStep = span->alphaStep; 136a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul GLfixed alpha = span->alpha; 137a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul GLubyte ref; 138a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul CLAMPED_FLOAT_TO_UBYTE(ref, ctx->Color.AlphaRef); 139cd5a623386f55704e5f9ac492fe397d75ac03945Brian Paul ALPHA_TEST(FixedToInt(alpha), alpha += alphaStep); 140ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul } 141a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul else if (span->array->ChanType == GL_UNSIGNED_SHORT) { 142a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul const GLfixed alphaStep = span->alphaStep; 143a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul GLfixed alpha = span->alpha; 144a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul GLushort ref; 145a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul CLAMPED_FLOAT_TO_USHORT(ref, ctx->Color.AlphaRef); 146cd5a623386f55704e5f9ac492fe397d75ac03945Brian Paul ALPHA_TEST(FixedToInt(alpha), alpha += alphaStep); 147a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul } 148a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul else { 149714d3ec9bc3e9085fe7caf522dc001198aaf685cBrian Paul const GLfloat alphaStep = FixedToFloat(span->alphaStep); 150714d3ec9bc3e9085fe7caf522dc001198aaf685cBrian Paul GLfloat alpha = FixedToFloat(span->alpha); 151a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul const GLfloat ref = ctx->Color.AlphaRef; 152a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul ALPHA_TEST(alpha, alpha += alphaStep); 153ceb39f4f8dc4863fde17d668c752533a2184476eBrian Paul } 1542ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul } 1552ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul 1562ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul span->writeAll = GL_FALSE; 157e3a051e0538a605551f4d58294c94f5eb00ed07fKeith Whitwell 158a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul /* XXX examine mask[] values? */ 159a50b7dbc3ba1db8c92b4bbb4f7f06de8d6c039c4Brian Paul return 1; 1602ef866d1fc0a5cc5ef8543d65744dfd4da4dbbafBrian Paul} 161