ff_fragment_shader.cpp revision 9a45176dd85a1cd523498efeebd0481950a1bf58
115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell/************************************************************************** 215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * Copyright 2003 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" 31a90046f1097ad95de2aa95ca65741dff5cddced9Brian#include "prog_parameter.h" 32a90046f1097ad95de2aa95ca65741dff5cddced9Brian#include "prog_instruction.h" 33a90046f1097ad95de2aa95ca65741dff5cddced9Brian#include "prog_print.h" 34a90046f1097ad95de2aa95ca65741dff5cddced9Brian#include "prog_statevars.h" 3515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell#include "texenvprogram.h" 3615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 37e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul/** 38e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul * According to Glean's texCombine test, no more than 21 instructions 39e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul * are needed. Allow a few extra just in case. 40e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul */ 41e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul#define MAX_INSTRUCTIONS 24 4215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 43269e3895d9837ac7303b91948f003ca5c12c0fe4Keith Whitwell#define DISASSEM (MESA_VERBOSE & VERBOSE_DISASSEM) 4415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 45ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstruct mode_opt { 465d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint Source:4; 475d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint Operand:3; 48ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell}; 49ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 50ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstruct state_key { 515d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLbitfield enabled_units; 525d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint separate_specular:1; 535d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint fog_enabled:1; 545d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint fog_mode:2; 55ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 56ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct { 575d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint enabled:1; 585d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint source_index:3; /* one of TEXTURE_1D/2D/3D/CUBE/RECT_INDEX */ 595d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint ScaleShiftRGB:2; 605d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint ScaleShiftA:2; 61ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 625d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint NumArgsRGB:2; 635d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint ModeRGB:4; 64ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct mode_opt OptRGB[3]; 65ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 665d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint NumArgsA:2; 675d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint ModeA:4; 68ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct mode_opt OptA[3]; 69ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } unit[8]; 70ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell}; 71ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 72ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define FOG_LINEAR 0 73ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define FOG_EXP 1 74ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define FOG_EXP2 2 75ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define FOG_UNKNOWN 3 76ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 77ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstatic GLuint translate_fog_mode( GLenum mode ) 78ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 79ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch (mode) { 80ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_LINEAR: return FOG_LINEAR; 81ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_EXP: return FOG_EXP; 82ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_EXP2: return FOG_EXP2; 83ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell default: return FOG_UNKNOWN; 84ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 85ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 86ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 87ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_SRC_COLOR 0 88ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_ONE_MINUS_SRC_COLOR 1 89ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_SRC_ALPHA 2 90ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_ONE_MINUS_SRC_ALPHA 3 91ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_ZERO 4 92ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_ONE 5 93ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_UNKNOWN 7 94ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 95ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstatic GLuint translate_operand( GLenum operand ) 96ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 97ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch (operand) { 98ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_SRC_COLOR: return OPR_SRC_COLOR; 99ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_ONE_MINUS_SRC_COLOR: return OPR_ONE_MINUS_SRC_COLOR; 100ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_SRC_ALPHA: return OPR_SRC_ALPHA; 101ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_ONE_MINUS_SRC_ALPHA: return OPR_ONE_MINUS_SRC_ALPHA; 102ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_ZERO: return OPR_ZERO; 103ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_ONE: return OPR_ONE; 104ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell default: return OPR_UNKNOWN; 105ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 106ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 107ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 108ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE 0 109ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE0 1 110ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE1 2 111ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE2 3 112ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE3 4 113ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE4 5 114ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE5 6 115ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE6 7 116ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE7 8 117ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_CONSTANT 9 118ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_PRIMARY_COLOR 10 119ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_PREVIOUS 11 120ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_UNKNOWN 15 121ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 122ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstatic GLuint translate_source( GLenum src ) 123ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 124ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch (src) { 125ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE: return SRC_TEXTURE; 126ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE0: 127ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE1: 128ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE2: 129ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE3: 130ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE4: 131ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE5: 132ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE6: 133ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE7: return SRC_TEXTURE0 + (src - GL_TEXTURE0); 134ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_CONSTANT: return SRC_CONSTANT; 135ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_PRIMARY_COLOR: return SRC_PRIMARY_COLOR; 136ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_PREVIOUS: return SRC_PREVIOUS; 137ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell default: return SRC_UNKNOWN; 138ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 139ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 140ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 141ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_REPLACE 0 142ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_MODULATE 1 143ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_ADD 2 144ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_ADD_SIGNED 3 145ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_INTERPOLATE 4 146ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_SUBTRACT 5 147ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_DOT3_RGB 6 148ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_DOT3_RGB_EXT 7 149ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_DOT3_RGBA 8 150ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_DOT3_RGBA_EXT 9 151ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_MODULATE_ADD_ATI 10 152ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_MODULATE_SIGNED_ADD_ATI 11 153ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_MODULATE_SUBTRACT_ATI 12 154ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_UNKNOWN 15 155ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 156ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstatic GLuint translate_mode( GLenum mode ) 157ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 158ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch (mode) { 159ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_REPLACE: return MODE_REPLACE; 160ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_MODULATE: return MODE_MODULATE; 161ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_ADD: return MODE_ADD; 162ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_ADD_SIGNED: return MODE_ADD_SIGNED; 163ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_INTERPOLATE: return MODE_INTERPOLATE; 164ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_SUBTRACT: return MODE_SUBTRACT; 165ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_DOT3_RGB: return MODE_DOT3_RGB; 166ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_DOT3_RGB_EXT: return MODE_DOT3_RGB_EXT; 167ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_DOT3_RGBA: return MODE_DOT3_RGBA; 168ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_DOT3_RGBA_EXT: return MODE_DOT3_RGBA_EXT; 169ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_MODULATE_ADD_ATI: return MODE_MODULATE_ADD_ATI; 170ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_MODULATE_SIGNED_ADD_ATI: return MODE_MODULATE_SIGNED_ADD_ATI; 171ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_MODULATE_SUBTRACT_ATI: return MODE_MODULATE_SUBTRACT_ATI; 172ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell default: return MODE_UNKNOWN; 173ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 174ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 175ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 176ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define TEXTURE_UNKNOWN_INDEX 7 177e00ac11d4dd05c56584622dc2707bbdcfe4b2707Brian Paulstatic GLuint translate_tex_src_bit( GLbitfield bit ) 178ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 179ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch (bit) { 180ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case TEXTURE_1D_BIT: return TEXTURE_1D_INDEX; 181ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case TEXTURE_2D_BIT: return TEXTURE_2D_INDEX; 182ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case TEXTURE_RECT_BIT: return TEXTURE_RECT_INDEX; 183ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case TEXTURE_3D_BIT: return TEXTURE_3D_INDEX; 184ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case TEXTURE_CUBE_BIT: return TEXTURE_CUBE_INDEX; 185ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell default: return TEXTURE_UNKNOWN_INDEX; 186ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 187ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 188ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 18922db53577603afef8fdf62c324ff5977de76b9d8Brian Paul/** 19022db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * Examine current texture environment state and generate a unique 19122db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * key to identify it. 19222db53577603afef8fdf62c324ff5977de76b9d8Brian Paul */ 1938065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwellstatic void make_state_key( GLcontext *ctx, struct state_key *key ) 194ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 195ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint i, j; 196ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 1978065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell memset(key, 0, sizeof(*key)); 1988065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell 199ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell for (i=0;i<MAX_TEXTURE_UNITS;i++) { 200d9736db6676948e06712d4bcba46b7040452f870Brian Paul const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i]; 201ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 202ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (!texUnit->_ReallyEnabled) 203ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell continue; 204ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 205ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].enabled = 1; 206ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->enabled_units |= (1<<i); 207ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 208ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].source_index = 209ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell translate_tex_src_bit(texUnit->_ReallyEnabled); 210ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 211ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].NumArgsRGB = texUnit->_CurrentCombine->_NumArgsRGB; 212ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].NumArgsA = texUnit->_CurrentCombine->_NumArgsA; 213ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 214ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].ModeRGB = 215ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell translate_mode(texUnit->_CurrentCombine->ModeRGB); 216ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].ModeA = 217ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell translate_mode(texUnit->_CurrentCombine->ModeA); 218ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 219ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].ScaleShiftRGB = texUnit->_CurrentCombine->ScaleShiftRGB; 22064da16146fed68605f83ccf3b64075c0d5b6f052Keith Whitwell key->unit[i].ScaleShiftA = texUnit->_CurrentCombine->ScaleShiftA; 221ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 222ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell for (j=0;j<3;j++) { 223ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].OptRGB[j].Operand = 224ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell translate_operand(texUnit->_CurrentCombine->OperandRGB[j]); 225ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].OptA[j].Operand = 226ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell translate_operand(texUnit->_CurrentCombine->OperandA[j]); 227ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].OptRGB[j].Source = 228ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell translate_source(texUnit->_CurrentCombine->SourceRGB[j]); 229ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].OptA[j].Source = 230ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell translate_source(texUnit->_CurrentCombine->SourceA[j]); 231ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 232ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 233ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 234ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) 235ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->separate_specular = 1; 236ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 237ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (ctx->Fog.Enabled) { 238ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->fog_enabled = 1; 239ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->fog_mode = translate_fog_mode(ctx->Fog.Mode); 240ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 241ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 242ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 24315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell/* Use uregs to represent registers internally, translate to Mesa's 24415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * expected formats on emit. 24515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 24615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * NOTE: These are passed by value extensively in this file rather 24715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * than as usual by pointer reference. If this disturbs you, try 24815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * remembering they are just 32bits in size. 24915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 25015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * GCC is smart enough to deal with these dword-sized structures in 25115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * much the same way as if I had defined them as dwords and was using 25215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * macros to access and set the fields. This is much nicer and easier 25315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * to evolve. 25415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 25515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstruct ureg { 25615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint file:4; 25715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint idx:8; 25815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint negatebase:1; 25915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint abs:1; 26015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint negateabs:1; 26115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint swz:12; 26215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint pad:5; 26315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell}; 26415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 26513abf91b42b00c7eb64c373aff3a4c1bb3d8fb7fBrian Paulstatic const struct ureg undef = { 2668d97265711b172da4f387748f0e72da9267492b0Alan Hourihane PROGRAM_UNDEFINED, 26715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell ~0, 26815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 0, 26915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 0, 27015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 0, 27115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 0, 27215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 0 27315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell}; 27415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 27515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 27615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell/* State used to build the fragment program: 27715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 27815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstruct texenv_fragment_program { 279122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul struct gl_fragment_program *program; 28015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLcontext *ctx; 281ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct state_key *state; 28215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 283c8d1741b78eda547762b35a6e4dea7ccb563ffa5Brian Paul GLbitfield alu_temps; /* Track texture indirections, see spec. */ 284c8d1741b78eda547762b35a6e4dea7ccb563ffa5Brian Paul GLbitfield temps_output; /* Track texture indirections, see spec. */ 285c8d1741b78eda547762b35a6e4dea7ccb563ffa5Brian Paul GLbitfield temp_in_use; /* Tracks temporary regs which are in use. */ 28615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLboolean error; 28715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 2882dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell struct ureg src_texture[MAX_TEXTURE_UNITS]; 289ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell /* Reg containing each texture unit's sampled texture color, 290ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell * else undef. 291ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell */ 29215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 29315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg src_previous; /* Reg containing color from previous 29415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * stage. May need to be decl'd. 29515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 29615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 29715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint last_tex_stage; /* Number of last enabled texture unit */ 2982dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 2992dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell struct ureg half; 3002dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell struct ureg one; 3012dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell struct ureg zero; 30215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell}; 30315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 30415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 30515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 30615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg make_ureg(GLuint file, GLuint idx) 30715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 30815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg reg; 30915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.file = file; 31015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.idx = idx; 31115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.negatebase = 0; 31215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.abs = 0; 31315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.negateabs = 0; 31415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.swz = SWIZZLE_NOOP; 31515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.pad = 0; 31615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return reg; 31715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 31815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 31915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg swizzle( struct ureg reg, int x, int y, int z, int w ) 32015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 32115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.swz = MAKE_SWIZZLE4(GET_SWZ(reg.swz, x), 32215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GET_SWZ(reg.swz, y), 32315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GET_SWZ(reg.swz, z), 32415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GET_SWZ(reg.swz, w)); 32515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 32615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return reg; 32715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 32815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 32915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg swizzle1( struct ureg reg, int x ) 33015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 33115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return swizzle(reg, x, x, x, x); 33215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 33315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 3346fe176a64859798db17fbaed6858cccc646aae38Keith Whitwellstatic struct ureg negate( struct ureg reg ) 3356fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell{ 3366fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell reg.negatebase ^= 1; 3376fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell return reg; 3386fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell} 3396fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell 34015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic GLboolean is_undef( struct ureg reg ) 34115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 3428d97265711b172da4f387748f0e72da9267492b0Alan Hourihane return reg.file == PROGRAM_UNDEFINED; 34315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 34415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 345ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 34615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg get_temp( struct texenv_fragment_program *p ) 34715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 34813abf91b42b00c7eb64c373aff3a4c1bb3d8fb7fBrian Paul GLint bit; 349ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 350cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell /* First try and reuse temps which have been used already: 351ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell */ 352b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul bit = _mesa_ffs( ~p->temp_in_use & p->alu_temps ); 353ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 354ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell /* Then any unused temporary: 355ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell */ 356ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell if (!bit) 357b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul bit = _mesa_ffs( ~p->temp_in_use ); 358ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 359ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell if (!bit) { 360bfb5ea307ec48b9b8d0d2eca0c03f6d02273d454Brian Paul _mesa_problem(NULL, "%s: out of temporaries\n", __FILE__); 361b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul _mesa_exit(1); 362ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell } 363ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 36413abf91b42b00c7eb64c373aff3a4c1bb3d8fb7fBrian Paul if ((GLuint) bit > p->program->Base.NumTemporaries) 365b5cbaf945dd5213d5faf7bb7e4d68d0d25a25b55Keith Whitwell p->program->Base.NumTemporaries = bit; 366b5cbaf945dd5213d5faf7bb7e4d68d0d25a25b55Keith Whitwell 36793cd9237d793e38ba4479d1367be7548853f67f4Keith Whitwell p->temp_in_use |= 1<<(bit-1); 368ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell return make_ureg(PROGRAM_TEMPORARY, (bit-1)); 369ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell} 370ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 371ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwellstatic struct ureg get_tex_temp( struct texenv_fragment_program *p ) 372ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell{ 373ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell int bit; 374ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 375cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell /* First try to find availble temp not previously used (to avoid 376cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell * starting a new texture indirection). According to the spec, the 377cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell * ~p->temps_output isn't necessary, but will keep it there for 378cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell * now: 379ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell */ 380b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul bit = _mesa_ffs( ~p->temp_in_use & ~p->alu_temps & ~p->temps_output ); 381ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 382ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell /* Then any unused temporary: 383ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell */ 384cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if (!bit) 385b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul bit = _mesa_ffs( ~p->temp_in_use ); 386ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 38715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell if (!bit) { 388bfb5ea307ec48b9b8d0d2eca0c03f6d02273d454Brian Paul _mesa_problem(NULL, "%s: out of temporaries\n", __FILE__); 389b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul _mesa_exit(1); 39015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 39115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 39213abf91b42b00c7eb64c373aff3a4c1bb3d8fb7fBrian Paul if ((GLuint) bit > p->program->Base.NumTemporaries) 393b5cbaf945dd5213d5faf7bb7e4d68d0d25a25b55Keith Whitwell p->program->Base.NumTemporaries = bit; 394b5cbaf945dd5213d5faf7bb7e4d68d0d25a25b55Keith Whitwell 39593cd9237d793e38ba4479d1367be7548853f67f4Keith Whitwell p->temp_in_use |= 1<<(bit-1); 39615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return make_ureg(PROGRAM_TEMPORARY, (bit-1)); 39715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 39815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 39915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 40015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic void release_temps( struct texenv_fragment_program *p ) 40115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 40205051037101dfa053798cf5ad91d1975fd1aa6a7Brian Paul GLuint max_temp = p->ctx->Const.FragmentProgram.MaxTemps; 40393cd9237d793e38ba4479d1367be7548853f67f4Keith Whitwell 4042dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell /* KW: To support tex_env_crossbar, don't release the registers in 4052dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell * temps_output. 4062dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell */ 40793cd9237d793e38ba4479d1367be7548853f67f4Keith Whitwell if (max_temp >= sizeof(int) * 8) 4082dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell p->temp_in_use = p->temps_output; 40993cd9237d793e38ba4479d1367be7548853f67f4Keith Whitwell else 4102dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell p->temp_in_use = ~((1<<max_temp)-1) | p->temps_output; 41115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 41215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 41315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 4149fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brianstatic struct ureg register_param5( struct texenv_fragment_program *p, 415ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLint s0, 416ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLint s1, 417ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLint s2, 418ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLint s3, 4199fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brian GLint s4) 42015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 4219fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brian gl_state_index tokens[STATE_LENGTH]; 42247b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell GLuint idx; 42347b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell tokens[0] = s0; 42447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell tokens[1] = s1; 42547b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell tokens[2] = s2; 42647b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell tokens[3] = s3; 42747b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell tokens[4] = s4; 428de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul idx = _mesa_add_state_reference( p->program->Base.Parameters, tokens ); 42947b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell return make_ureg(PROGRAM_STATE_VAR, idx); 43047b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell} 43115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 43215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 4339fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brian#define register_param1(p,s0) register_param5(p,s0,0,0,0,0) 4349fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brian#define register_param2(p,s0,s1) register_param5(p,s0,s1,0,0,0) 4359fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brian#define register_param3(p,s0,s1,s2) register_param5(p,s0,s1,s2,0,0) 4369fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brian#define register_param4(p,s0,s1,s2,s3) register_param5(p,s0,s1,s2,s3,0) 43747b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell 43847b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell 43947b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwellstatic struct ureg register_input( struct texenv_fragment_program *p, GLuint input ) 44047b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell{ 441de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul p->program->Base.InputsRead |= (1 << input); 44247b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell return make_ureg(PROGRAM_INPUT, input); 44315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 44415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 44547b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell 4467e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paulstatic void emit_arg( struct prog_src_register *reg, 44715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg ureg ) 44815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 44915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg->File = ureg.file; 45015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg->Index = ureg.idx; 45115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg->Swizzle = ureg.swz; 452f2802c40fff686301a7ff99f0a0b1c57d5cf5625Keith Whitwell reg->NegateBase = ureg.negatebase ? 0xf : 0x0; 45315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg->Abs = ureg.abs; 45415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg->NegateAbs = ureg.negateabs; 45515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 45615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 4577e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paulstatic void emit_dst( struct prog_dst_register *dst, 45815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg ureg, GLuint mask ) 45915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 46015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell dst->File = ureg.file; 46115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell dst->Index = ureg.idx; 46215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell dst->WriteMask = mask; 46315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell dst->CondMask = 0; 46415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell dst->CondSwizzle = 0; 46515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 46615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 4677e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paulstatic struct prog_instruction * 46815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellemit_op(struct texenv_fragment_program *p, 4695d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul enum prog_opcode op, 47015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg dest, 47115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint mask, 47222db53577603afef8fdf62c324ff5977de76b9d8Brian Paul GLboolean saturate, 47315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg src0, 47415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg src1, 47515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg src2 ) 47615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 47747b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell GLuint nr = p->program->Base.NumInstructions++; 478de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul struct prog_instruction *inst = &p->program->Base.Instructions[nr]; 47915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 480d6272e06172f7ac7a0d6e8062e8ffba33e1ab3baBrian Paul _mesa_init_instructions(inst, 1); 48115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell inst->Opcode = op; 48215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 48347b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell emit_arg( &inst->SrcReg[0], src0 ); 48447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell emit_arg( &inst->SrcReg[1], src1 ); 48547b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell emit_arg( &inst->SrcReg[2], src2 ); 48615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 487e31ac052236ea615b4995f9ec301d8af4b864531Brian Paul inst->SaturateMode = saturate ? SATURATE_ZERO_ONE : SATURATE_OFF; 48815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 48915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell emit_dst( &inst->DstReg, dest, mask ); 49015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 491cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell /* Accounting for indirection tracking: 492cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell */ 493cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if (dest.file == PROGRAM_TEMPORARY) 494cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell p->temps_output |= 1 << dest.idx; 495cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell 49615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return inst; 49715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 49815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 49915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 50015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg emit_arith( struct texenv_fragment_program *p, 5015d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul enum prog_opcode op, 50247b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell struct ureg dest, 50347b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell GLuint mask, 50422db53577603afef8fdf62c324ff5977de76b9d8Brian Paul GLboolean saturate, 50547b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell struct ureg src0, 50647b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell struct ureg src1, 50747b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell struct ureg src2 ) 50815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 50915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell emit_op(p, op, dest, mask, saturate, src0, src1, src2); 51015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 511cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell /* Accounting for indirection tracking: 512cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell */ 513cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if (src0.file == PROGRAM_TEMPORARY) 514cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell p->alu_temps |= 1 << src0.idx; 515cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell 516cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if (!is_undef(src1) && src1.file == PROGRAM_TEMPORARY) 517cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell p->alu_temps |= 1 << src1.idx; 518cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell 519cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if (!is_undef(src2) && src2.file == PROGRAM_TEMPORARY) 520cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell p->alu_temps |= 1 << src2.idx; 521cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell 522cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if (dest.file == PROGRAM_TEMPORARY) 523cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell p->alu_temps |= 1 << dest.idx; 524cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell 52521f99792a916a62fcfae7c208f50f192d4ce5926Brian p->program->Base.NumAluInstructions++; 52615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return dest; 52715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 52815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 52915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg emit_texld( struct texenv_fragment_program *p, 5305d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul enum prog_opcode op, 531ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct ureg dest, 532ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint destmask, 533ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint tex_unit, 534ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint tex_idx, 535ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct ureg coord ) 53615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 5377e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul struct prog_instruction *inst = emit_op( p, op, 53815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell dest, destmask, 53922db53577603afef8fdf62c324ff5977de76b9d8Brian Paul GL_FALSE, /* don't saturate? */ 54015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell coord, /* arg 0? */ 54115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell undef, 54215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell undef); 54315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 5447e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul inst->TexSrcTarget = tex_idx; 54515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell inst->TexSrcUnit = tex_unit; 54615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 54721f99792a916a62fcfae7c208f50f192d4ce5926Brian p->program->Base.NumTexInstructions++; 54815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 549cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell /* Is this a texture indirection? 550cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell */ 551cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if ((coord.file == PROGRAM_TEMPORARY && 552cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell (p->temps_output & (1<<coord.idx))) || 553cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell (dest.file == PROGRAM_TEMPORARY && 554cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell (p->alu_temps & (1<<dest.idx)))) { 55521f99792a916a62fcfae7c208f50f192d4ce5926Brian p->program->Base.NumTexIndirections++; 5562dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell p->temps_output = 1<<coord.idx; 557cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell p->alu_temps = 0; 5582dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell assert(0); /* KW: texture env crossbar */ 55915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 56015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 56115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return dest; 56215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 56315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 56415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 56547b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwellstatic struct ureg register_const4f( struct texenv_fragment_program *p, 566ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLfloat s0, 567ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLfloat s1, 568ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLfloat s2, 569ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLfloat s3) 57015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 57147b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell GLfloat values[4]; 572a90046f1097ad95de2aa95ca65741dff5cddced9Brian GLuint idx, swizzle; 57347b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell values[0] = s0; 57447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell values[1] = s1; 57547b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell values[2] = s2; 57647b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell values[3] = s3; 577a90046f1097ad95de2aa95ca65741dff5cddced9Brian idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4, 578a90046f1097ad95de2aa95ca65741dff5cddced9Brian &swizzle ); 579a90046f1097ad95de2aa95ca65741dff5cddced9Brian ASSERT(swizzle == SWIZZLE_NOOP); 58047b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell return make_ureg(PROGRAM_STATE_VAR, idx); 58115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 58215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 583e490242b9aeb50bd96fed7a9afbf529295a8ac0eKeith Whitwell#define register_scalar_const(p, s0) register_const4f(p, s0, s0, s0, s0) 58447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell#define register_const1f(p, s0) register_const4f(p, s0, 0, 0, 1) 58547b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell#define register_const2f(p, s0, s1) register_const4f(p, s0, s1, 0, 1) 58647b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell#define register_const3f(p, s0, s1, s2) register_const4f(p, s0, s1, s2, 1) 58715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 58815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 5892dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwellstatic struct ureg get_one( struct texenv_fragment_program *p ) 5902dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell{ 5912dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell if (is_undef(p->one)) 5922dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell p->one = register_scalar_const(p, 1.0); 5932dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell return p->one; 5942dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell} 5952dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 5962dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwellstatic struct ureg get_half( struct texenv_fragment_program *p ) 5972dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell{ 5982dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell if (is_undef(p->half)) 5994dd8a8907e40126e42131a400b59e7d5da5e302aAapo Tahkola p->half = register_scalar_const(p, 0.5); 6002dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell return p->half; 6012dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell} 6022dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 6032dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwellstatic struct ureg get_zero( struct texenv_fragment_program *p ) 6042dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell{ 6052dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell if (is_undef(p->zero)) 6064dd8a8907e40126e42131a400b59e7d5da5e302aAapo Tahkola p->zero = register_scalar_const(p, 0.0); 6072dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell return p->zero; 6082dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell} 6092dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 61015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 61115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic void program_error( struct texenv_fragment_program *p, const char *msg ) 61215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 613bfb5ea307ec48b9b8d0d2eca0c03f6d02273d454Brian Paul _mesa_problem(NULL, msg); 61415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell p->error = 1; 61515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 61615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 61715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg get_source( struct texenv_fragment_program *p, 618ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint src, GLuint unit ) 61915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 62015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell switch (src) { 621ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE: 6222dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell assert(!is_undef(p->src_texture[unit])); 6232dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell return p->src_texture[unit]; 62415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 625ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE0: 626ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE1: 627ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE2: 628ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE3: 629ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE4: 630ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE5: 631ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE6: 632ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE7: 633ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell assert(!is_undef(p->src_texture[src - SRC_TEXTURE0])); 634ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell return p->src_texture[src - SRC_TEXTURE0]; 635ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 636ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_CONSTANT: 63747b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell return register_param2(p, STATE_TEXENV_COLOR, unit); 6382dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 639ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_PRIMARY_COLOR: 64047b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell return register_input(p, FRAG_ATTRIB_COL0); 6412dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 642ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_PREVIOUS: 643ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell default: 64447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell if (is_undef(p->src_previous)) 64547b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell return register_input(p, FRAG_ATTRIB_COL0); 64647b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell else 64747b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell return p->src_previous; 64815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 64915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 6502dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 65115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg emit_combine_source( struct texenv_fragment_program *p, 652ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint mask, 653ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint unit, 654ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint source, 655ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint operand ) 65615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 65715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg arg, src, one; 65815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 65915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell src = get_source(p, source, unit); 66015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 66115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell switch (operand) { 662ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE_MINUS_SRC_COLOR: 66315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Get unused tmp, 66415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * Emit tmp = 1.0 - arg.xyzw 66515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 66615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell arg = get_temp( p ); 6672dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell one = get_one( p ); 6687e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_SUB, arg, mask, 0, one, src, undef); 66915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 670ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_SRC_ALPHA: 67115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell if (mask == WRITEMASK_W) 67215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return src; 67315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell else 67422db53577603afef8fdf62c324ff5977de76b9d8Brian Paul return swizzle1( src, SWIZZLE_W ); 675ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE_MINUS_SRC_ALPHA: 67615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Get unused tmp, 67715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * Emit tmp = 1.0 - arg.wwww 67815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 6792dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell arg = get_temp(p); 6802dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell one = get_one(p); 6817e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith(p, OPCODE_SUB, arg, mask, 0, 68222db53577603afef8fdf62c324ff5977de76b9d8Brian Paul one, swizzle1(src, SWIZZLE_W), undef); 683ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ZERO: 6842dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell return get_zero(p); 685ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE: 6862dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell return get_one(p); 687ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_SRC_COLOR: 68815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 68915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return src; 69015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 69115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 69215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 693ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstatic GLboolean args_match( struct state_key *key, GLuint unit ) 69415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 69522db53577603afef8fdf62c324ff5977de76b9d8Brian Paul GLuint i, nr = key->unit[unit].NumArgsRGB; 69615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 69715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell for (i = 0 ; i < nr ; i++) { 698ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->unit[unit].OptA[i].Source != key->unit[unit].OptRGB[i].Source) 69915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return GL_FALSE; 70015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 701ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch(key->unit[unit].OptA[i].Operand) { 702ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_SRC_ALPHA: 703ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch(key->unit[unit].OptRGB[i].Operand) { 704ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_SRC_COLOR: 705ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_SRC_ALPHA: 70615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 70715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 70815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return GL_FALSE; 70915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 71015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 711ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE_MINUS_SRC_ALPHA: 712ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch(key->unit[unit].OptRGB[i].Operand) { 713ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE_MINUS_SRC_COLOR: 714ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE_MINUS_SRC_ALPHA: 71515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 71615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 71715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return GL_FALSE; 71815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 71915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 72015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 72115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return GL_FALSE; /* impossible */ 72215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 72315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 72415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 72515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return GL_TRUE; 72615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 72715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 72815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg emit_combine( struct texenv_fragment_program *p, 729ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct ureg dest, 730ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint mask, 73122db53577603afef8fdf62c324ff5977de76b9d8Brian Paul GLboolean saturate, 732ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint unit, 733ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint nr, 734ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint mode, 735d9736db6676948e06712d4bcba46b7040452f870Brian Paul const struct mode_opt *opt) 736ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 73715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg src[3]; 738cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell struct ureg tmp, half; 73922db53577603afef8fdf62c324ff5977de76b9d8Brian Paul GLuint i; 74015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 7410063084804d62402d80821a86978660663955442Brian Paul tmp = undef; /* silence warning (bug 5318) */ 7420063084804d62402d80821a86978660663955442Brian Paul 74315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell for (i = 0; i < nr; i++) 744ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell src[i] = emit_combine_source( p, mask, unit, opt[i].Source, opt[i].Operand ); 74515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 74615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell switch (mode) { 747ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_REPLACE: 74815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell if (mask == WRITEMASK_XYZW && !saturate) 74915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return src[0]; 75015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell else 7517e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_MOV, dest, mask, saturate, src[0], undef, undef ); 752ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_MODULATE: 7537e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_MUL, dest, mask, saturate, 7546fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell src[0], src[1], undef ); 755ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_ADD: 7567e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_ADD, dest, mask, saturate, 7576fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell src[0], src[1], undef ); 758ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_ADD_SIGNED: 75915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* tmp = arg0 + arg1 760cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell * result = tmp - .5 76115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 7622dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell half = get_half(p); 76399da2d30eb08e50edf4b0067518af3acdf2dabc0Jerome Glisse tmp = get_temp( p ); 7647e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_ADD, tmp, mask, 0, src[0], src[1], undef ); 7657e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_SUB, dest, mask, saturate, tmp, half, undef ); 76615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return dest; 767ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_INTERPOLATE: 76815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Arg0 * (Arg2) + Arg1 * (1-Arg2) -- note arguments are reordered: 76915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 7707e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_LRP, dest, mask, saturate, src[2], src[0], src[1] ); 77115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 772ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_SUBTRACT: 7737e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_SUB, dest, mask, saturate, src[0], src[1], undef ); 77415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 775ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGBA: 776ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGBA_EXT: 777ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGB_EXT: 778ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGB: { 77915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg tmp0 = get_temp( p ); 78015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg tmp1 = get_temp( p ); 781e490242b9aeb50bd96fed7a9afbf529295a8ac0eKeith Whitwell struct ureg neg1 = register_scalar_const(p, -1); 782e490242b9aeb50bd96fed7a9afbf529295a8ac0eKeith Whitwell struct ureg two = register_scalar_const(p, 2); 78315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 78415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* tmp0 = 2*src0 - 1 78515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * tmp1 = 2*src1 - 1 78615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 78715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * dst = tmp0 dot3 tmp1 78815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 7897e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_MAD, tmp0, WRITEMASK_XYZW, 0, 7906fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell two, src[0], neg1); 79115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 792aa2069586d434dd0487b0daa2b583efe801a0d51Brian Paul if (_mesa_memcmp(&src[0], &src[1], sizeof(struct ureg)) == 0) 79315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell tmp1 = tmp0; 79415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell else 7957e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_MAD, tmp1, WRITEMASK_XYZW, 0, 7966fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell two, src[1], neg1); 7977e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_DP3, dest, mask, saturate, tmp0, tmp1, undef); 79815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return dest; 79915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 800ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_MODULATE_ADD_ATI: 8016fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell /* Arg0 * Arg2 + Arg1 */ 8027e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_MAD, dest, mask, saturate, 8036fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell src[0], src[2], src[1] ); 804ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_MODULATE_SIGNED_ADD_ATI: { 8056fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell /* Arg0 * Arg2 + Arg1 - 0.5 */ 8066fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell struct ureg tmp0 = get_temp(p); 8072dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell half = get_half(p); 8087e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_MAD, tmp0, mask, 0, src[0], src[2], src[1] ); 8097e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_SUB, dest, mask, saturate, tmp0, half, undef ); 8106fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell return dest; 8116fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell } 812ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_MODULATE_SUBTRACT_ATI: 8136fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell /* Arg0 * Arg2 - Arg1 */ 8147e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_MAD, dest, mask, 0, src[0], src[2], negate(src[1]) ); 8156fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell return dest; 81615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 81715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return src[0]; 81815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 81915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 82015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 82115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 82222db53577603afef8fdf62c324ff5977de76b9d8Brian Paul/** 82322db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * Generate instructions for one texture unit's env/combiner mode. 82422db53577603afef8fdf62c324ff5977de76b9d8Brian Paul */ 82522db53577603afef8fdf62c324ff5977de76b9d8Brian Paulstatic struct ureg 82622db53577603afef8fdf62c324ff5977de76b9d8Brian Paulemit_texenv(struct texenv_fragment_program *p, GLuint unit) 82715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 828ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct state_key *key = p->state; 82922db53577603afef8fdf62c324ff5977de76b9d8Brian Paul GLboolean saturate = (unit < p->last_tex_stage); 83015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint rgb_shift, alpha_shift; 83115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg out, shift; 832cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell struct ureg dest; 83315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 834ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (!key->unit[unit].enabled) { 835ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell return get_source(p, SRC_PREVIOUS, 0); 83615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 837ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 838ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch (key->unit[unit].ModeRGB) { 839ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGB_EXT: 840ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell alpha_shift = key->unit[unit].ScaleShiftA; 84115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell rgb_shift = 0; 84215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 843ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGBA_EXT: 84415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell alpha_shift = 0; 84515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell rgb_shift = 0; 84615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 84715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 848ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell rgb_shift = key->unit[unit].ScaleShiftRGB; 849ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell alpha_shift = key->unit[unit].ScaleShiftA; 85015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 85115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 852ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 853cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell /* If this is the very last calculation, emit direct to output reg: 854cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell */ 855ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->separate_specular || 856cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell unit != p->last_tex_stage || 857cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell alpha_shift || 858cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell rgb_shift) 859cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell dest = get_temp( p ); 860cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell else 86190ebb581e60d29bd565ad4d8a49e642de7b0ce5dBrian Paul dest = make_ureg(PROGRAM_OUTPUT, FRAG_RESULT_COLR); 86215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 86315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Emit the RGB and A combine ops 86415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 865ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->unit[unit].ModeRGB == key->unit[unit].ModeA && 866ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell args_match(key, unit)) { 86715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell out = emit_combine( p, dest, WRITEMASK_XYZW, saturate, 86815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell unit, 869ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].NumArgsRGB, 870ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].ModeRGB, 871ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].OptRGB); 87215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 873ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell else if (key->unit[unit].ModeRGB == MODE_DOT3_RGBA_EXT || 8749a45176dd85a1cd523498efeebd0481950a1bf58Roland Scheidegger key->unit[unit].ModeRGB == MODE_DOT3_RGBA) { 87515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 87615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell out = emit_combine( p, dest, WRITEMASK_XYZW, saturate, 87715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell unit, 878ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].NumArgsRGB, 879ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].ModeRGB, 880ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].OptRGB); 88115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 88215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell else { 88315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Need to do something to stop from re-emitting identical 88415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * argument calculations here: 88515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 88615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell out = emit_combine( p, dest, WRITEMASK_XYZ, saturate, 88715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell unit, 888ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].NumArgsRGB, 889ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].ModeRGB, 890ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].OptRGB); 89115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell out = emit_combine( p, dest, WRITEMASK_W, saturate, 89215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell unit, 893ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].NumArgsA, 894ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].ModeA, 895ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].OptA); 89615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 89715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 89815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Deal with the final shift: 89915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 90015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell if (alpha_shift || rgb_shift) { 90115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell if (rgb_shift == alpha_shift) { 902e490242b9aeb50bd96fed7a9afbf529295a8ac0eKeith Whitwell shift = register_scalar_const(p, 1<<rgb_shift); 90315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 90415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell else { 9052dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell shift = register_const4f(p, 9062dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 1<<rgb_shift, 9072dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 1<<rgb_shift, 9082dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 1<<rgb_shift, 9092dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 1<<alpha_shift); 91015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 9117e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_MUL, dest, WRITEMASK_XYZW, 91215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell saturate, out, shift, undef ); 91315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 91415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell else 91515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return out; 91615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 91715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 9182dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 91922db53577603afef8fdf62c324ff5977de76b9d8Brian Paul/** 92022db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * Generate instruction for getting a texture source term. 92122db53577603afef8fdf62c324ff5977de76b9d8Brian Paul */ 9222dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwellstatic void load_texture( struct texenv_fragment_program *p, GLuint unit ) 9232dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell{ 9242dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell if (is_undef(p->src_texture[unit])) { 925ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint dim = p->state->unit[unit].source_index; 9262dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell struct ureg texcoord = register_input(p, FRAG_ATTRIB_TEX0+unit); 9272dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell struct ureg tmp = get_tex_temp( p ); 9282dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 929bfb5ea307ec48b9b8d0d2eca0c03f6d02273d454Brian Paul if (dim == TEXTURE_UNKNOWN_INDEX) 930bfb5ea307ec48b9b8d0d2eca0c03f6d02273d454Brian Paul program_error(p, "TexSrcBit"); 931ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 9322dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell /* TODO: Use D0_MASK_XY where possible. 9332dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell */ 934b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola if (p->state->unit[unit].enabled) 935b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola p->src_texture[unit] = emit_texld( p, OPCODE_TXP, 936b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola tmp, WRITEMASK_XYZW, 937b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola unit, dim, texcoord ); 938b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola else 939b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola p->src_texture[unit] = get_zero(p); 9402dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell } 9412dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell} 9422dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 943241b6b7ab1a1a11c7fc516d1b6ff2c1bc8aba238Keith Whitwellstatic GLboolean load_texenv_source( struct texenv_fragment_program *p, 944ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint src, GLuint unit ) 9452dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell{ 9462dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell switch (src) { 9474dd8a8907e40126e42131a400b59e7d5da5e302aAapo Tahkola case SRC_TEXTURE: 9482dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell load_texture(p, unit); 9492dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell break; 9502dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 951ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE0: 952ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE1: 953ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE2: 954ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE3: 955ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE4: 956ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE5: 957ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE6: 958ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE7: 959ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell load_texture(p, src - SRC_TEXTURE0); 9602dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell break; 9612dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 9622dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell default: 9632dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell break; 9642dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell } 965241b6b7ab1a1a11c7fc516d1b6ff2c1bc8aba238Keith Whitwell 966241b6b7ab1a1a11c7fc516d1b6ff2c1bc8aba238Keith Whitwell return GL_TRUE; 9672dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell} 9682dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 96922db53577603afef8fdf62c324ff5977de76b9d8Brian Paul 97022db53577603afef8fdf62c324ff5977de76b9d8Brian Paul/** 97122db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * Generate instructions for loading all texture source terms. 97222db53577603afef8fdf62c324ff5977de76b9d8Brian Paul */ 97322db53577603afef8fdf62c324ff5977de76b9d8Brian Paulstatic GLboolean 97422db53577603afef8fdf62c324ff5977de76b9d8Brian Paulload_texunit_sources( struct texenv_fragment_program *p, int unit ) 9752dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell{ 976ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct state_key *key = p->state; 977b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola GLuint i; 978b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola 979b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola for (i = 0; i < key->unit[unit].NumArgsRGB; i++) { 980b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola load_texenv_source( p, key->unit[unit].OptRGB[i].Source, unit); 981b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola } 982b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola 983b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola for (i = 0; i < key->unit[unit].NumArgsA; i++) { 984b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola load_texenv_source( p, key->unit[unit].OptA[i].Source, unit ); 9852dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell } 986b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola 987241b6b7ab1a1a11c7fc516d1b6ff2c1bc8aba238Keith Whitwell return GL_TRUE; 9882dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell} 9892dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 99022db53577603afef8fdf62c324ff5977de76b9d8Brian Paul 99122db53577603afef8fdf62c324ff5977de76b9d8Brian Paul/** 99222db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * Generate a new fragment program which implements the context's 99322db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * current texture env/combine mode. 99422db53577603afef8fdf62c324ff5977de76b9d8Brian Paul */ 99522db53577603afef8fdf62c324ff5977de76b9d8Brian Paulstatic void 996e998c346471142db91a1bcb6c61551b8247b87e7Brian Paulcreate_new_program(GLcontext *ctx, struct state_key *key, 997122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul struct gl_fragment_program *program) 99815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 999e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul struct prog_instruction instBuffer[MAX_INSTRUCTIONS]; 100015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct texenv_fragment_program p; 100115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint unit; 100215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg cf, out; 1003276330b2412910777f7016f427909085f02acbb8Keith Whitwell 1004e490242b9aeb50bd96fed7a9afbf529295a8ac0eKeith Whitwell _mesa_memset(&p, 0, sizeof(p)); 100515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell p.ctx = ctx; 1006ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell p.state = key; 1007ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell p.program = program; 100815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1009e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul /* During code generation, use locally-allocated instruction buffer, 1010e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul * then alloc dynamic storage below. 1011e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul */ 1012e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul p.program->Base.Instructions = instBuffer; 1013276330b2412910777f7016f427909085f02acbb8Keith Whitwell p.program->Base.Target = GL_FRAGMENT_PROGRAM_ARB; 101421f99792a916a62fcfae7c208f50f192d4ce5926Brian p.program->Base.NumTexIndirections = 1; /* correct? */ 101521f99792a916a62fcfae7c208f50f192d4ce5926Brian p.program->Base.NumTexInstructions = 0; 101621f99792a916a62fcfae7c208f50f192d4ce5926Brian p.program->Base.NumAluInstructions = 0; 10171240eb2683043ba81e81378807170d0d7045581dBrian p.program->Base.String = NULL; 10189ca8815d3ba56ad718ba1c48c73aae3cdc0b8db0Keith Whitwell p.program->Base.NumInstructions = 1019e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul p.program->Base.NumTemporaries = 1020e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul p.program->Base.NumParameters = 1021e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul p.program->Base.NumAttributes = p.program->Base.NumAddressRegs = 0; 1022de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul p.program->Base.Parameters = _mesa_new_parameter_list(); 1023dbeea25bb834479a29712100888c862348112018Keith Whitwell 1024de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul p.program->Base.InputsRead = 0; 1025de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul p.program->Base.OutputsWritten = 1 << FRAG_RESULT_COLR; 102615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 10272dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell for (unit = 0; unit < MAX_TEXTURE_UNITS; unit++) 10282dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell p.src_texture[unit] = undef; 10292dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 103047b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell p.src_previous = undef; 10315ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell p.half = undef; 10325ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell p.zero = undef; 10335ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell p.one = undef; 10345ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell 103515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell p.last_tex_stage = 0; 103693cd9237d793e38ba4479d1367be7548853f67f4Keith Whitwell release_temps(&p); 103715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1038ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->enabled_units) { 10392dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell /* First pass - to support texture_env_crossbar, first identify 10402dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell * all referenced texture sources and emit texld instructions 10412dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell * for each: 10422dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell */ 104315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell for (unit = 0 ; unit < ctx->Const.MaxTextureUnits ; unit++) 1044ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->unit[unit].enabled) { 1045b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola load_texunit_sources( &p, unit ); 1046b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola p.last_tex_stage = unit; 104715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 104815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 10492dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell /* Second pass - emit combine instructions to build final color: 10502dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell */ 105115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) 1052ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->enabled_units & (1<<unit)) { 105315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell p.src_previous = emit_texenv( &p, unit ); 105493cd9237d793e38ba4479d1367be7548853f67f4Keith Whitwell release_temps(&p); /* release all temps */ 105515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 105615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 105715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1058ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell cf = get_source( &p, SRC_PREVIOUS, 0 ); 105990ebb581e60d29bd565ad4d8a49e642de7b0ce5dBrian Paul out = make_ureg( PROGRAM_OUTPUT, FRAG_RESULT_COLR ); 106015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1061ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->separate_specular) { 106215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Emit specular add. 106315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 106447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell struct ureg s = register_input(&p, FRAG_ATTRIB_COL1); 10657e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( &p, OPCODE_ADD, out, WRITEMASK_XYZ, 0, cf, s, undef ); 10667e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( &p, OPCODE_MOV, out, WRITEMASK_W, 0, cf, undef, undef ); 106715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 1068aa2069586d434dd0487b0daa2b583efe801a0d51Brian Paul else if (_mesa_memcmp(&cf, &out, sizeof(cf)) != 0) { 106915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Will wind up in here if no texture enabled or a couple of 107015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * other scenarios (GL_REPLACE for instance). 107115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 10727e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( &p, OPCODE_MOV, out, WRITEMASK_XYZW, 0, cf, undef, undef ); 107315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 107415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 107547b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell /* Finish up: 107647b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell */ 10777e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( &p, OPCODE_END, undef, WRITEMASK_XYZW, 0, undef, undef, undef); 107847b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell 1079ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->fog_enabled) { 1080ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell /* Pull fog mode from GLcontext, the value in the state key is 1081ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell * a reduced value and not what is expected in FogOption 1082ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell */ 1083276330b2412910777f7016f427909085f02acbb8Keith Whitwell p.program->FogOption = ctx->Fog.Mode; 1084ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } else 1085276330b2412910777f7016f427909085f02acbb8Keith Whitwell p.program->FogOption = GL_NONE; 108647b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell 108721f99792a916a62fcfae7c208f50f192d4ce5926Brian if (p.program->Base.NumTexIndirections > ctx->Const.FragmentProgram.MaxTexIndirections) 108815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell program_error(&p, "Exceeded max nr indirect texture lookups"); 108915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 109021f99792a916a62fcfae7c208f50f192d4ce5926Brian if (p.program->Base.NumTexInstructions > ctx->Const.FragmentProgram.MaxTexInstructions) 109115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell program_error(&p, "Exceeded max TEX instructions"); 109215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 109321f99792a916a62fcfae7c208f50f192d4ce5926Brian if (p.program->Base.NumAluInstructions > ctx->Const.FragmentProgram.MaxAluInstructions) 109415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell program_error(&p, "Exceeded max ALU instructions"); 109515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 10965d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul ASSERT(p.program->Base.NumInstructions <= MAX_INSTRUCTIONS); 10978b88f62fbd62153500fc3483003f438561366a00Keith Whitwell 1098e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul /* Allocate final instruction array */ 1099e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul program->Base.Instructions 1100e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul = _mesa_alloc_instructions(program->Base.NumInstructions); 1101e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul if (!program->Base.Instructions) { 1102e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, 1103e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul "generating tex env program"); 1104e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul return; 1105e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul } 11061240eb2683043ba81e81378807170d0d7045581dBrian _mesa_copy_instructions(program->Base.Instructions, instBuffer, 11071240eb2683043ba81e81378807170d0d7045581dBrian program->Base.NumInstructions); 1108e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul 1109dbeea25bb834479a29712100888c862348112018Keith Whitwell /* Notify driver the fragment program has (actually) changed. 11108b88f62fbd62153500fc3483003f438561366a00Keith Whitwell */ 1111e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul if (ctx->Driver.ProgramStringNotify) { 1112e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul ctx->Driver.ProgramStringNotify( ctx, GL_FRAGMENT_PROGRAM_ARB, 1113e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul &p.program->Base ); 1114e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul } 1115e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul 1116e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul if (DISASSEM) { 1117e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul _mesa_print_program(&p.program->Base); 1118e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul _mesa_printf("\n"); 1119dbeea25bb834479a29712100888c862348112018Keith Whitwell } 112015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 112115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 11225d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul 1123122629f27925a9dc50029bebc5079f87f416a7e1Brian Paulstatic struct gl_fragment_program * 1124d9736db6676948e06712d4bcba46b7040452f870Brian Paulsearch_cache(const struct texenvprog_cache *cache, 1125d9736db6676948e06712d4bcba46b7040452f870Brian Paul GLuint hash, 1126e4cb9cd167b2993a4d73871b80216af9766f130bBrian Paul const void *key, 1127d9736db6676948e06712d4bcba46b7040452f870Brian Paul GLuint keysize) 1128ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 11295ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell struct texenvprog_cache_item *c; 1130ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 11315ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell for (c = cache->items[hash % cache->size]; c; c = c->next) { 11325ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell if (c->hash == hash && memcmp(c->key, key, keysize) == 0) 1133122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul return (struct gl_fragment_program *) c->data; 1134ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 1135ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 1136ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell return NULL; 1137ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 1138ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 11395ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwellstatic void rehash( struct texenvprog_cache *cache ) 11405ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell{ 11415ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell struct texenvprog_cache_item **items; 11425ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell struct texenvprog_cache_item *c, *next; 11435ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell GLuint size, i; 11445ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell 11455ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell size = cache->size * 3; 11465ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell items = (struct texenvprog_cache_item**) _mesa_malloc(size * sizeof(*items)); 11475ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell _mesa_memset(items, 0, size * sizeof(*items)); 11485ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell 11495ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell for (i = 0; i < cache->size; i++) 11505ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell for (c = cache->items[i]; c; c = next) { 11515ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell next = c->next; 11525ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell c->next = items[c->hash % size]; 11535ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell items[c->hash % size] = c; 11545ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell } 11555ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell 11565ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell _mesa_free(cache->items); 11575ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell cache->items = items; 11585ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell cache->size = size; 11595ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell} 11605ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell 11618065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwellstatic void clear_cache( struct texenvprog_cache *cache ) 11628065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell{ 11638065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell struct texenvprog_cache_item *c, *next; 11648065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell GLuint i; 11658065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell 11668065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell for (i = 0; i < cache->size; i++) { 11678065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell for (c = cache->items[i]; c; c = next) { 11688065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell next = c->next; 11698065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell _mesa_free(c->key); 1170122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul cache->ctx->Driver.DeleteProgram(cache->ctx, 1171122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul (struct gl_program *) c->data); 11728065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell _mesa_free(c); 11738065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell } 11748065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell cache->items[i] = NULL; 11758065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell } 11768065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell 11778065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell 11788065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell cache->n_items = 0; 11798065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell} 11808065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell 11818065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell 11825ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwellstatic void cache_item( struct texenvprog_cache *cache, 1183ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint hash, 1184b8f2f6fee147f423438ef7044984b1d7cfb5a428Brian Paul const struct state_key *key, 1185ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell void *data ) 1186ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 118718d1fdebebcb52e7fcf50e62c4c02862d173af51Brian struct texenvprog_cache_item *c 118818d1fdebebcb52e7fcf50e62c4c02862d173af51Brian = (struct texenvprog_cache_item *) MALLOC(sizeof(*c)); 1189ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell c->hash = hash; 11908065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell 11918065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell c->key = _mesa_malloc(sizeof(*key)); 11928065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell memcpy(c->key, key, sizeof(*key)); 11938065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell 119418d1fdebebcb52e7fcf50e62c4c02862d173af51Brian c->data = (struct gl_fragment_program *) data; 11955ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell 11968065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell if (cache->n_items > cache->size * 1.5) { 11978065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell if (cache->size < 1000) 11988065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell rehash(cache); 11998065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell else 12008065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell clear_cache(cache); 12018065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell } 12025ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell 12038065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell cache->n_items++; 12045ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell c->next = cache->items[hash % cache->size]; 12055ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell cache->items[hash % cache->size] = c; 1206ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 1207ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 1208d9736db6676948e06712d4bcba46b7040452f870Brian Paulstatic GLuint hash_key( const struct state_key *key ) 1209ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 1210ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint *ikey = (GLuint *)key; 1211ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint hash = 0, i; 1212ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 12138065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell /* Make a slightly better attempt at a hash function: 1214ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell */ 12158065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell for (i = 0; i < sizeof(*key)/sizeof(*ikey); i++) 12168065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell { 12178065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell hash += ikey[i]; 12188065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell hash += (hash << 10); 12198065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell hash ^= (hash >> 6); 12208065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell } 1221ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 1222ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell return hash; 1223ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 1224ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 1225a90046f1097ad95de2aa95ca65741dff5cddced9Brian 1226a90046f1097ad95de2aa95ca65741dff5cddced9Brian/** 1227a90046f1097ad95de2aa95ca65741dff5cddced9Brian * If _MaintainTexEnvProgram is set we'll generate a fragment program that 1228a90046f1097ad95de2aa95ca65741dff5cddced9Brian * implements the current texture env/combine mode. 1229a90046f1097ad95de2aa95ca65741dff5cddced9Brian * This function generates that program and puts it into effect. 1230a90046f1097ad95de2aa95ca65741dff5cddced9Brian */ 1231a90046f1097ad95de2aa95ca65741dff5cddced9Brianvoid 1232a90046f1097ad95de2aa95ca65741dff5cddced9Brian_mesa_UpdateTexEnvProgram( GLcontext *ctx ) 1233ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 12348065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell struct state_key key; 1235ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint hash; 1236122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul const struct gl_fragment_program *prev = ctx->FragmentProgram._Current; 1237ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 1238a90046f1097ad95de2aa95ca65741dff5cddced9Brian ASSERT(ctx->FragmentProgram._MaintainTexEnvProgram); 1239a90046f1097ad95de2aa95ca65741dff5cddced9Brian 1240a90046f1097ad95de2aa95ca65741dff5cddced9Brian /* If a conventional fragment program/shader isn't in effect... */ 1241efcfdbd4d16071088e60a59cb966abd730d9d111Brian if (!ctx->FragmentProgram._Enabled && 1242efcfdbd4d16071088e60a59cb966abd730d9d111Brian !ctx->Shader.CurrentProgram) { 12438065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell make_state_key(ctx, &key); 12448065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell hash = hash_key(&key); 1245c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell 1246d9736db6676948e06712d4bcba46b7040452f870Brian Paul ctx->FragmentProgram._Current = 1247a90046f1097ad95de2aa95ca65741dff5cddced9Brian ctx->FragmentProgram._TexEnvProgram = 1248a90046f1097ad95de2aa95ca65741dff5cddced9Brian search_cache(&ctx->Texture.env_fp_cache, hash, &key, sizeof(key)); 1249a90046f1097ad95de2aa95ca65741dff5cddced9Brian 1250a90046f1097ad95de2aa95ca65741dff5cddced9Brian if (!ctx->FragmentProgram._TexEnvProgram) { 1251a90046f1097ad95de2aa95ca65741dff5cddced9Brian if (0) 1252a90046f1097ad95de2aa95ca65741dff5cddced9Brian _mesa_printf("Building new texenv proggy for key %x\n", hash); 1253a90046f1097ad95de2aa95ca65741dff5cddced9Brian 1254a90046f1097ad95de2aa95ca65741dff5cddced9Brian /* create new tex env program */ 1255efcfdbd4d16071088e60a59cb966abd730d9d111Brian ctx->FragmentProgram._Current = 1256efcfdbd4d16071088e60a59cb966abd730d9d111Brian ctx->FragmentProgram._TexEnvProgram = 1257efcfdbd4d16071088e60a59cb966abd730d9d111Brian (struct gl_fragment_program *) 1258a90046f1097ad95de2aa95ca65741dff5cddced9Brian ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0); 1259ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 1260a90046f1097ad95de2aa95ca65741dff5cddced9Brian create_new_program(ctx, &key, ctx->FragmentProgram._TexEnvProgram); 1261ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 1262a90046f1097ad95de2aa95ca65741dff5cddced9Brian cache_item(&ctx->Texture.env_fp_cache, hash, &key, 1263a90046f1097ad95de2aa95ca65741dff5cddced9Brian ctx->FragmentProgram._TexEnvProgram); 1264c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell } 1265a90046f1097ad95de2aa95ca65741dff5cddced9Brian else { 1266a90046f1097ad95de2aa95ca65741dff5cddced9Brian if (0) 1267a90046f1097ad95de2aa95ca65741dff5cddced9Brian _mesa_printf("Found existing texenv program for key %x\n", hash); 1268c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell } 1269c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell } 1270c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell else { 1271c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell ctx->FragmentProgram._Current = ctx->FragmentProgram.Current; 1272ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 1273c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell 1274c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell /* Tell the driver about the change. Could define a new target for 1275c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell * this? 1276c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell */ 12775d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul if (ctx->FragmentProgram._Current != prev && ctx->Driver.BindProgram) { 12785d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 1279a90046f1097ad95de2aa95ca65741dff5cddced9Brian (struct gl_program *) ctx->FragmentProgram._Current); 12805d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul } 1281ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 1282ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 12835ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell 12845ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwellvoid _mesa_TexEnvProgramCacheInit( GLcontext *ctx ) 12855ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell{ 12868065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell ctx->Texture.env_fp_cache.ctx = ctx; 12875ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell ctx->Texture.env_fp_cache.size = 17; 12885ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell ctx->Texture.env_fp_cache.n_items = 0; 12895ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell ctx->Texture.env_fp_cache.items = (struct texenvprog_cache_item **) 12905ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell _mesa_calloc(ctx->Texture.env_fp_cache.size * 12915ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell sizeof(struct texenvprog_cache_item)); 12925ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell} 12935ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell 12945ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell 1295ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellvoid _mesa_TexEnvProgramCacheDestroy( GLcontext *ctx ) 1296ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 12978065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell clear_cache(&ctx->Texture.env_fp_cache); 12985ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell _mesa_free(ctx->Texture.env_fp_cache.items); 1299ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 1300