ff_fragment_shader.cpp revision 239617fbe22d4dd7b2794510a6665f09602b5adf
115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell/************************************************************************** 215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 3f4a5ea2ccb472958a4635c606e9510011bceaa3dBrian * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * All Rights Reserved. 515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a 715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * copy of this software and associated documentation files (the 815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * "Software"), to deal in the Software without restriction, including 915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * without limitation the rights to use, copy, modify, merge, publish, 1015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * distribute, sub license, and/or sell copies of the Software, and to 1115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * permit persons to whom the Software is furnished to do so, subject to 1215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * the following conditions: 1315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 1415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * The above copyright notice and this permission notice (including the 1515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * next paragraph) shall be included in all copies or substantial portions 1615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * of the Software. 1715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 1815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 1915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 2015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 2115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 2215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 2315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 2415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 2615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell **************************************************************************/ 2715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 2815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell#include "glheader.h" 2915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell#include "macros.h" 3015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell#include "enums.h" 31c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "shader/prog_parameter.h" 32f4a5ea2ccb472958a4635c606e9510011bceaa3dBrian#include "shader/prog_cache.h" 33c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "shader/prog_instruction.h" 34c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "shader/prog_print.h" 35c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "shader/prog_statevars.h" 3683fad68ec1989c719646a76f4cc5e0b3d23537edBrian#include "shader/programopt.h" 3715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell#include "texenvprogram.h" 3815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 39e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul/** 403f99f501db2582e241851e63e432c18e2de415beBrian Paul * Up to nine instructions per tex unit, plus fog, specular color. 41e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul */ 423f99f501db2582e241851e63e432c18e2de415beBrian Paul#define MAX_INSTRUCTIONS ((MAX_TEXTURE_UNITS * 9) + 12) 4315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 44269e3895d9837ac7303b91948f003ca5c12c0fe4Keith Whitwell#define DISASSEM (MESA_VERBOSE & VERBOSE_DISASSEM) 4515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 46ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstruct mode_opt { 476280e335706f95ed0ebb089d8f72aeede9b5a1adKeith Whitwell GLubyte Source:4; 486280e335706f95ed0ebb089d8f72aeede9b5a1adKeith Whitwell GLubyte Operand:3; 49ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell}; 50ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 51ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstruct state_key { 526280e335706f95ed0ebb089d8f72aeede9b5a1adKeith Whitwell GLuint nr_enabled_units:8; 536280e335706f95ed0ebb089d8f72aeede9b5a1adKeith Whitwell GLuint enabled_units:8; 545d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint separate_specular:1; 555d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint fog_enabled:1; 565d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint fog_mode:2; 576280e335706f95ed0ebb089d8f72aeede9b5a1adKeith Whitwell GLuint inputs_available:12; 58ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 59ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct { 605d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint enabled:1; 615d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint source_index:3; /* one of TEXTURE_1D/2D/3D/CUBE/RECT_INDEX */ 625d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint ScaleShiftRGB:2; 635d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint ScaleShiftA:2; 64ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 655d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint NumArgsRGB:2; 665d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint ModeRGB:4; 675d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint NumArgsA:2; 685d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint ModeA:4; 696280e335706f95ed0ebb089d8f72aeede9b5a1adKeith Whitwell 706280e335706f95ed0ebb089d8f72aeede9b5a1adKeith Whitwell struct mode_opt OptRGB[3]; 71ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct mode_opt OptA[3]; 72ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } unit[8]; 73ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell}; 74ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 75ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define FOG_LINEAR 0 76ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define FOG_EXP 1 77ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define FOG_EXP2 2 78ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define FOG_UNKNOWN 3 79ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 80ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstatic GLuint translate_fog_mode( GLenum mode ) 81ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 82ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch (mode) { 83ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_LINEAR: return FOG_LINEAR; 84ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_EXP: return FOG_EXP; 85ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_EXP2: return FOG_EXP2; 86ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell default: return FOG_UNKNOWN; 87ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 88ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 89ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 90ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_SRC_COLOR 0 91ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_ONE_MINUS_SRC_COLOR 1 92ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_SRC_ALPHA 2 93ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_ONE_MINUS_SRC_ALPHA 3 94ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_ZERO 4 95ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_ONE 5 96ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_UNKNOWN 7 97ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 98ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstatic GLuint translate_operand( GLenum operand ) 99ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 100ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch (operand) { 101ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_SRC_COLOR: return OPR_SRC_COLOR; 102ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_ONE_MINUS_SRC_COLOR: return OPR_ONE_MINUS_SRC_COLOR; 103ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_SRC_ALPHA: return OPR_SRC_ALPHA; 104ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_ONE_MINUS_SRC_ALPHA: return OPR_ONE_MINUS_SRC_ALPHA; 105ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_ZERO: return OPR_ZERO; 106ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_ONE: return OPR_ONE; 107ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell default: return OPR_UNKNOWN; 108ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 109ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 110ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 111ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE 0 112ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE0 1 113ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE1 2 114ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE2 3 115ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE3 4 116ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE4 5 117ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE5 6 118ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE6 7 119ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE7 8 120ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_CONSTANT 9 121ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_PRIMARY_COLOR 10 122ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_PREVIOUS 11 123ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_UNKNOWN 15 124ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 125ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstatic GLuint translate_source( GLenum src ) 126ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 127ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch (src) { 128ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE: return SRC_TEXTURE; 129ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE0: 130ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE1: 131ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE2: 132ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE3: 133ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE4: 134ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE5: 135ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE6: 136ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE7: return SRC_TEXTURE0 + (src - GL_TEXTURE0); 137ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_CONSTANT: return SRC_CONSTANT; 138ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_PRIMARY_COLOR: return SRC_PRIMARY_COLOR; 139ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_PREVIOUS: return SRC_PREVIOUS; 140ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell default: return SRC_UNKNOWN; 141ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 142ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 143ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 144ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_REPLACE 0 145ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_MODULATE 1 146ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_ADD 2 147ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_ADD_SIGNED 3 148ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_INTERPOLATE 4 149ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_SUBTRACT 5 150ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_DOT3_RGB 6 151ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_DOT3_RGB_EXT 7 152ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_DOT3_RGBA 8 153ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_DOT3_RGBA_EXT 9 154ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_MODULATE_ADD_ATI 10 155ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_MODULATE_SIGNED_ADD_ATI 11 156ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_MODULATE_SUBTRACT_ATI 12 157ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_UNKNOWN 15 158ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 159ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstatic GLuint translate_mode( GLenum mode ) 160ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 161ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch (mode) { 162ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_REPLACE: return MODE_REPLACE; 163ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_MODULATE: return MODE_MODULATE; 164ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_ADD: return MODE_ADD; 165ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_ADD_SIGNED: return MODE_ADD_SIGNED; 166ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_INTERPOLATE: return MODE_INTERPOLATE; 167ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_SUBTRACT: return MODE_SUBTRACT; 168ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_DOT3_RGB: return MODE_DOT3_RGB; 169ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_DOT3_RGB_EXT: return MODE_DOT3_RGB_EXT; 170ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_DOT3_RGBA: return MODE_DOT3_RGBA; 171ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_DOT3_RGBA_EXT: return MODE_DOT3_RGBA_EXT; 172ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_MODULATE_ADD_ATI: return MODE_MODULATE_ADD_ATI; 173ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_MODULATE_SIGNED_ADD_ATI: return MODE_MODULATE_SIGNED_ADD_ATI; 174ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_MODULATE_SUBTRACT_ATI: return MODE_MODULATE_SUBTRACT_ATI; 175ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell default: return MODE_UNKNOWN; 176ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 177ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 178ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 179ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define TEXTURE_UNKNOWN_INDEX 7 180e00ac11d4dd05c56584622dc2707bbdcfe4b2707Brian Paulstatic GLuint translate_tex_src_bit( GLbitfield bit ) 181ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 182ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch (bit) { 183ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case TEXTURE_1D_BIT: return TEXTURE_1D_INDEX; 184ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case TEXTURE_2D_BIT: return TEXTURE_2D_INDEX; 185ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case TEXTURE_RECT_BIT: return TEXTURE_RECT_INDEX; 186ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case TEXTURE_3D_BIT: return TEXTURE_3D_INDEX; 187ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case TEXTURE_CUBE_BIT: return TEXTURE_CUBE_INDEX; 188ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell default: return TEXTURE_UNKNOWN_INDEX; 189ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 190ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 191ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 1921680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell#define VERT_BIT_TEX_ANY (0xff << VERT_ATTRIB_TEX0) 1931680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell#define VERT_RESULT_TEX_ANY (0xff << VERT_RESULT_TEX0) 1941680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 195239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul/** 196239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul * Identify all possible varying inputs. The fragment program will 1971680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * never reference non-varying inputs, but will track them via state 1981680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * constants instead. 1991680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * 2001680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * This function figures out all the inputs that the fragment program 2011680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * has access to. The bitmask is later reduced to just those which 2021680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * are actually referenced. 2031680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell */ 204239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paulstatic GLbitfield get_fp_input_mask( GLcontext *ctx ) 2051680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell{ 206239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul GLbitfield fp_inputs = 0x0; 2071680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 2086ff1cf5b82488dc5a07513b0806c23e70f7a665eKeith Whitwell if (!ctx->VertexProgram._Enabled || 2096ff1cf5b82488dc5a07513b0806c23e70f7a665eKeith Whitwell !ctx->VertexProgram._Current) { 2106ff1cf5b82488dc5a07513b0806c23e70f7a665eKeith Whitwell 2116ff1cf5b82488dc5a07513b0806c23e70f7a665eKeith Whitwell /* Fixed function logic */ 212239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul GLbitfield varying_inputs = ctx->varying_vp_inputs; 2131680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 2141680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell /* First look at what values may be computed by the generated 2151680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * vertex program: 2161680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell */ 2171680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell if (ctx->Light.Enabled) { 2181680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell fp_inputs |= FRAG_BIT_COL0; 2191680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 2201680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) 2211680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell fp_inputs |= FRAG_BIT_COL1; 2221680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell } 2231680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 2241680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell fp_inputs |= (ctx->Texture._TexGenEnabled | 2251680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell ctx->Texture._TexMatEnabled) << FRAG_ATTRIB_TEX0; 2261680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 2271680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell /* Then look at what might be varying as a result of enabled 2281680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * arrays, etc: 2291680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell */ 2301680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell if (varying_inputs & VERT_BIT_COLOR0) fp_inputs |= FRAG_BIT_COL0; 2311680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell if (varying_inputs & VERT_BIT_COLOR1) fp_inputs |= FRAG_BIT_COL1; 2321680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 2331680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell fp_inputs |= (((varying_inputs & VERT_BIT_TEX_ANY) >> VERT_ATTRIB_TEX0) 2341680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell << FRAG_ATTRIB_TEX0); 2351680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 2361680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell } 2371680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell else { 2381680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell /* calculate from vp->outputs */ 239239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul GLbitfield vp_outputs = ctx->VertexProgram._Current->Base.OutputsWritten; 2401680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 2411680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell if (vp_outputs & (1 << VERT_RESULT_COL0)) fp_inputs |= FRAG_BIT_COL0; 2421680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell if (vp_outputs & (1 << VERT_RESULT_COL1)) fp_inputs |= FRAG_BIT_COL1; 2431680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 2440370d6b359016790c6b879c2a4b6661adac20deaKeith Whitwell fp_inputs |= (((vp_outputs & VERT_RESULT_TEX_ANY) >> VERT_RESULT_TEX0) 2450370d6b359016790c6b879c2a4b6661adac20deaKeith Whitwell << FRAG_ATTRIB_TEX0); 2461680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell } 2471680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 2481680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell return fp_inputs; 2491680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell} 2501680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 2511680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 25222db53577603afef8fdf62c324ff5977de76b9d8Brian Paul/** 25322db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * Examine current texture environment state and generate a unique 25422db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * key to identify it. 25522db53577603afef8fdf62c324ff5977de76b9d8Brian Paul */ 2568065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwellstatic void make_state_key( GLcontext *ctx, struct state_key *key ) 257ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 258ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint i, j; 259239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul GLbitfield inputs_referenced = FRAG_BIT_COL0; 260239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul GLbitfield inputs_available = get_fp_input_mask( ctx ); 2611680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 2628065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell memset(key, 0, sizeof(*key)); 2638065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell 264ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell for (i=0;i<MAX_TEXTURE_UNITS;i++) { 265d9736db6676948e06712d4bcba46b7040452f870Brian Paul const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i]; 266ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 2671680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell if (!texUnit->_ReallyEnabled) 268ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell continue; 269ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 270ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].enabled = 1; 271ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->enabled_units |= (1<<i); 2721680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell key->nr_enabled_units = i+1; 2731680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell inputs_referenced |= FRAG_BIT_TEX(i); 274ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 275ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].source_index = 276ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell translate_tex_src_bit(texUnit->_ReallyEnabled); 277ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 278ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].NumArgsRGB = texUnit->_CurrentCombine->_NumArgsRGB; 279ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].NumArgsA = texUnit->_CurrentCombine->_NumArgsA; 280ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 281ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].ModeRGB = 282ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell translate_mode(texUnit->_CurrentCombine->ModeRGB); 283ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].ModeA = 284ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell translate_mode(texUnit->_CurrentCombine->ModeA); 285ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 286ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].ScaleShiftRGB = texUnit->_CurrentCombine->ScaleShiftRGB; 28764da16146fed68605f83ccf3b64075c0d5b6f052Keith Whitwell key->unit[i].ScaleShiftA = texUnit->_CurrentCombine->ScaleShiftA; 288ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 289ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell for (j=0;j<3;j++) { 290ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].OptRGB[j].Operand = 291ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell translate_operand(texUnit->_CurrentCombine->OperandRGB[j]); 292ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].OptA[j].Operand = 293ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell translate_operand(texUnit->_CurrentCombine->OperandA[j]); 294ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].OptRGB[j].Source = 295ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell translate_source(texUnit->_CurrentCombine->SourceRGB[j]); 296ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].OptA[j].Source = 297ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell translate_source(texUnit->_CurrentCombine->SourceA[j]); 298ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 299ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 300ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 3011680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) { 302ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->separate_specular = 1; 3031680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell inputs_referenced |= FRAG_BIT_COL1; 3041680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell } 305ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 306ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (ctx->Fog.Enabled) { 307ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->fog_enabled = 1; 308ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->fog_mode = translate_fog_mode(ctx->Fog.Mode); 3091680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell inputs_referenced |= FRAG_BIT_FOGC; /* maybe */ 310ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 3111680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 3121680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell key->inputs_available = (inputs_available & inputs_referenced); 313ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 314ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 315239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul/** 316239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul * Use uregs to represent registers internally, translate to Mesa's 31715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * expected formats on emit. 31815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 31915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * NOTE: These are passed by value extensively in this file rather 32015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * than as usual by pointer reference. If this disturbs you, try 32115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * remembering they are just 32bits in size. 32215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 32315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * GCC is smart enough to deal with these dword-sized structures in 32415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * much the same way as if I had defined them as dwords and was using 32515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * macros to access and set the fields. This is much nicer and easier 32615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * to evolve. 32715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 32815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstruct ureg { 32915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint file:4; 33015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint idx:8; 33115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint negatebase:1; 33215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint abs:1; 33315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint negateabs:1; 33415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint swz:12; 33515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint pad:5; 33615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell}; 33715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 33813abf91b42b00c7eb64c373aff3a4c1bb3d8fb7fBrian Paulstatic const struct ureg undef = { 3398d97265711b172da4f387748f0e72da9267492b0Alan Hourihane PROGRAM_UNDEFINED, 34015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell ~0, 34115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 0, 34215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 0, 34315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 0, 34415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 0, 34515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 0 34615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell}; 34715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 34815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 349239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul/** State used to build the fragment program: 35015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 35115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstruct texenv_fragment_program { 352122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul struct gl_fragment_program *program; 35315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLcontext *ctx; 354ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct state_key *state; 35515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 356239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul GLbitfield alu_temps; /**< Track texture indirections, see spec. */ 357239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul GLbitfield temps_output; /**< Track texture indirections, see spec. */ 358239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul GLbitfield temp_in_use; /**< Tracks temporary regs which are in use. */ 35915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLboolean error; 36015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 3612dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell struct ureg src_texture[MAX_TEXTURE_UNITS]; 362ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell /* Reg containing each texture unit's sampled texture color, 363ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell * else undef. 364ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell */ 36515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 366239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul struct ureg src_previous; /**< Reg containing color from previous 36715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * stage. May need to be decl'd. 36815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 36915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 370239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul GLuint last_tex_stage; /**< Number of last enabled texture unit */ 3712dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 3722dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell struct ureg half; 3732dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell struct ureg one; 3742dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell struct ureg zero; 37515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell}; 37615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 37715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 37815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 37915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg make_ureg(GLuint file, GLuint idx) 38015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 38115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg reg; 38215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.file = file; 38315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.idx = idx; 38415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.negatebase = 0; 38515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.abs = 0; 38615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.negateabs = 0; 38715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.swz = SWIZZLE_NOOP; 38815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.pad = 0; 38915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return reg; 39015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 39115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 39215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg swizzle( struct ureg reg, int x, int y, int z, int w ) 39315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 39415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.swz = MAKE_SWIZZLE4(GET_SWZ(reg.swz, x), 39515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GET_SWZ(reg.swz, y), 39615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GET_SWZ(reg.swz, z), 39715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GET_SWZ(reg.swz, w)); 39815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 39915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return reg; 40015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 40115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 40215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg swizzle1( struct ureg reg, int x ) 40315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 40415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return swizzle(reg, x, x, x, x); 40515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 40615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 4076fe176a64859798db17fbaed6858cccc646aae38Keith Whitwellstatic struct ureg negate( struct ureg reg ) 4086fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell{ 4096fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell reg.negatebase ^= 1; 4106fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell return reg; 4116fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell} 4126fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell 41315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic GLboolean is_undef( struct ureg reg ) 41415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 4158d97265711b172da4f387748f0e72da9267492b0Alan Hourihane return reg.file == PROGRAM_UNDEFINED; 41615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 41715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 418ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 41915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg get_temp( struct texenv_fragment_program *p ) 42015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 42113abf91b42b00c7eb64c373aff3a4c1bb3d8fb7fBrian Paul GLint bit; 422ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 423cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell /* First try and reuse temps which have been used already: 424ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell */ 425b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul bit = _mesa_ffs( ~p->temp_in_use & p->alu_temps ); 426ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 427ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell /* Then any unused temporary: 428ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell */ 429ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell if (!bit) 430b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul bit = _mesa_ffs( ~p->temp_in_use ); 431ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 432ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell if (!bit) { 433bfb5ea307ec48b9b8d0d2eca0c03f6d02273d454Brian Paul _mesa_problem(NULL, "%s: out of temporaries\n", __FILE__); 434b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul _mesa_exit(1); 435ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell } 436ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 43713abf91b42b00c7eb64c373aff3a4c1bb3d8fb7fBrian Paul if ((GLuint) bit > p->program->Base.NumTemporaries) 438b5cbaf945dd5213d5faf7bb7e4d68d0d25a25b55Keith Whitwell p->program->Base.NumTemporaries = bit; 439b5cbaf945dd5213d5faf7bb7e4d68d0d25a25b55Keith Whitwell 44093cd9237d793e38ba4479d1367be7548853f67f4Keith Whitwell p->temp_in_use |= 1<<(bit-1); 441ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell return make_ureg(PROGRAM_TEMPORARY, (bit-1)); 442ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell} 443ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 444ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwellstatic struct ureg get_tex_temp( struct texenv_fragment_program *p ) 445ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell{ 446ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell int bit; 447ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 448006fb638188f083d64a2427cd28979b432622f3eBrian Paul /* First try to find available temp not previously used (to avoid 449cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell * starting a new texture indirection). According to the spec, the 450cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell * ~p->temps_output isn't necessary, but will keep it there for 451cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell * now: 452ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell */ 453b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul bit = _mesa_ffs( ~p->temp_in_use & ~p->alu_temps & ~p->temps_output ); 454ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 455ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell /* Then any unused temporary: 456ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell */ 457cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if (!bit) 458b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul bit = _mesa_ffs( ~p->temp_in_use ); 459ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 46015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell if (!bit) { 461bfb5ea307ec48b9b8d0d2eca0c03f6d02273d454Brian Paul _mesa_problem(NULL, "%s: out of temporaries\n", __FILE__); 462b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul _mesa_exit(1); 46315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 46415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 46513abf91b42b00c7eb64c373aff3a4c1bb3d8fb7fBrian Paul if ((GLuint) bit > p->program->Base.NumTemporaries) 466b5cbaf945dd5213d5faf7bb7e4d68d0d25a25b55Keith Whitwell p->program->Base.NumTemporaries = bit; 467b5cbaf945dd5213d5faf7bb7e4d68d0d25a25b55Keith Whitwell 46893cd9237d793e38ba4479d1367be7548853f67f4Keith Whitwell p->temp_in_use |= 1<<(bit-1); 46915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return make_ureg(PROGRAM_TEMPORARY, (bit-1)); 47015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 47115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 47215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 4738fd329d04885eba7587bbe7604d3a1088e35de40Brian Paul/** Mark a temp reg as being no longer allocatable. */ 4748fd329d04885eba7587bbe7604d3a1088e35de40Brian Paulstatic void reserve_temp( struct texenv_fragment_program *p, struct ureg r ) 4758fd329d04885eba7587bbe7604d3a1088e35de40Brian Paul{ 4768fd329d04885eba7587bbe7604d3a1088e35de40Brian Paul if (r.file == PROGRAM_TEMPORARY) 4778fd329d04885eba7587bbe7604d3a1088e35de40Brian Paul p->temps_output |= (1 << r.idx); 4788fd329d04885eba7587bbe7604d3a1088e35de40Brian Paul} 4798fd329d04885eba7587bbe7604d3a1088e35de40Brian Paul 4808fd329d04885eba7587bbe7604d3a1088e35de40Brian Paul 481f18d4e058ed979c6e42e868c7febde4fa62c5810Brianstatic void release_temps(GLcontext *ctx, struct texenv_fragment_program *p ) 48215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 483f18d4e058ed979c6e42e868c7febde4fa62c5810Brian GLuint max_temp = ctx->Const.FragmentProgram.MaxTemps; 48493cd9237d793e38ba4479d1367be7548853f67f4Keith Whitwell 4852dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell /* KW: To support tex_env_crossbar, don't release the registers in 4862dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell * temps_output. 4872dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell */ 48893cd9237d793e38ba4479d1367be7548853f67f4Keith Whitwell if (max_temp >= sizeof(int) * 8) 4892dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell p->temp_in_use = p->temps_output; 49093cd9237d793e38ba4479d1367be7548853f67f4Keith Whitwell else 4912dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell p->temp_in_use = ~((1<<max_temp)-1) | p->temps_output; 49215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 49315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 49415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 4959fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brianstatic struct ureg register_param5( struct texenv_fragment_program *p, 496ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLint s0, 497ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLint s1, 498ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLint s2, 499ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLint s3, 5009fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brian GLint s4) 50115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 5029fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brian gl_state_index tokens[STATE_LENGTH]; 50347b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell GLuint idx; 50447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell tokens[0] = s0; 50547b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell tokens[1] = s1; 50647b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell tokens[2] = s2; 50747b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell tokens[3] = s3; 50847b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell tokens[4] = s4; 509de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul idx = _mesa_add_state_reference( p->program->Base.Parameters, tokens ); 51047b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell return make_ureg(PROGRAM_STATE_VAR, idx); 51147b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell} 51215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 51315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 5149fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brian#define register_param1(p,s0) register_param5(p,s0,0,0,0,0) 5159fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brian#define register_param2(p,s0,s1) register_param5(p,s0,s1,0,0,0) 5169fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brian#define register_param3(p,s0,s1,s2) register_param5(p,s0,s1,s2,0,0) 5179fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brian#define register_param4(p,s0,s1,s2,s3) register_param5(p,s0,s1,s2,s3,0) 51847b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell 5191680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwellstatic GLuint frag_to_vert_attrib( GLuint attrib ) 5201680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell{ 5211680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell switch (attrib) { 5221680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell case FRAG_ATTRIB_COL0: return VERT_ATTRIB_COLOR0; 5231680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell case FRAG_ATTRIB_COL1: return VERT_ATTRIB_COLOR1; 5241680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell default: 5251680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell assert(attrib >= FRAG_ATTRIB_TEX0); 5261680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell assert(attrib <= FRAG_ATTRIB_TEX7); 5271680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell return attrib - FRAG_ATTRIB_TEX0 + VERT_ATTRIB_TEX0; 5281680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell } 5291680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell} 5301680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 53147b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell 53247b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwellstatic struct ureg register_input( struct texenv_fragment_program *p, GLuint input ) 53347b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell{ 5341680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell if (p->state->inputs_available & (1<<input)) { 5351680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell p->program->Base.InputsRead |= (1 << input); 5361680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell return make_ureg(PROGRAM_INPUT, input); 5371680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell } 5381680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell else { 5391680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell GLuint idx = frag_to_vert_attrib( input ); 5401680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell return register_param3( p, STATE_INTERNAL, STATE_CURRENT_ATTRIB, idx ); 5411680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell } 54215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 54315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 54447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell 5457e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paulstatic void emit_arg( struct prog_src_register *reg, 54615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg ureg ) 54715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 54815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg->File = ureg.file; 54915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg->Index = ureg.idx; 55015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg->Swizzle = ureg.swz; 551f2802c40fff686301a7ff99f0a0b1c57d5cf5625Keith Whitwell reg->NegateBase = ureg.negatebase ? 0xf : 0x0; 55215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg->Abs = ureg.abs; 55315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg->NegateAbs = ureg.negateabs; 55415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 55515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 5567e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paulstatic void emit_dst( struct prog_dst_register *dst, 55715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg ureg, GLuint mask ) 55815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 55915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell dst->File = ureg.file; 56015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell dst->Index = ureg.idx; 56115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell dst->WriteMask = mask; 562112a1580f658948e553fe04399a20958dca67c16Brian dst->CondMask = COND_TR; /* always pass cond test */ 563112a1580f658948e553fe04399a20958dca67c16Brian dst->CondSwizzle = SWIZZLE_NOOP; 56415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 56515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 5667e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paulstatic struct prog_instruction * 56715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellemit_op(struct texenv_fragment_program *p, 5685d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul enum prog_opcode op, 56915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg dest, 57015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint mask, 57122db53577603afef8fdf62c324ff5977de76b9d8Brian Paul GLboolean saturate, 57215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg src0, 57315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg src1, 57415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg src2 ) 57515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 57647b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell GLuint nr = p->program->Base.NumInstructions++; 577de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul struct prog_instruction *inst = &p->program->Base.Instructions[nr]; 57815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 579e69943e6dda102df8418a8261b95155350181a2fBrian assert(nr < MAX_INSTRUCTIONS); 580e69943e6dda102df8418a8261b95155350181a2fBrian 581d6272e06172f7ac7a0d6e8062e8ffba33e1ab3baBrian Paul _mesa_init_instructions(inst, 1); 58215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell inst->Opcode = op; 58315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 58447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell emit_arg( &inst->SrcReg[0], src0 ); 58547b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell emit_arg( &inst->SrcReg[1], src1 ); 58647b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell emit_arg( &inst->SrcReg[2], src2 ); 58715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 588e31ac052236ea615b4995f9ec301d8af4b864531Brian Paul inst->SaturateMode = saturate ? SATURATE_ZERO_ONE : SATURATE_OFF; 58915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 59015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell emit_dst( &inst->DstReg, dest, mask ); 59115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 5928fd329d04885eba7587bbe7604d3a1088e35de40Brian Paul#if 0 593cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell /* Accounting for indirection tracking: 594cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell */ 595cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if (dest.file == PROGRAM_TEMPORARY) 596cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell p->temps_output |= 1 << dest.idx; 5978fd329d04885eba7587bbe7604d3a1088e35de40Brian Paul#endif 598cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell 59915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return inst; 60015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 60115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 60215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 60315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg emit_arith( struct texenv_fragment_program *p, 6045d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul enum prog_opcode op, 60547b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell struct ureg dest, 60647b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell GLuint mask, 60722db53577603afef8fdf62c324ff5977de76b9d8Brian Paul GLboolean saturate, 60847b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell struct ureg src0, 60947b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell struct ureg src1, 61047b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell struct ureg src2 ) 61115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 61215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell emit_op(p, op, dest, mask, saturate, src0, src1, src2); 61315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 614cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell /* Accounting for indirection tracking: 615cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell */ 616cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if (src0.file == PROGRAM_TEMPORARY) 617cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell p->alu_temps |= 1 << src0.idx; 618cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell 619cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if (!is_undef(src1) && src1.file == PROGRAM_TEMPORARY) 620cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell p->alu_temps |= 1 << src1.idx; 621cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell 622cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if (!is_undef(src2) && src2.file == PROGRAM_TEMPORARY) 623cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell p->alu_temps |= 1 << src2.idx; 624cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell 625cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if (dest.file == PROGRAM_TEMPORARY) 626cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell p->alu_temps |= 1 << dest.idx; 627cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell 62821f99792a916a62fcfae7c208f50f192d4ce5926Brian p->program->Base.NumAluInstructions++; 62915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return dest; 63015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 63115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 63215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg emit_texld( struct texenv_fragment_program *p, 6335d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul enum prog_opcode op, 634ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct ureg dest, 635ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint destmask, 636ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint tex_unit, 637ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint tex_idx, 638ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct ureg coord ) 63915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 6407e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul struct prog_instruction *inst = emit_op( p, op, 64115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell dest, destmask, 64222db53577603afef8fdf62c324ff5977de76b9d8Brian Paul GL_FALSE, /* don't saturate? */ 64315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell coord, /* arg 0? */ 64415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell undef, 64515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell undef); 64615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 6477e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul inst->TexSrcTarget = tex_idx; 64815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell inst->TexSrcUnit = tex_unit; 64915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 65021f99792a916a62fcfae7c208f50f192d4ce5926Brian p->program->Base.NumTexInstructions++; 65115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 6528fd329d04885eba7587bbe7604d3a1088e35de40Brian Paul /* Accounting for indirection tracking: 6538fd329d04885eba7587bbe7604d3a1088e35de40Brian Paul */ 6548fd329d04885eba7587bbe7604d3a1088e35de40Brian Paul reserve_temp(p, dest); 6558fd329d04885eba7587bbe7604d3a1088e35de40Brian Paul 656cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell /* Is this a texture indirection? 657cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell */ 658cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if ((coord.file == PROGRAM_TEMPORARY && 659cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell (p->temps_output & (1<<coord.idx))) || 660cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell (dest.file == PROGRAM_TEMPORARY && 661cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell (p->alu_temps & (1<<dest.idx)))) { 66221f99792a916a62fcfae7c208f50f192d4ce5926Brian p->program->Base.NumTexIndirections++; 6632dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell p->temps_output = 1<<coord.idx; 664cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell p->alu_temps = 0; 6652dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell assert(0); /* KW: texture env crossbar */ 66615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 66715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 66815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return dest; 66915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 67015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 67115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 67247b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwellstatic struct ureg register_const4f( struct texenv_fragment_program *p, 673ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLfloat s0, 674ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLfloat s1, 675ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLfloat s2, 676ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLfloat s3) 67715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 67847b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell GLfloat values[4]; 679a90046f1097ad95de2aa95ca65741dff5cddced9Brian GLuint idx, swizzle; 680006fb638188f083d64a2427cd28979b432622f3eBrian Paul struct ureg r; 68147b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell values[0] = s0; 68247b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell values[1] = s1; 68347b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell values[2] = s2; 68447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell values[3] = s3; 685a90046f1097ad95de2aa95ca65741dff5cddced9Brian idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4, 686a90046f1097ad95de2aa95ca65741dff5cddced9Brian &swizzle ); 687006fb638188f083d64a2427cd28979b432622f3eBrian Paul r = make_ureg(PROGRAM_CONSTANT, idx); 688006fb638188f083d64a2427cd28979b432622f3eBrian Paul r.swz = swizzle; 689006fb638188f083d64a2427cd28979b432622f3eBrian Paul return r; 69015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 69115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 692e490242b9aeb50bd96fed7a9afbf529295a8ac0eKeith Whitwell#define register_scalar_const(p, s0) register_const4f(p, s0, s0, s0, s0) 69347b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell#define register_const1f(p, s0) register_const4f(p, s0, 0, 0, 1) 69447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell#define register_const2f(p, s0, s1) register_const4f(p, s0, s1, 0, 1) 69547b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell#define register_const3f(p, s0, s1, s2) register_const4f(p, s0, s1, s2, 1) 69615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 69715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 6982dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwellstatic struct ureg get_one( struct texenv_fragment_program *p ) 6992dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell{ 7002dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell if (is_undef(p->one)) 7012dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell p->one = register_scalar_const(p, 1.0); 7022dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell return p->one; 7032dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell} 7042dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 7052dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwellstatic struct ureg get_half( struct texenv_fragment_program *p ) 7062dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell{ 7072dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell if (is_undef(p->half)) 7084dd8a8907e40126e42131a400b59e7d5da5e302aAapo Tahkola p->half = register_scalar_const(p, 0.5); 7092dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell return p->half; 7102dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell} 7112dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 7122dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwellstatic struct ureg get_zero( struct texenv_fragment_program *p ) 7132dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell{ 7142dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell if (is_undef(p->zero)) 7154dd8a8907e40126e42131a400b59e7d5da5e302aAapo Tahkola p->zero = register_scalar_const(p, 0.0); 7162dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell return p->zero; 7172dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell} 7182dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 71915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 72015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic void program_error( struct texenv_fragment_program *p, const char *msg ) 72115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 722bfb5ea307ec48b9b8d0d2eca0c03f6d02273d454Brian Paul _mesa_problem(NULL, msg); 72315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell p->error = 1; 72415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 72515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 72615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg get_source( struct texenv_fragment_program *p, 727ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint src, GLuint unit ) 72815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 72915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell switch (src) { 730ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE: 7312dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell assert(!is_undef(p->src_texture[unit])); 7322dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell return p->src_texture[unit]; 73315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 734ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE0: 735ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE1: 736ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE2: 737ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE3: 738ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE4: 739ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE5: 740ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE6: 741ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE7: 742ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell assert(!is_undef(p->src_texture[src - SRC_TEXTURE0])); 743ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell return p->src_texture[src - SRC_TEXTURE0]; 744ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 745ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_CONSTANT: 74647b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell return register_param2(p, STATE_TEXENV_COLOR, unit); 7472dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 748ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_PRIMARY_COLOR: 74947b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell return register_input(p, FRAG_ATTRIB_COL0); 7502dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 751ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_PREVIOUS: 752ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell default: 75347b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell if (is_undef(p->src_previous)) 75447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell return register_input(p, FRAG_ATTRIB_COL0); 75547b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell else 75647b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell return p->src_previous; 75715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 75815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 7592dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 76015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg emit_combine_source( struct texenv_fragment_program *p, 761ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint mask, 762ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint unit, 763ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint source, 764ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint operand ) 76515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 76615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg arg, src, one; 76715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 76815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell src = get_source(p, source, unit); 76915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 77015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell switch (operand) { 771ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE_MINUS_SRC_COLOR: 77215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Get unused tmp, 77315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * Emit tmp = 1.0 - arg.xyzw 77415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 77515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell arg = get_temp( p ); 7762dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell one = get_one( p ); 7777e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_SUB, arg, mask, 0, one, src, undef); 77815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 779ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_SRC_ALPHA: 78015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell if (mask == WRITEMASK_W) 78115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return src; 78215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell else 78322db53577603afef8fdf62c324ff5977de76b9d8Brian Paul return swizzle1( src, SWIZZLE_W ); 784ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE_MINUS_SRC_ALPHA: 78515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Get unused tmp, 78615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * Emit tmp = 1.0 - arg.wwww 78715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 7882dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell arg = get_temp(p); 7892dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell one = get_one(p); 7907e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith(p, OPCODE_SUB, arg, mask, 0, 79122db53577603afef8fdf62c324ff5977de76b9d8Brian Paul one, swizzle1(src, SWIZZLE_W), undef); 792ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ZERO: 7932dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell return get_zero(p); 794ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE: 7952dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell return get_one(p); 796ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_SRC_COLOR: 79715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 79815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return src; 79915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 80015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 80115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 802ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstatic GLboolean args_match( struct state_key *key, GLuint unit ) 80315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 80422db53577603afef8fdf62c324ff5977de76b9d8Brian Paul GLuint i, nr = key->unit[unit].NumArgsRGB; 80515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 80615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell for (i = 0 ; i < nr ; i++) { 807ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->unit[unit].OptA[i].Source != key->unit[unit].OptRGB[i].Source) 80815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return GL_FALSE; 80915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 810ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch(key->unit[unit].OptA[i].Operand) { 811ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_SRC_ALPHA: 812ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch(key->unit[unit].OptRGB[i].Operand) { 813ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_SRC_COLOR: 814ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_SRC_ALPHA: 81515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 81615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 81715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return GL_FALSE; 81815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 81915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 820ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE_MINUS_SRC_ALPHA: 821ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch(key->unit[unit].OptRGB[i].Operand) { 822ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE_MINUS_SRC_COLOR: 823ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE_MINUS_SRC_ALPHA: 82415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 82515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 82615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return GL_FALSE; 82715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 82815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 82915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 83015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return GL_FALSE; /* impossible */ 83115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 83215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 83315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 83415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return GL_TRUE; 83515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 83615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 83715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg emit_combine( struct texenv_fragment_program *p, 838ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct ureg dest, 839ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint mask, 84022db53577603afef8fdf62c324ff5977de76b9d8Brian Paul GLboolean saturate, 841ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint unit, 842ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint nr, 843ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint mode, 844d9736db6676948e06712d4bcba46b7040452f870Brian Paul const struct mode_opt *opt) 845ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 84615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg src[3]; 847cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell struct ureg tmp, half; 84822db53577603afef8fdf62c324ff5977de76b9d8Brian Paul GLuint i; 84915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 8500063084804d62402d80821a86978660663955442Brian Paul tmp = undef; /* silence warning (bug 5318) */ 8510063084804d62402d80821a86978660663955442Brian Paul 85215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell for (i = 0; i < nr; i++) 853ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell src[i] = emit_combine_source( p, mask, unit, opt[i].Source, opt[i].Operand ); 85415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 85515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell switch (mode) { 856ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_REPLACE: 85715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell if (mask == WRITEMASK_XYZW && !saturate) 85815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return src[0]; 85915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell else 8607e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_MOV, dest, mask, saturate, src[0], undef, undef ); 861ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_MODULATE: 8627e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_MUL, dest, mask, saturate, 8636fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell src[0], src[1], undef ); 864ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_ADD: 8657e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_ADD, dest, mask, saturate, 8666fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell src[0], src[1], undef ); 867ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_ADD_SIGNED: 86815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* tmp = arg0 + arg1 869cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell * result = tmp - .5 87015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 8712dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell half = get_half(p); 87299da2d30eb08e50edf4b0067518af3acdf2dabc0Jerome Glisse tmp = get_temp( p ); 8737e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_ADD, tmp, mask, 0, src[0], src[1], undef ); 8747e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_SUB, dest, mask, saturate, tmp, half, undef ); 87515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return dest; 876ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_INTERPOLATE: 87715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Arg0 * (Arg2) + Arg1 * (1-Arg2) -- note arguments are reordered: 87815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 8797e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_LRP, dest, mask, saturate, src[2], src[0], src[1] ); 88015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 881ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_SUBTRACT: 8827e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_SUB, dest, mask, saturate, src[0], src[1], undef ); 88315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 884ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGBA: 885ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGBA_EXT: 886ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGB_EXT: 887ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGB: { 88815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg tmp0 = get_temp( p ); 88915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg tmp1 = get_temp( p ); 890e490242b9aeb50bd96fed7a9afbf529295a8ac0eKeith Whitwell struct ureg neg1 = register_scalar_const(p, -1); 891e490242b9aeb50bd96fed7a9afbf529295a8ac0eKeith Whitwell struct ureg two = register_scalar_const(p, 2); 89215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 89315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* tmp0 = 2*src0 - 1 89415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * tmp1 = 2*src1 - 1 89515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 89615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * dst = tmp0 dot3 tmp1 89715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 8987e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_MAD, tmp0, WRITEMASK_XYZW, 0, 8996fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell two, src[0], neg1); 90015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 901aa2069586d434dd0487b0daa2b583efe801a0d51Brian Paul if (_mesa_memcmp(&src[0], &src[1], sizeof(struct ureg)) == 0) 90215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell tmp1 = tmp0; 90315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell else 9047e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_MAD, tmp1, WRITEMASK_XYZW, 0, 9056fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell two, src[1], neg1); 9067e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_DP3, dest, mask, saturate, tmp0, tmp1, undef); 90715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return dest; 90815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 909ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_MODULATE_ADD_ATI: 9106fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell /* Arg0 * Arg2 + Arg1 */ 9117e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_MAD, dest, mask, saturate, 9126fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell src[0], src[2], src[1] ); 913ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_MODULATE_SIGNED_ADD_ATI: { 9146fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell /* Arg0 * Arg2 + Arg1 - 0.5 */ 9156fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell struct ureg tmp0 = get_temp(p); 9162dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell half = get_half(p); 9177e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_MAD, tmp0, mask, 0, src[0], src[2], src[1] ); 9187e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_SUB, dest, mask, saturate, tmp0, half, undef ); 9196fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell return dest; 9206fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell } 921ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_MODULATE_SUBTRACT_ATI: 9226fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell /* Arg0 * Arg2 - Arg1 */ 9237e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_MAD, dest, mask, 0, src[0], src[2], negate(src[1]) ); 9246fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell return dest; 92515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 92615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return src[0]; 92715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 92815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 92915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 93015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 93122db53577603afef8fdf62c324ff5977de76b9d8Brian Paul/** 93222db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * Generate instructions for one texture unit's env/combiner mode. 93322db53577603afef8fdf62c324ff5977de76b9d8Brian Paul */ 93422db53577603afef8fdf62c324ff5977de76b9d8Brian Paulstatic struct ureg 93522db53577603afef8fdf62c324ff5977de76b9d8Brian Paulemit_texenv(struct texenv_fragment_program *p, GLuint unit) 93615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 937ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct state_key *key = p->state; 93822db53577603afef8fdf62c324ff5977de76b9d8Brian Paul GLboolean saturate = (unit < p->last_tex_stage); 93915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint rgb_shift, alpha_shift; 94015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg out, shift; 941cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell struct ureg dest; 94215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 943ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (!key->unit[unit].enabled) { 944ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell return get_source(p, SRC_PREVIOUS, 0); 94515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 946ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 947ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch (key->unit[unit].ModeRGB) { 948ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGB_EXT: 949ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell alpha_shift = key->unit[unit].ScaleShiftA; 95015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell rgb_shift = 0; 95115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 952ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGBA_EXT: 95315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell alpha_shift = 0; 95415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell rgb_shift = 0; 95515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 95615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 957ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell rgb_shift = key->unit[unit].ScaleShiftRGB; 958ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell alpha_shift = key->unit[unit].ScaleShiftA; 95915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 96015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 961ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 962cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell /* If this is the very last calculation, emit direct to output reg: 963cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell */ 964ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->separate_specular || 965cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell unit != p->last_tex_stage || 966cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell alpha_shift || 967cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell rgb_shift) 968cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell dest = get_temp( p ); 969cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell else 97090ebb581e60d29bd565ad4d8a49e642de7b0ce5dBrian Paul dest = make_ureg(PROGRAM_OUTPUT, FRAG_RESULT_COLR); 97115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 97215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Emit the RGB and A combine ops 97315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 974ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->unit[unit].ModeRGB == key->unit[unit].ModeA && 975ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell args_match(key, unit)) { 97615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell out = emit_combine( p, dest, WRITEMASK_XYZW, saturate, 97715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell unit, 978ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].NumArgsRGB, 979ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].ModeRGB, 980ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].OptRGB); 98115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 982ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell else if (key->unit[unit].ModeRGB == MODE_DOT3_RGBA_EXT || 9839a45176dd85a1cd523498efeebd0481950a1bf58Roland Scheidegger key->unit[unit].ModeRGB == MODE_DOT3_RGBA) { 98415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 98515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell out = emit_combine( p, dest, WRITEMASK_XYZW, saturate, 98615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell unit, 987ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].NumArgsRGB, 988ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].ModeRGB, 989ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].OptRGB); 99015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 99115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell else { 99215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Need to do something to stop from re-emitting identical 99315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * argument calculations here: 99415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 99515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell out = emit_combine( p, dest, WRITEMASK_XYZ, saturate, 99615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell unit, 997ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].NumArgsRGB, 998ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].ModeRGB, 999ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].OptRGB); 100015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell out = emit_combine( p, dest, WRITEMASK_W, saturate, 100115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell unit, 1002ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].NumArgsA, 1003ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].ModeA, 1004ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].OptA); 100515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 100615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 100715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Deal with the final shift: 100815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 100915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell if (alpha_shift || rgb_shift) { 101015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell if (rgb_shift == alpha_shift) { 101153174afeeb68a79e471185cb463c13ff90af698fJosé Fonseca shift = register_scalar_const(p, (GLfloat)(1<<rgb_shift)); 101215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 101315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell else { 10142dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell shift = register_const4f(p, 101553174afeeb68a79e471185cb463c13ff90af698fJosé Fonseca (GLfloat)(1<<rgb_shift), 101653174afeeb68a79e471185cb463c13ff90af698fJosé Fonseca (GLfloat)(1<<rgb_shift), 101753174afeeb68a79e471185cb463c13ff90af698fJosé Fonseca (GLfloat)(1<<rgb_shift), 101853174afeeb68a79e471185cb463c13ff90af698fJosé Fonseca (GLfloat)(1<<alpha_shift)); 101915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 10207e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_MUL, dest, WRITEMASK_XYZW, 102115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell saturate, out, shift, undef ); 102215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 102315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell else 102415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return out; 102515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 102615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 10272dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 102822db53577603afef8fdf62c324ff5977de76b9d8Brian Paul/** 102922db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * Generate instruction for getting a texture source term. 103022db53577603afef8fdf62c324ff5977de76b9d8Brian Paul */ 10312dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwellstatic void load_texture( struct texenv_fragment_program *p, GLuint unit ) 10322dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell{ 10332dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell if (is_undef(p->src_texture[unit])) { 1034ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint dim = p->state->unit[unit].source_index; 10352dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell struct ureg texcoord = register_input(p, FRAG_ATTRIB_TEX0+unit); 10362dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell struct ureg tmp = get_tex_temp( p ); 10372dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 1038bfb5ea307ec48b9b8d0d2eca0c03f6d02273d454Brian Paul if (dim == TEXTURE_UNKNOWN_INDEX) 1039bfb5ea307ec48b9b8d0d2eca0c03f6d02273d454Brian Paul program_error(p, "TexSrcBit"); 1040ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 10412dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell /* TODO: Use D0_MASK_XY where possible. 10422dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell */ 10431e3b07f363e6bf512ab1a5c620656985aece40fdBrian if (p->state->unit[unit].enabled) { 1044b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola p->src_texture[unit] = emit_texld( p, OPCODE_TXP, 1045b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola tmp, WRITEMASK_XYZW, 1046b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola unit, dim, texcoord ); 10471e3b07f363e6bf512ab1a5c620656985aece40fdBrian p->program->Base.SamplersUsed |= (1 << unit); 1048fce4612f8a29ee1798c9326a431a139d856c7a04Brian /* This identity mapping should already be in place 1049fce4612f8a29ee1798c9326a431a139d856c7a04Brian * (see _mesa_init_program_struct()) but let's be safe. 1050fce4612f8a29ee1798c9326a431a139d856c7a04Brian */ 1051fce4612f8a29ee1798c9326a431a139d856c7a04Brian p->program->Base.SamplerUnits[unit] = unit; 10521e3b07f363e6bf512ab1a5c620656985aece40fdBrian } 1053b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola else 1054b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola p->src_texture[unit] = get_zero(p); 10552dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell } 10562dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell} 10572dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 1058241b6b7ab1a1a11c7fc516d1b6ff2c1bc8aba238Keith Whitwellstatic GLboolean load_texenv_source( struct texenv_fragment_program *p, 1059ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint src, GLuint unit ) 10602dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell{ 10612dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell switch (src) { 10624dd8a8907e40126e42131a400b59e7d5da5e302aAapo Tahkola case SRC_TEXTURE: 10632dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell load_texture(p, unit); 10642dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell break; 10652dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 1066ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE0: 1067ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE1: 1068ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE2: 1069ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE3: 1070ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE4: 1071ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE5: 1072ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE6: 1073ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE7: 1074ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell load_texture(p, src - SRC_TEXTURE0); 10752dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell break; 10762dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 10772dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell default: 10782dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell break; 10792dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell } 1080241b6b7ab1a1a11c7fc516d1b6ff2c1bc8aba238Keith Whitwell 1081241b6b7ab1a1a11c7fc516d1b6ff2c1bc8aba238Keith Whitwell return GL_TRUE; 10822dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell} 10832dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 108422db53577603afef8fdf62c324ff5977de76b9d8Brian Paul 108522db53577603afef8fdf62c324ff5977de76b9d8Brian Paul/** 108622db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * Generate instructions for loading all texture source terms. 108722db53577603afef8fdf62c324ff5977de76b9d8Brian Paul */ 108822db53577603afef8fdf62c324ff5977de76b9d8Brian Paulstatic GLboolean 108922db53577603afef8fdf62c324ff5977de76b9d8Brian Paulload_texunit_sources( struct texenv_fragment_program *p, int unit ) 10902dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell{ 1091ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct state_key *key = p->state; 1092b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola GLuint i; 1093b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola 1094b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola for (i = 0; i < key->unit[unit].NumArgsRGB; i++) { 1095b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola load_texenv_source( p, key->unit[unit].OptRGB[i].Source, unit); 1096b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola } 1097b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola 1098b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola for (i = 0; i < key->unit[unit].NumArgsA; i++) { 1099b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola load_texenv_source( p, key->unit[unit].OptA[i].Source, unit ); 11002dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell } 1101b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola 1102241b6b7ab1a1a11c7fc516d1b6ff2c1bc8aba238Keith Whitwell return GL_TRUE; 11032dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell} 11042dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 110522db53577603afef8fdf62c324ff5977de76b9d8Brian Paul 110622db53577603afef8fdf62c324ff5977de76b9d8Brian Paul/** 110722db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * Generate a new fragment program which implements the context's 110822db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * current texture env/combine mode. 110922db53577603afef8fdf62c324ff5977de76b9d8Brian Paul */ 111022db53577603afef8fdf62c324ff5977de76b9d8Brian Paulstatic void 1111e998c346471142db91a1bcb6c61551b8247b87e7Brian Paulcreate_new_program(GLcontext *ctx, struct state_key *key, 1112122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul struct gl_fragment_program *program) 111315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 1114e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul struct prog_instruction instBuffer[MAX_INSTRUCTIONS]; 111515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct texenv_fragment_program p; 111615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint unit; 111715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg cf, out; 1118276330b2412910777f7016f427909085f02acbb8Keith Whitwell 1119e490242b9aeb50bd96fed7a9afbf529295a8ac0eKeith Whitwell _mesa_memset(&p, 0, sizeof(p)); 112015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell p.ctx = ctx; 1121ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell p.state = key; 1122ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell p.program = program; 112315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1124e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul /* During code generation, use locally-allocated instruction buffer, 1125e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul * then alloc dynamic storage below. 1126e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul */ 1127e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul p.program->Base.Instructions = instBuffer; 1128276330b2412910777f7016f427909085f02acbb8Keith Whitwell p.program->Base.Target = GL_FRAGMENT_PROGRAM_ARB; 112921f99792a916a62fcfae7c208f50f192d4ce5926Brian p.program->Base.NumTexIndirections = 1; /* correct? */ 113021f99792a916a62fcfae7c208f50f192d4ce5926Brian p.program->Base.NumTexInstructions = 0; 113121f99792a916a62fcfae7c208f50f192d4ce5926Brian p.program->Base.NumAluInstructions = 0; 11321240eb2683043ba81e81378807170d0d7045581dBrian p.program->Base.String = NULL; 11339ca8815d3ba56ad718ba1c48c73aae3cdc0b8db0Keith Whitwell p.program->Base.NumInstructions = 1134e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul p.program->Base.NumTemporaries = 1135e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul p.program->Base.NumParameters = 1136e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul p.program->Base.NumAttributes = p.program->Base.NumAddressRegs = 0; 1137de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul p.program->Base.Parameters = _mesa_new_parameter_list(); 1138dbeea25bb834479a29712100888c862348112018Keith Whitwell 1139de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul p.program->Base.InputsRead = 0; 1140de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul p.program->Base.OutputsWritten = 1 << FRAG_RESULT_COLR; 114115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 11422dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell for (unit = 0; unit < MAX_TEXTURE_UNITS; unit++) 11432dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell p.src_texture[unit] = undef; 11442dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 114547b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell p.src_previous = undef; 11465ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell p.half = undef; 11475ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell p.zero = undef; 11485ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell p.one = undef; 11495ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell 115015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell p.last_tex_stage = 0; 1151f18d4e058ed979c6e42e868c7febde4fa62c5810Brian release_temps(ctx, &p); 115215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1153ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->enabled_units) { 11542dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell /* First pass - to support texture_env_crossbar, first identify 11552dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell * all referenced texture sources and emit texld instructions 11562dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell * for each: 11572dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell */ 115815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell for (unit = 0 ; unit < ctx->Const.MaxTextureUnits ; unit++) 1159ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->unit[unit].enabled) { 1160b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola load_texunit_sources( &p, unit ); 1161b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola p.last_tex_stage = unit; 116215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 116315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 11642dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell /* Second pass - emit combine instructions to build final color: 11652dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell */ 116615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) 1167ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->enabled_units & (1<<unit)) { 116815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell p.src_previous = emit_texenv( &p, unit ); 11698fd329d04885eba7587bbe7604d3a1088e35de40Brian Paul reserve_temp(&p, p.src_previous); /* don't re-use this temp reg */ 1170f18d4e058ed979c6e42e868c7febde4fa62c5810Brian release_temps(ctx, &p); /* release all temps */ 117115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 117215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 117315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1174ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell cf = get_source( &p, SRC_PREVIOUS, 0 ); 117590ebb581e60d29bd565ad4d8a49e642de7b0ce5dBrian Paul out = make_ureg( PROGRAM_OUTPUT, FRAG_RESULT_COLR ); 117615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1177ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->separate_specular) { 117815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Emit specular add. 117915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 118047b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell struct ureg s = register_input(&p, FRAG_ATTRIB_COL1); 11817e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( &p, OPCODE_ADD, out, WRITEMASK_XYZ, 0, cf, s, undef ); 11827e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( &p, OPCODE_MOV, out, WRITEMASK_W, 0, cf, undef, undef ); 118315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 1184aa2069586d434dd0487b0daa2b583efe801a0d51Brian Paul else if (_mesa_memcmp(&cf, &out, sizeof(cf)) != 0) { 118515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Will wind up in here if no texture enabled or a couple of 118615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * other scenarios (GL_REPLACE for instance). 118715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 11887e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( &p, OPCODE_MOV, out, WRITEMASK_XYZW, 0, cf, undef, undef ); 118915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 119015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 119147b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell /* Finish up: 119247b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell */ 11937e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( &p, OPCODE_END, undef, WRITEMASK_XYZW, 0, undef, undef, undef); 119447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell 1195ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->fog_enabled) { 1196ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell /* Pull fog mode from GLcontext, the value in the state key is 1197ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell * a reduced value and not what is expected in FogOption 1198ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell */ 1199276330b2412910777f7016f427909085f02acbb8Keith Whitwell p.program->FogOption = ctx->Fog.Mode; 120063be96bdc7e9f388a5c49295bd7e150462fd003aBrian p.program->Base.InputsRead |= FRAG_BIT_FOGC; /* XXX new */ 1201ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } else 1202276330b2412910777f7016f427909085f02acbb8Keith Whitwell p.program->FogOption = GL_NONE; 120347b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell 120421f99792a916a62fcfae7c208f50f192d4ce5926Brian if (p.program->Base.NumTexIndirections > ctx->Const.FragmentProgram.MaxTexIndirections) 120515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell program_error(&p, "Exceeded max nr indirect texture lookups"); 120615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 120721f99792a916a62fcfae7c208f50f192d4ce5926Brian if (p.program->Base.NumTexInstructions > ctx->Const.FragmentProgram.MaxTexInstructions) 120815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell program_error(&p, "Exceeded max TEX instructions"); 120915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 121021f99792a916a62fcfae7c208f50f192d4ce5926Brian if (p.program->Base.NumAluInstructions > ctx->Const.FragmentProgram.MaxAluInstructions) 121115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell program_error(&p, "Exceeded max ALU instructions"); 121215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 12135d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul ASSERT(p.program->Base.NumInstructions <= MAX_INSTRUCTIONS); 12148b88f62fbd62153500fc3483003f438561366a00Keith Whitwell 1215e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul /* Allocate final instruction array */ 12163bf8d2ac7108a7f0f1722e411161e013bb8573f0Brian p.program->Base.Instructions 12173bf8d2ac7108a7f0f1722e411161e013bb8573f0Brian = _mesa_alloc_instructions(p.program->Base.NumInstructions); 12183bf8d2ac7108a7f0f1722e411161e013bb8573f0Brian if (!p.program->Base.Instructions) { 1219e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, 1220e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul "generating tex env program"); 1221e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul return; 1222e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul } 12233bf8d2ac7108a7f0f1722e411161e013bb8573f0Brian _mesa_copy_instructions(p.program->Base.Instructions, instBuffer, 12243bf8d2ac7108a7f0f1722e411161e013bb8573f0Brian p.program->Base.NumInstructions); 12253bf8d2ac7108a7f0f1722e411161e013bb8573f0Brian 12263bf8d2ac7108a7f0f1722e411161e013bb8573f0Brian if (p.program->FogOption) { 12273bf8d2ac7108a7f0f1722e411161e013bb8573f0Brian _mesa_append_fog_code(ctx, p.program); 12283bf8d2ac7108a7f0f1722e411161e013bb8573f0Brian p.program->FogOption = GL_NONE; 12293bf8d2ac7108a7f0f1722e411161e013bb8573f0Brian } 12303bf8d2ac7108a7f0f1722e411161e013bb8573f0Brian 1231e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul 1232dbeea25bb834479a29712100888c862348112018Keith Whitwell /* Notify driver the fragment program has (actually) changed. 12338b88f62fbd62153500fc3483003f438561366a00Keith Whitwell */ 1234e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul if (ctx->Driver.ProgramStringNotify) { 1235e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul ctx->Driver.ProgramStringNotify( ctx, GL_FRAGMENT_PROGRAM_ARB, 1236e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul &p.program->Base ); 1237e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul } 1238e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul 1239e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul if (DISASSEM) { 1240e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul _mesa_print_program(&p.program->Base); 1241e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul _mesa_printf("\n"); 1242dbeea25bb834479a29712100888c862348112018Keith Whitwell } 124315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 124415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 12455d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul 1246a90046f1097ad95de2aa95ca65741dff5cddced9Brian/** 124783ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian * Return a fragment program which implements the current 124883ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian * fixed-function texture, fog and color-sum operations. 124983ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian */ 125083ce6c51d7189094cf2a13fdcc0882a051a3bd41Brianstruct gl_fragment_program * 125183ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian_mesa_get_fixed_func_fragment_program(GLcontext *ctx) 125283ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian{ 125383ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian struct gl_fragment_program *prog; 125483ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian struct state_key key; 125583ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian 125683ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian make_state_key(ctx, &key); 125783ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian 1258f4a5ea2ccb472958a4635c606e9510011bceaa3dBrian prog = (struct gl_fragment_program *) 1259f4a5ea2ccb472958a4635c606e9510011bceaa3dBrian _mesa_search_program_cache(ctx->FragmentProgram.Cache, 1260f4a5ea2ccb472958a4635c606e9510011bceaa3dBrian &key, sizeof(key)); 126183ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian 126283ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian if (!prog) { 126383ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian prog = (struct gl_fragment_program *) 126483ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0); 126583ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian 126683ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian create_new_program(ctx, &key, prog); 126783ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian 1268f4a5ea2ccb472958a4635c606e9510011bceaa3dBrian _mesa_program_cache_insert(ctx, ctx->FragmentProgram.Cache, 1269f4a5ea2ccb472958a4635c606e9510011bceaa3dBrian &key, sizeof(key), &prog->Base); 127083ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian } 127183ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian 127283ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian return prog; 127383ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian} 127483ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian 127583ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian 127683ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian 127783ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian/** 1278a90046f1097ad95de2aa95ca65741dff5cddced9Brian * If _MaintainTexEnvProgram is set we'll generate a fragment program that 1279a90046f1097ad95de2aa95ca65741dff5cddced9Brian * implements the current texture env/combine mode. 1280a90046f1097ad95de2aa95ca65741dff5cddced9Brian * This function generates that program and puts it into effect. 1281a90046f1097ad95de2aa95ca65741dff5cddced9Brian */ 1282a90046f1097ad95de2aa95ca65741dff5cddced9Brianvoid 1283a90046f1097ad95de2aa95ca65741dff5cddced9Brian_mesa_UpdateTexEnvProgram( GLcontext *ctx ) 1284ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 1285122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul const struct gl_fragment_program *prev = ctx->FragmentProgram._Current; 1286ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 1287a90046f1097ad95de2aa95ca65741dff5cddced9Brian ASSERT(ctx->FragmentProgram._MaintainTexEnvProgram); 1288a90046f1097ad95de2aa95ca65741dff5cddced9Brian 1289a90046f1097ad95de2aa95ca65741dff5cddced9Brian /* If a conventional fragment program/shader isn't in effect... */ 1290efcfdbd4d16071088e60a59cb966abd730d9d111Brian if (!ctx->FragmentProgram._Enabled && 1291d781cdc8fadc802a1f2edbeb13ccb1ee768ce803Brian (!ctx->Shader.CurrentProgram || 1292d781cdc8fadc802a1f2edbeb13ccb1ee768ce803Brian !ctx->Shader.CurrentProgram->FragmentProgram) ) { 1293a90046f1097ad95de2aa95ca65741dff5cddced9Brian 129483ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian ctx->FragmentProgram._Current 129583ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian = ctx->FragmentProgram._TexEnvProgram 129683ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian = _mesa_get_fixed_func_fragment_program(ctx); 1297c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell } 1298c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell 1299c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell /* Tell the driver about the change. Could define a new target for 1300c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell * this? 1301c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell */ 13025d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul if (ctx->FragmentProgram._Current != prev && ctx->Driver.BindProgram) { 13035d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 1304a90046f1097ad95de2aa95ca65741dff5cddced9Brian (struct gl_program *) ctx->FragmentProgram._Current); 13055d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul } 1306ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 1307