12cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/* 22cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Mesa 3-D graphics library 32d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul * Version: 7.5 42cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * 52d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 62d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 72cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * 82cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Permission is hereby granted, free of charge, to any person obtaining a 92cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * copy of this software and associated documentation files (the "Software"), 102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * to deal in the Software without restriction, including without limitation 112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * the rights to use, copy, modify, merge, publish, distribute, sublicense, 122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * and/or sell copies of the Software, and to permit persons to whom the 132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Software is furnished to do so, subject to the following conditions: 142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * 152cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * The above copyright notice and this permission notice shall be included 162cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * in all copies or substantial portions of the Software. 172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * 182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 27bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/glheader.h" 28bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/context.h" 29bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/colormac.h" 30bbd287103dad776d8a45c87c4e51fbc26d9b80d5Brian Paul#include "main/imports.h" 311c131752c3e07ef91f49d4970dafca6d26585334Brian Paul#include "main/pixeltransfer.h" 32cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen#include "main/samplerobj.h" 33ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/prog_instruction.h" 342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#include "s_context.h" 362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul#include "s_texcombine.h" 372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/** 400695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul * Pointer to array of float[4] 410695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul * This type makes the code below more concise and avoids a lot of casting. 420695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul */ 430695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paultypedef float (*float4_array)[4]; 440695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul 450695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul 460695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul/** 470695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul * Return array of texels for given unit. 480695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul */ 499520f483b8f1e45fa474674b415554988de5d8d3Brian Paulstatic inline float4_array 501b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paulget_texel_array(SWcontext *swrast, GLuint unit) 510695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul{ 52e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger#ifdef _OPENMP 5347d88ef204b42a9220c6be3e98c92df9c9aa0860Brian Paul return (float4_array) (swrast->TexelBuffer + unit * SWRAST_MAX_WIDTH * 4 * omp_get_num_threads() + (SWRAST_MAX_WIDTH * 4 * omp_get_thread_num())); 54e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger#else 5547d88ef204b42a9220c6be3e98c92df9c9aa0860Brian Paul return (float4_array) (swrast->TexelBuffer + unit * SWRAST_MAX_WIDTH * 4); 56e411cd7b0a54d2f9b9f4cda4918aa7742ed5c2a6Andreas Fänger#endif 570695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul} 580695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul 590695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul 600695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul 610695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul/** 62bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul * Do texture application for: 63bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul * GL_EXT_texture_env_combine 64bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul * GL_ARB_texture_env_combine 65bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul * GL_EXT_texture_env_dot3 66bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul * GL_ARB_texture_env_dot3 67bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul * GL_ATI_texture_env_combine3 68bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul * GL_NV_texture_env_combine4 69bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul * conventional GL texture env modes 702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * 712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * \param ctx rendering context 72bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul * \param unit the texture combiner unit 732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * \param primary_rgba incoming fragment color array 742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * \param texelBuffer pointer to texel colors for all texture units 752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * 766ba8f0688a35ffac93bd025739aefe8e3694ca0cYuanhan Liu * \param span two fields are used in this function: 776ba8f0688a35ffac93bd025739aefe8e3694ca0cYuanhan Liu * span->end: number of fragments to process 786ba8f0688a35ffac93bd025739aefe8e3694ca0cYuanhan Liu * span->array->rgba: incoming/result fragment colors 792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulstatic void 816ba8f0688a35ffac93bd025739aefe8e3694ca0cYuanhan Liutexture_combine( struct gl_context *ctx, GLuint unit, 820695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul const float4_array primary_rgba, 830695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul const GLfloat *texelBuffer, 846ba8f0688a35ffac93bd025739aefe8e3694ca0cYuanhan Liu SWspan *span ) 852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 861b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paul SWcontext *swrast = SWRAST_CONTEXT(ctx); 872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_unit *textureUnit = &(ctx->Texture.Unit[unit]); 88933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul const struct gl_tex_env_combine_state *combine = textureUnit->_CurrentCombine; 890695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul float4_array argRGB[MAX_COMBINER_TERMS]; 900695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul float4_array argA[MAX_COMBINER_TERMS]; 91bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul const GLfloat scaleRGB = (GLfloat) (1 << combine->ScaleShiftRGB); 92bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul const GLfloat scaleA = (GLfloat) (1 << combine->ScaleShiftA); 93bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul const GLuint numArgsRGB = combine->_NumArgsRGB; 94bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul const GLuint numArgsA = combine->_NumArgsA; 95aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul float4_array ccolor[4], rgba; 96933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul GLuint i, term; 976ba8f0688a35ffac93bd025739aefe8e3694ca0cYuanhan Liu GLuint n = span->end; 986ba8f0688a35ffac93bd025739aefe8e3694ca0cYuanhan Liu GLchan (*rgbaChan)[4] = span->array->rgba; 992cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 100aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul /* alloc temp pixel buffers */ 101aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul rgba = (float4_array) malloc(4 * n * sizeof(GLfloat)); 102aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul if (!rgba) { 103aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture_combine"); 104aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul return; 105aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul } 106aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul 107aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul for (i = 0; i < numArgsRGB || i < numArgsA; i++) { 108aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul ccolor[i] = (float4_array) malloc(4 * n * sizeof(GLfloat)); 109aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul if (!ccolor[i]) { 110aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul while (i) { 111aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul free(ccolor[i]); 112aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul i--; 113aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul } 114aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture_combine"); 115c81b441ba2b8ab61d5e1f24ec7a34914c8a3b215Vinson Lee free(rgba); 116aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul return; 117aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul } 118aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul } 119aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul 120de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul for (i = 0; i < n; i++) { 121de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul rgba[i][RCOMP] = CHAN_TO_FLOAT(rgbaChan[i][RCOMP]); 122de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul rgba[i][GCOMP] = CHAN_TO_FLOAT(rgbaChan[i][GCOMP]); 123de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul rgba[i][BCOMP] = CHAN_TO_FLOAT(rgbaChan[i][BCOMP]); 124de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul rgba[i][ACOMP] = CHAN_TO_FLOAT(rgbaChan[i][ACOMP]); 125de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul } 126de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul 1272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* 1282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul printf("modeRGB 0x%x modeA 0x%x srcRGB1 0x%x srcA1 0x%x srcRGB2 0x%x srcA2 0x%x\n", 129933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul combine->ModeRGB, 130933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul combine->ModeA, 131933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul combine->SourceRGB[0], 132933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul combine->SourceA[0], 133933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul combine->SourceRGB[1], 134933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul combine->SourceA[1]); 1352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 1362cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 1372cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* 1382d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul * Do operand setup for up to 4 operands. Loop over the terms. 1392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 140bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul for (term = 0; term < numArgsRGB; term++) { 141933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul const GLenum srcRGB = combine->SourceRGB[term]; 142933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul const GLenum operandRGB = combine->OperandRGB[term]; 1432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 1442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul switch (srcRGB) { 1452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_TEXTURE: 1461b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paul argRGB[term] = get_texel_array(swrast, unit); 1472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 1482cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_PRIMARY_COLOR: 149933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul argRGB[term] = primary_rgba; 1502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 1512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_PREVIOUS: 1520695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul argRGB[term] = rgba; 1532cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 1542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_CONSTANT: 1552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul { 1560695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul float4_array c = ccolor[term]; 157de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat red = textureUnit->EnvColor[0]; 158de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat green = textureUnit->EnvColor[1]; 159de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat blue = textureUnit->EnvColor[2]; 160de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat alpha = textureUnit->EnvColor[3]; 1612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 162de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul ASSIGN_4V(c[i], red, green, blue, alpha); 1632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 1640695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul argRGB[term] = ccolor[term]; 1652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 1662cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 1672cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* GL_ATI_texture_env_combine3 allows GL_ZERO & GL_ONE as sources. 1682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 1692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_ZERO: 170de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul { 1710695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul float4_array c = ccolor[term]; 172de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul for (i = 0; i < n; i++) { 173de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul ASSIGN_4V(c[i], 0.0F, 0.0F, 0.0F, 0.0F); 174de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul } 1750695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul argRGB[term] = ccolor[term]; 176de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul } 1772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 1782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_ONE: 179de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul { 1800695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul float4_array c = ccolor[term]; 181de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul for (i = 0; i < n; i++) { 182de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul ASSIGN_4V(c[i], 1.0F, 1.0F, 1.0F, 1.0F); 183de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul } 1840695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul argRGB[term] = ccolor[term]; 185de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul } 1862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 1872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul default: 1882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* ARB_texture_env_crossbar source */ 1892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul { 1902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLuint srcUnit = srcRGB - GL_TEXTURE0; 1912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(srcUnit < ctx->Const.MaxTextureUnits); 1922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (!ctx->Texture.Unit[srcUnit]._ReallyEnabled) 193aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul goto end; 1941b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paul argRGB[term] = get_texel_array(swrast, srcUnit); 1952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 1962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 1972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 198933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul if (operandRGB != GL_SRC_COLOR) { 1990695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul float4_array src = argRGB[term]; 2000695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul float4_array dst = ccolor[term]; 2012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 202933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul /* point to new arg[term] storage */ 2030695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul argRGB[term] = ccolor[term]; 2042cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 205933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul switch (operandRGB) { 206933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul case GL_ONE_MINUS_SRC_COLOR: 2072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 208de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul dst[i][RCOMP] = 1.0F - src[i][RCOMP]; 209de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul dst[i][GCOMP] = 1.0F - src[i][GCOMP]; 210de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul dst[i][BCOMP] = 1.0F - src[i][BCOMP]; 2112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 212933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul break; 213933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul case GL_SRC_ALPHA: 2142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 215aef2e1c1dcda77b6dc5fcfd2de7c9d720effa4e7Brian Paul dst[i][RCOMP] = 216aef2e1c1dcda77b6dc5fcfd2de7c9d720effa4e7Brian Paul dst[i][GCOMP] = 2172cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul dst[i][BCOMP] = src[i][ACOMP]; 2182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 219933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul break; 220933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul case GL_ONE_MINUS_SRC_ALPHA: 2212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 222aef2e1c1dcda77b6dc5fcfd2de7c9d720effa4e7Brian Paul dst[i][RCOMP] = 223aef2e1c1dcda77b6dc5fcfd2de7c9d720effa4e7Brian Paul dst[i][GCOMP] = 224de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul dst[i][BCOMP] = 1.0F - src[i][ACOMP]; 2252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 226933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul break; 227933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul default: 228933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul _mesa_problem(ctx, "Bad operandRGB"); 2292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 2302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 2312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 2322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 2332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* 234bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul * Set up the argA[term] pointers 2352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 236bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul for (term = 0; term < numArgsA; term++) { 237933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul const GLenum srcA = combine->SourceA[term]; 238933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul const GLenum operandA = combine->OperandA[term]; 2392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 2402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul switch (srcA) { 2412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_TEXTURE: 2421b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paul argA[term] = get_texel_array(swrast, unit); 2432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 2442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_PRIMARY_COLOR: 245933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul argA[term] = primary_rgba; 2462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 2472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_PREVIOUS: 2480695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul argA[term] = rgba; 2492cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 2502cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_CONSTANT: 2512cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul { 2520695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul float4_array c = ccolor[term]; 253933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul GLfloat alpha = textureUnit->EnvColor[3]; 2542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) 2552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul c[i][ACOMP] = alpha; 2560695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul argA[term] = ccolor[term]; 2572cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 2582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 2592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* GL_ATI_texture_env_combine3 allows GL_ZERO & GL_ONE as sources. 2602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 2612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_ZERO: 262933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul { 2630695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul float4_array c = ccolor[term]; 264933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul for (i = 0; i < n; i++) 265933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul c[i][ACOMP] = 0.0F; 2660695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul argA[term] = ccolor[term]; 267933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul } 2682cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 2692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_ONE: 270933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul { 2710695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul float4_array c = ccolor[term]; 272933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul for (i = 0; i < n; i++) 273933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul c[i][ACOMP] = 1.0F; 2740695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul argA[term] = ccolor[term]; 275933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul } 2762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 2772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul default: 2782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* ARB_texture_env_crossbar source */ 2792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul { 2802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const GLuint srcUnit = srcA - GL_TEXTURE0; 2812cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ASSERT(srcUnit < ctx->Const.MaxTextureUnits); 2822cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (!ctx->Texture.Unit[srcUnit]._ReallyEnabled) 283aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul goto end; 2841b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paul argA[term] = get_texel_array(swrast, srcUnit); 2852cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 2862cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 2872cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 288933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul if (operandA == GL_ONE_MINUS_SRC_ALPHA) { 2890695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul float4_array src = argA[term]; 2900695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul float4_array dst = ccolor[term]; 2910695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul argA[term] = ccolor[term]; 2922cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 293de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul dst[i][ACOMP] = 1.0F - src[i][ACOMP]; 2942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 2952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 2962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 2972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 298933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul /* RGB channel combine */ 299933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul { 3000695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul float4_array arg0 = argRGB[0]; 3010695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul float4_array arg1 = argRGB[1]; 3020695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul float4_array arg2 = argRGB[2]; 3030695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul float4_array arg3 = argRGB[3]; 304933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul 305933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul switch (combine->ModeRGB) { 3062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_REPLACE: 307933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul for (i = 0; i < n; i++) { 308bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul rgba[i][RCOMP] = arg0[i][RCOMP] * scaleRGB; 309bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul rgba[i][GCOMP] = arg0[i][GCOMP] * scaleRGB; 310bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul rgba[i][BCOMP] = arg0[i][BCOMP] * scaleRGB; 3112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 3122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 3132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_MODULATE: 314933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul for (i = 0; i < n; i++) { 315bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul rgba[i][RCOMP] = arg0[i][RCOMP] * arg1[i][RCOMP] * scaleRGB; 316bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul rgba[i][GCOMP] = arg0[i][GCOMP] * arg1[i][GCOMP] * scaleRGB; 317bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul rgba[i][BCOMP] = arg0[i][BCOMP] * arg1[i][BCOMP] * scaleRGB; 3182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 3192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 3202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_ADD: 3212d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul if (textureUnit->EnvMode == GL_COMBINE4_NV) { 3222d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul /* (a * b) + (c * d) */ 3232d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul for (i = 0; i < n; i++) { 3242d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul rgba[i][RCOMP] = (arg0[i][RCOMP] * arg1[i][RCOMP] + 325bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul arg2[i][RCOMP] * arg3[i][RCOMP]) * scaleRGB; 3262d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul rgba[i][GCOMP] = (arg0[i][GCOMP] * arg1[i][GCOMP] + 327bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul arg2[i][GCOMP] * arg3[i][GCOMP]) * scaleRGB; 3282d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul rgba[i][BCOMP] = (arg0[i][BCOMP] * arg1[i][BCOMP] + 329bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul arg2[i][BCOMP] * arg3[i][BCOMP]) * scaleRGB; 3302d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul } 3312d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul } 3322d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul else { 3332d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul /* 2-term addition */ 3342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 335bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul rgba[i][RCOMP] = (arg0[i][RCOMP] + arg1[i][RCOMP]) * scaleRGB; 336bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul rgba[i][GCOMP] = (arg0[i][GCOMP] + arg1[i][GCOMP]) * scaleRGB; 337bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul rgba[i][BCOMP] = (arg0[i][BCOMP] + arg1[i][BCOMP]) * scaleRGB; 3382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 3392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 3402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 3412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_ADD_SIGNED: 3422d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul if (textureUnit->EnvMode == GL_COMBINE4_NV) { 3432d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul /* (a * b) + (c * d) - 0.5 */ 3442d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul for (i = 0; i < n; i++) { 34587c356a222bb97ecf9b04e8d509b103199159b11Brian Paul rgba[i][RCOMP] = (arg0[i][RCOMP] * arg1[i][RCOMP] + 346880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul arg2[i][RCOMP] * arg3[i][RCOMP] - 0.5F) * scaleRGB; 34787c356a222bb97ecf9b04e8d509b103199159b11Brian Paul rgba[i][GCOMP] = (arg0[i][GCOMP] * arg1[i][GCOMP] + 348880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul arg2[i][GCOMP] * arg3[i][GCOMP] - 0.5F) * scaleRGB; 34987c356a222bb97ecf9b04e8d509b103199159b11Brian Paul rgba[i][BCOMP] = (arg0[i][BCOMP] * arg1[i][BCOMP] + 350880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul arg2[i][BCOMP] * arg3[i][BCOMP] - 0.5F) * scaleRGB; 3512d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul } 3522d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul } 3532d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul else { 3542cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 355880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul rgba[i][RCOMP] = (arg0[i][RCOMP] + arg1[i][RCOMP] - 0.5F) * scaleRGB; 356880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul rgba[i][GCOMP] = (arg0[i][GCOMP] + arg1[i][GCOMP] - 0.5F) * scaleRGB; 357880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul rgba[i][BCOMP] = (arg0[i][BCOMP] + arg1[i][BCOMP] - 0.5F) * scaleRGB; 3582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 3592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 3602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 3612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_INTERPOLATE: 362933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul for (i = 0; i < n; i++) { 363933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul rgba[i][RCOMP] = (arg0[i][RCOMP] * arg2[i][RCOMP] + 364bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul arg1[i][RCOMP] * (1.0F - arg2[i][RCOMP])) * scaleRGB; 365933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul rgba[i][GCOMP] = (arg0[i][GCOMP] * arg2[i][GCOMP] + 366bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul arg1[i][GCOMP] * (1.0F - arg2[i][GCOMP])) * scaleRGB; 367933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul rgba[i][BCOMP] = (arg0[i][BCOMP] * arg2[i][BCOMP] + 368bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul arg1[i][BCOMP] * (1.0F - arg2[i][BCOMP])) * scaleRGB; 3692cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 3702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 3712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_SUBTRACT: 372933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul for (i = 0; i < n; i++) { 373bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul rgba[i][RCOMP] = (arg0[i][RCOMP] - arg1[i][RCOMP]) * scaleRGB; 374bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul rgba[i][GCOMP] = (arg0[i][GCOMP] - arg1[i][GCOMP]) * scaleRGB; 375bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul rgba[i][BCOMP] = (arg0[i][BCOMP] - arg1[i][BCOMP]) * scaleRGB; 3762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 3772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 3782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_DOT3_RGB_EXT: 3792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_DOT3_RGBA_EXT: 380933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul /* Do not scale the result by 1 2 or 4 */ 381933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul for (i = 0; i < n; i++) { 382bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul GLfloat dot = ((arg0[i][RCOMP] - 0.5F) * (arg1[i][RCOMP] - 0.5F) + 383bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul (arg0[i][GCOMP] - 0.5F) * (arg1[i][GCOMP] - 0.5F) + 384bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul (arg0[i][BCOMP] - 0.5F) * (arg1[i][BCOMP] - 0.5F)) 385933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul * 4.0F; 386933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul dot = CLAMP(dot, 0.0F, 1.0F); 387aef2e1c1dcda77b6dc5fcfd2de7c9d720effa4e7Brian Paul rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = dot; 3882cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 3892cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 3902cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_DOT3_RGB: 3912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_DOT3_RGBA: 392933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul /* DO scale the result by 1 2 or 4 */ 393933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul for (i = 0; i < n; i++) { 394bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul GLfloat dot = ((arg0[i][RCOMP] - 0.5F) * (arg1[i][RCOMP] - 0.5F) + 395bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul (arg0[i][GCOMP] - 0.5F) * (arg1[i][GCOMP] - 0.5F) + 396bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul (arg0[i][BCOMP] - 0.5F) * (arg1[i][BCOMP] - 0.5F)) 397bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul * 4.0F * scaleRGB; 398b30898f4ab533085d97a33638ad0a1cf9ddb1d67Karl Schultz dot = CLAMP(dot, 0.0F, 1.0F); 399aef2e1c1dcda77b6dc5fcfd2de7c9d720effa4e7Brian Paul rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = dot; 4002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 4012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 4022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_MODULATE_ADD_ATI: 403933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul for (i = 0; i < n; i++) { 404933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) + 405bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul arg1[i][RCOMP]) * scaleRGB; 406933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) + 407bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul arg1[i][GCOMP]) * scaleRGB; 408933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) + 409bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul arg1[i][BCOMP]) * scaleRGB; 4102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 4112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 4122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_MODULATE_SIGNED_ADD_ATI: 413933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul for (i = 0; i < n; i++) { 414933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) + 415880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul arg1[i][RCOMP] - 0.5F) * scaleRGB; 416933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) + 417880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul arg1[i][GCOMP] - 0.5F) * scaleRGB; 418933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) + 419880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul arg1[i][BCOMP] - 0.5F) * scaleRGB; 4202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 4212cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 4222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_MODULATE_SUBTRACT_ATI: 423933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul for (i = 0; i < n; i++) { 424933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) - 425bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul arg1[i][RCOMP]) * scaleRGB; 426933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) - 427bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul arg1[i][GCOMP]) * scaleRGB; 428933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) - 429bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul arg1[i][BCOMP]) * scaleRGB; 4302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 4312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 432114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger case GL_BUMP_ENVMAP_ATI: 4333630da9916a4f24a03d3a63420690f8016a9b72aBrian Paul /* this produces a fixed rgba color, and the coord calc is done elsewhere */ 4343630da9916a4f24a03d3a63420690f8016a9b72aBrian Paul for (i = 0; i < n; i++) { 435114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger /* rgba result is 0,0,0,1 */ 4363630da9916a4f24a03d3a63420690f8016a9b72aBrian Paul rgba[i][RCOMP] = 0.0; 4373630da9916a4f24a03d3a63420690f8016a9b72aBrian Paul rgba[i][GCOMP] = 0.0; 4383630da9916a4f24a03d3a63420690f8016a9b72aBrian Paul rgba[i][BCOMP] = 0.0; 4393630da9916a4f24a03d3a63420690f8016a9b72aBrian Paul rgba[i][ACOMP] = 1.0; 440114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger } 441aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul goto end; /* no alpha processing */ 4422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul default: 4432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul _mesa_problem(ctx, "invalid combine mode"); 444933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul } 4452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 4462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 447933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul /* Alpha channel combine */ 448933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul { 4490695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul float4_array arg0 = argA[0]; 4500695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul float4_array arg1 = argA[1]; 4510695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul float4_array arg2 = argA[2]; 4520695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul float4_array arg3 = argA[3]; 453933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul 454933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul switch (combine->ModeA) { 4552cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_REPLACE: 456933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul for (i = 0; i < n; i++) { 457aef2e1c1dcda77b6dc5fcfd2de7c9d720effa4e7Brian Paul rgba[i][ACOMP] = arg0[i][ACOMP] * scaleA; 4582cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 4592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 4602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_MODULATE: 461933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul for (i = 0; i < n; i++) { 462bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul rgba[i][ACOMP] = arg0[i][ACOMP] * arg1[i][ACOMP] * scaleA; 4632cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 4642cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 4652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_ADD: 4662d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul if (textureUnit->EnvMode == GL_COMBINE4_NV) { 4672d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul /* (a * b) + (c * d) */ 4682d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul for (i = 0; i < n; i++) { 4692d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul rgba[i][ACOMP] = (arg0[i][ACOMP] * arg1[i][ACOMP] + 470bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul arg2[i][ACOMP] * arg3[i][ACOMP]) * scaleA; 4712d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul } 4722d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul } 4732d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul else { 4742d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul /* two-term add */ 4752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 476bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul rgba[i][ACOMP] = (arg0[i][ACOMP] + arg1[i][ACOMP]) * scaleA; 4772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 4782cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 4792cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 4802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_ADD_SIGNED: 4812d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul if (textureUnit->EnvMode == GL_COMBINE4_NV) { 4822d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul /* (a * b) + (c * d) - 0.5 */ 4832d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul for (i = 0; i < n; i++) { 4842d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul rgba[i][ACOMP] = (arg0[i][ACOMP] * arg1[i][ACOMP] + 4852d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul arg2[i][ACOMP] * arg3[i][ACOMP] - 486880411c72aee7c0ec81366bdf6ab8cf25bebb9d5Brian Paul 0.5F) * scaleA; 4872d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul } 4882d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul } 4892d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul else { 4902d508c1d5c53dc475e5262593dd4dac5575a6b08Brian Paul /* a + b - 0.5 */ 4912cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 492bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul rgba[i][ACOMP] = (arg0[i][ACOMP] + arg1[i][ACOMP] - 0.5F) * scaleA; 4932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 4942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 4952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 4962cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_INTERPOLATE: 497aef2e1c1dcda77b6dc5fcfd2de7c9d720effa4e7Brian Paul for (i = 0; i < n; i++) { 498933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul rgba[i][ACOMP] = (arg0[i][ACOMP] * arg2[i][ACOMP] + 499933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul arg1[i][ACOMP] * (1.0F - arg2[i][ACOMP])) 500bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul * scaleA; 5012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 5022cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 5032cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_SUBTRACT: 504933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul for (i = 0; i < n; i++) { 505bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul rgba[i][ACOMP] = (arg0[i][ACOMP] - arg1[i][ACOMP]) * scaleA; 5062cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 5072cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 5082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_MODULATE_ADD_ATI: 509933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul for (i = 0; i < n; i++) { 510933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP]) 511bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul + arg1[i][ACOMP]) * scaleA; 5122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 5132cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 5142cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_MODULATE_SIGNED_ADD_ATI: 515933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul for (i = 0; i < n; i++) { 516933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP]) + 517bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul arg1[i][ACOMP] - 0.5F) * scaleA; 5182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 5192cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 5202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul case GL_MODULATE_SUBTRACT_ATI: 521933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul for (i = 0; i < n; i++) { 522933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP]) 523bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul - arg1[i][ACOMP]) * scaleA; 5242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 5252cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul break; 5262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul default: 5272cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul _mesa_problem(ctx, "invalid combine mode"); 528933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul } 5292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 5302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 5312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* Fix the alpha component for GL_DOT3_RGBA_EXT/ARB combining. 5322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * This is kind of a kludge. It would have been better if the spec 5332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * were written such that the GL_COMBINE_ALPHA value could be set to 5342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * GL_DOT3. 5352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 536933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul if (combine->ModeRGB == GL_DOT3_RGBA_EXT || 537933f3b13c34c2ed9223755c0e7c7dc22f09d23e8Brian Paul combine->ModeRGB == GL_DOT3_RGBA) { 5382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < n; i++) { 5392cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul rgba[i][ACOMP] = rgba[i][RCOMP]; 5402cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 5412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 542de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul 543de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul for (i = 0; i < n; i++) { 544de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][RCOMP], rgba[i][RCOMP]); 545de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][GCOMP], rgba[i][GCOMP]); 546de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][BCOMP], rgba[i][BCOMP]); 547de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][ACOMP], rgba[i][ACOMP]); 548de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul } 5492e6402feb754dd6384ee27fe623a7f9fce66dcafYuanhan Liu /* The span->array->rgba values are of CHAN type so set 5502e6402feb754dd6384ee27fe623a7f9fce66dcafYuanhan Liu * span->array->ChanType field accordingly. 5512e6402feb754dd6384ee27fe623a7f9fce66dcafYuanhan Liu */ 5522e6402feb754dd6384ee27fe623a7f9fce66dcafYuanhan Liu span->array->ChanType = CHAN_TYPE; 553aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul 554aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paulend: 555aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul for (i = 0; i < numArgsRGB || i < numArgsA; i++) { 556aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul free(ccolor[i]); 557aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul } 558aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul free(rgba); 5592cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 560de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul 5612cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 5622cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul/** 56354c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul * Apply X/Y/Z/W/0/1 swizzle to an array of colors/texels. 56454c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul * See GL_EXT_texture_swizzle. 56554c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul */ 56654c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paulstatic void 5670695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paulswizzle_texels(GLuint swizzle, GLuint count, float4_array texels) 56854c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul{ 56954c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul const GLuint swzR = GET_SWZ(swizzle, 0); 57054c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul const GLuint swzG = GET_SWZ(swizzle, 1); 57154c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul const GLuint swzB = GET_SWZ(swizzle, 2); 57254c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul const GLuint swzA = GET_SWZ(swizzle, 3); 573de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLfloat vector[6]; 57454c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul GLuint i; 57554c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul 57654c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul vector[SWIZZLE_ZERO] = 0; 577de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul vector[SWIZZLE_ONE] = 1.0F; 57854c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul 57954c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul for (i = 0; i < count; i++) { 58054c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul vector[SWIZZLE_X] = texels[i][0]; 58154c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul vector[SWIZZLE_Y] = texels[i][1]; 58254c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul vector[SWIZZLE_Z] = texels[i][2]; 58354c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul vector[SWIZZLE_W] = texels[i][3]; 58454c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul texels[i][RCOMP] = vector[swzR]; 58554c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul texels[i][GCOMP] = vector[swzG]; 58654c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul texels[i][BCOMP] = vector[swzB]; 58754c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul texels[i][ACOMP] = vector[swzA]; 58854c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul } 58954c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul} 59054c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul 59154c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul 59254c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul/** 5932cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Apply texture mapping to a span of fragments. 5942cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 5952cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paulvoid 596f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_swrast_texture_span( struct gl_context *ctx, SWspan *span ) 5972cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul{ 5982cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul SWcontext *swrast = SWRAST_CONTEXT(ctx); 599aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul float4_array primary_rgba; 6002cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint unit; 6012cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 6029119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul if (!swrast->TexelBuffer) { 6039119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul#ifdef _OPENMP 6049119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul const GLint maxThreads = omp_get_max_threads(); 6059119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul#else 6069119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul const GLint maxThreads = 1; 6079119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul#endif 6089119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul 6099119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul /* TexelBuffer is also global and normally shared by all SWspan 6109119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul * instances; when running with multiple threads, create one per 6119119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul * thread. 6129119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul */ 6139119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul swrast->TexelBuffer = 6149119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul (GLfloat *) MALLOC(ctx->Const.MaxTextureImageUnits * maxThreads * 61547d88ef204b42a9220c6be3e98c92df9c9aa0860Brian Paul SWRAST_MAX_WIDTH * 4 * sizeof(GLfloat)); 6169119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul if (!swrast->TexelBuffer) { 6179119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture_combine"); 6189119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul return; 6199119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul } 6209119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul } 6219119269ca14ed42b51c7d8e2e662500311b29fa3Brian Paul 622aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul primary_rgba = (float4_array) malloc(span->end * 4 * sizeof(GLfloat)); 623aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul 624aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul if (!primary_rgba) { 625aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture_span"); 626aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul return; 627aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul } 628aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul 62947d88ef204b42a9220c6be3e98c92df9c9aa0860Brian Paul ASSERT(span->end <= SWRAST_MAX_WIDTH); 6302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 6312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* 6322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Save copy of the incoming fragment colors (the GL_PRIMARY_COLOR) 6332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 6347aed2b0c30c6d29d70efd2402a68a8e3de98418cBrian Paul if (swrast->_TextureCombinePrimary) { 635de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul GLuint i; 636de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul for (i = 0; i < span->end; i++) { 637de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul primary_rgba[i][RCOMP] = CHAN_TO_FLOAT(span->array->rgba[i][RCOMP]); 638de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul primary_rgba[i][GCOMP] = CHAN_TO_FLOAT(span->array->rgba[i][GCOMP]); 639de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul primary_rgba[i][BCOMP] = CHAN_TO_FLOAT(span->array->rgba[i][BCOMP]); 640de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul primary_rgba[i][ACOMP] = CHAN_TO_FLOAT(span->array->rgba[i][ACOMP]); 641de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul } 642de2afd8688ceb45013d15be7c6e0995199b80e5aBrian Paul } 6432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 644114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger /* First must sample all bump maps */ 645114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { 6461b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paul const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; 6471b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paul 6481b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paul if (texUnit->_ReallyEnabled && 6491b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paul texUnit->_CurrentCombine->ModeRGB == GL_BUMP_ENVMAP_ATI) { 6501b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paul const GLfloat (*texcoords)[4] = (const GLfloat (*)[4]) 651114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger span->array->attribs[FRAG_ATTRIB_TEX0 + unit]; 6521b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paul float4_array targetcoords = 653114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger span->array->attribs[FRAG_ATTRIB_TEX0 + 654114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger ctx->Texture.Unit[unit].BumpTarget - GL_TEXTURE0]; 655114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 656cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp = _mesa_get_samplerobj(ctx, unit); 657114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger GLfloat *lambda = span->array->lambda[unit]; 6581b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paul float4_array texels = get_texel_array(swrast, unit); 659114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger GLuint i; 660114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger GLfloat rotMatrix00 = ctx->Texture.Unit[unit].RotMatrix[0]; 661114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger GLfloat rotMatrix01 = ctx->Texture.Unit[unit].RotMatrix[1]; 662114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger GLfloat rotMatrix10 = ctx->Texture.Unit[unit].RotMatrix[2]; 663114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger GLfloat rotMatrix11 = ctx->Texture.Unit[unit].RotMatrix[3]; 664114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 665114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger /* adjust texture lod (lambda) */ 666114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger if (span->arrayMask & SPAN_LAMBDA) { 667cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen if (texUnit->LodBias + samp->LodBias != 0.0F) { 668114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger /* apply LOD bias, but don't clamp yet */ 669cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const GLfloat bias = CLAMP(texUnit->LodBias + samp->LodBias, 670114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger -ctx->Const.MaxTextureLodBias, 671114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger ctx->Const.MaxTextureLodBias); 672114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger GLuint i; 673114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger for (i = 0; i < span->end; i++) { 674114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger lambda[i] += bias; 675114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger } 676114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger } 677114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 678cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen if (samp->MinLod != -1000.0 || 679cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen samp->MaxLod != 1000.0) { 680114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger /* apply LOD clamping to lambda */ 681cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const GLfloat min = samp->MinLod; 682cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const GLfloat max = samp->MaxLod; 683114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger GLuint i; 684114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger for (i = 0; i < span->end; i++) { 685114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger GLfloat l = lambda[i]; 686114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger lambda[i] = CLAMP(l, min, max); 687114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger } 688114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger } 689114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger } 690114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 691114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger /* Sample the texture (span->end = number of fragments) */ 692cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen swrast->TextureSample[unit]( ctx, samp, 693cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen ctx->Texture.Unit[unit]._Current, 694cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen span->end, texcoords, lambda, texels ); 695114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 696114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger /* manipulate the span values of the bump target 697114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger not sure this can work correctly even ignoring 698114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger the problem that channel is unsigned */ 699114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger for (i = 0; i < span->end; i++) { 700114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger targetcoords[i][0] += (texels[i][0] * rotMatrix00 + texels[i][1] * 701114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger rotMatrix01) / targetcoords[i][3]; 702114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger targetcoords[i][1] += (texels[i][0] * rotMatrix10 + texels[i][1] * 703114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger rotMatrix11) / targetcoords[i][3]; 704114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger } 705114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger } 706114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger } 707114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 7082cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* 7092cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * Must do all texture sampling before combining in order to 7102cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * accomodate GL_ARB_texture_env_crossbar. 7112cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 7122cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { 7131b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paul const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; 7141b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paul if (texUnit->_ReallyEnabled && 7151b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paul texUnit->_CurrentCombine->ModeRGB != GL_BUMP_ENVMAP_ATI) { 7160695413d2be5999f7597ce07ba5a4c8fd6a6b333Brian Paul const GLfloat (*texcoords)[4] = (const GLfloat (*)[4]) 717f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3Brian span->array->attribs[FRAG_ATTRIB_TEX0 + unit]; 7182cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul const struct gl_texture_object *curObj = texUnit->_Current; 719cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const struct gl_sampler_object *samp = _mesa_get_samplerobj(ctx, unit); 7202cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLfloat *lambda = span->array->lambda[unit]; 7211b2ab023673261b4b942e1126c0b599d02fbd4a0Brian Paul float4_array texels = get_texel_array(swrast, unit); 7222cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 7232cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* adjust texture lod (lambda) */ 7242cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul if (span->arrayMask & SPAN_LAMBDA) { 725cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen if (texUnit->LodBias + samp->LodBias != 0.0F) { 7262cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* apply LOD bias, but don't clamp yet */ 727cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const GLfloat bias = CLAMP(texUnit->LodBias + samp->LodBias, 7282cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul -ctx->Const.MaxTextureLodBias, 7292cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul ctx->Const.MaxTextureLodBias); 7302cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 7312cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < span->end; i++) { 7322cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda[i] += bias; 7332cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 7342cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 7352cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 736cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen if (samp->MinLod != -1000.0 || 737cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen samp->MaxLod != 1000.0) { 7382cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* apply LOD clamping to lambda */ 739cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const GLfloat min = samp->MinLod; 740cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen const GLfloat max = samp->MaxLod; 7412cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLuint i; 7422cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (i = 0; i < span->end; i++) { 7432cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul GLfloat l = lambda[i]; 7442cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul lambda[i] = CLAMP(l, min, max); 7452cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 7462cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 7472cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 748cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen else if (samp->MaxAnisotropy > 1.0 && 749cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen samp->MinFilter == GL_LINEAR_MIPMAP_LINEAR) { 7508a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* sample_lambda_2d_aniso is beeing used as texture_sample_func, 7518a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * it requires the current SWspan *span as an additional parameter. 7528a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * In order to keep the same function signature, the unused lambda 7538a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * parameter will be modified to actually contain the SWspan pointer. 7548a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * This is a Hack. To make it right, the texture_sample_func 7558a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger * signature and all implementing functions need to be modified. 7568a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger */ 7578a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger /* "hide" SWspan struct; cast to (GLfloat *) to suppress warning */ 7588a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger lambda = (GLfloat *)span; 7598a98aabe0bcea42cfdc982001ae4876e3d9b1214Andreas Faenger } 7602cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 761aa8abf8081023c00469b6c88760ed0291033eb6eBrian Paul /* Sample the texture (span->end = number of fragments) */ 762cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen swrast->TextureSample[unit]( ctx, samp, 763cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen ctx->Texture.Unit[unit]._Current, 764cbdc1d53542b3ecca0085399c4bb3b3371f94809Pauli Nieminen span->end, texcoords, lambda, texels ); 7652cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 76654c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul /* GL_EXT_texture_swizzle */ 76754c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul if (curObj->_Swizzle != SWIZZLE_NOOP) { 76854c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul swizzle_texels(curObj->_Swizzle, span->end, texels); 76954c62ba5c36f3e2b279151f5df851d2ceee15319Brian Paul } 7702cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 7712cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 7722cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul 7732cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul /* 7742cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * OK, now apply the texture (aka texture combine/blend). 7752cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul * We modify the span->color.rgba values. 7762cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul */ 7772cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { 7786ba8f0688a35ffac93bd025739aefe8e3694ca0cYuanhan Liu if (ctx->Texture.Unit[unit]._ReallyEnabled) 7796ba8f0688a35ffac93bd025739aefe8e3694ca0cYuanhan Liu texture_combine(ctx, unit, primary_rgba, swrast->TexelBuffer, span); 7802cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul } 781aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul 782aa28efe60dee4570730538ef091d1c79f42fa1cdBrian Paul free(primary_rgba); 7832cd8791cad11ea3961533c0cd8f9c1bbf50ef6ccBrian Paul} 784