ff_fragment_shader.cpp revision 2389c055ed4c26ba5f3979c4a7871a333725dd88
115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell/************************************************************************** 215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 3f4a5ea2ccb472958a4635c606e9510011bceaa3dBrian * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * All Rights Reserved. 515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a 715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * copy of this software and associated documentation files (the 815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * "Software"), to deal in the Software without restriction, including 915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * without limitation the rights to use, copy, modify, merge, publish, 1015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * distribute, sub license, and/or sell copies of the Software, and to 1115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * permit persons to whom the Software is furnished to do so, subject to 1215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * the following conditions: 1315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 1415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * The above copyright notice and this permission notice (including the 1515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * next paragraph) shall be included in all copies or substantial portions 1615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * of the Software. 1715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 1815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 1915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 2015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 2115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 2215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 2315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 2415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 2615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell **************************************************************************/ 2715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 2815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell#include "glheader.h" 2915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell#include "macros.h" 3015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell#include "enums.h" 315b5c9315275752add1215dba0f86d5f5068d856bBrian Paul#include "shader/program.h" 32c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "shader/prog_parameter.h" 33f4a5ea2ccb472958a4635c606e9510011bceaa3dBrian#include "shader/prog_cache.h" 34c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "shader/prog_instruction.h" 35c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "shader/prog_print.h" 36c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "shader/prog_statevars.h" 3783fad68ec1989c719646a76f4cc5e0b3d23537edBrian#include "shader/programopt.h" 3815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell#include "texenvprogram.h" 3915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 405b5c9315275752add1215dba0f86d5f5068d856bBrian Paul 415b5c9315275752add1215dba0f86d5f5068d856bBrian Paulstruct texenvprog_cache_item 425b5c9315275752add1215dba0f86d5f5068d856bBrian Paul{ 435b5c9315275752add1215dba0f86d5f5068d856bBrian Paul GLuint hash; 445b5c9315275752add1215dba0f86d5f5068d856bBrian Paul void *key; 455b5c9315275752add1215dba0f86d5f5068d856bBrian Paul struct gl_fragment_program *data; 465b5c9315275752add1215dba0f86d5f5068d856bBrian Paul struct texenvprog_cache_item *next; 475b5c9315275752add1215dba0f86d5f5068d856bBrian Paul}; 485b5c9315275752add1215dba0f86d5f5068d856bBrian Paul 495b5c9315275752add1215dba0f86d5f5068d856bBrian Paul 50e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul/** 51b5e1a93036b22bd30738abccbb8a2645a515667fBrian Paul * Up to nine instructions per tex unit, plus fog, specular color. 52e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul */ 53b5e1a93036b22bd30738abccbb8a2645a515667fBrian Paul#define MAX_INSTRUCTIONS ((MAX_TEXTURE_UNITS * 9) + 12) 5415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 55269e3895d9837ac7303b91948f003ca5c12c0fe4Keith Whitwell#define DISASSEM (MESA_VERBOSE & VERBOSE_DISASSEM) 5615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 57ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstruct mode_opt { 586280e335706f95ed0ebb089d8f72aeede9b5a1adKeith Whitwell GLubyte Source:4; 596280e335706f95ed0ebb089d8f72aeede9b5a1adKeith Whitwell GLubyte Operand:3; 60ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell}; 61ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 62ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstruct state_key { 636280e335706f95ed0ebb089d8f72aeede9b5a1adKeith Whitwell GLuint nr_enabled_units:8; 646280e335706f95ed0ebb089d8f72aeede9b5a1adKeith Whitwell GLuint enabled_units:8; 655d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint separate_specular:1; 665d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint fog_enabled:1; 675d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint fog_mode:2; 686280e335706f95ed0ebb089d8f72aeede9b5a1adKeith Whitwell GLuint inputs_available:12; 69ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 70ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct { 715d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint enabled:1; 725d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint source_index:3; /* one of TEXTURE_1D/2D/3D/CUBE/RECT_INDEX */ 7383ad2a756ea8dd1b0ca9746e355ce3de0f29356eNicolai Haehnle GLuint shadow:1; 745d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint ScaleShiftRGB:2; 755d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint ScaleShiftA:2; 76ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 775d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint NumArgsRGB:2; 785d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint ModeRGB:4; 795d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint NumArgsA:2; 805d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint ModeA:4; 816280e335706f95ed0ebb089d8f72aeede9b5a1adKeith Whitwell 826280e335706f95ed0ebb089d8f72aeede9b5a1adKeith Whitwell struct mode_opt OptRGB[3]; 83ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct mode_opt OptA[3]; 84ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } unit[8]; 85ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell}; 86ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 87ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define FOG_LINEAR 0 88ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define FOG_EXP 1 89ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define FOG_EXP2 2 90ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define FOG_UNKNOWN 3 91ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 92ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstatic GLuint translate_fog_mode( GLenum mode ) 93ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 94ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch (mode) { 95ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_LINEAR: return FOG_LINEAR; 96ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_EXP: return FOG_EXP; 97ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_EXP2: return FOG_EXP2; 98ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell default: return FOG_UNKNOWN; 99ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 100ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 101ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 102ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_SRC_COLOR 0 103ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_ONE_MINUS_SRC_COLOR 1 104ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_SRC_ALPHA 2 105ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_ONE_MINUS_SRC_ALPHA 3 106ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_ZERO 4 107ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_ONE 5 108ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_UNKNOWN 7 109ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 110ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstatic GLuint translate_operand( GLenum operand ) 111ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 112ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch (operand) { 113ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_SRC_COLOR: return OPR_SRC_COLOR; 114ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_ONE_MINUS_SRC_COLOR: return OPR_ONE_MINUS_SRC_COLOR; 115ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_SRC_ALPHA: return OPR_SRC_ALPHA; 116ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_ONE_MINUS_SRC_ALPHA: return OPR_ONE_MINUS_SRC_ALPHA; 117ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_ZERO: return OPR_ZERO; 118ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_ONE: return OPR_ONE; 119ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell default: return OPR_UNKNOWN; 120ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 121ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 122ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 123ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE 0 124ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE0 1 125ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE1 2 126ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE2 3 127ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE3 4 128ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE4 5 129ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE5 6 130ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE6 7 131ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE7 8 132ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_CONSTANT 9 133ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_PRIMARY_COLOR 10 134ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_PREVIOUS 11 135ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_UNKNOWN 15 136ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 137ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstatic GLuint translate_source( GLenum src ) 138ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 139ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch (src) { 140ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE: return SRC_TEXTURE; 141ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE0: 142ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE1: 143ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE2: 144ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE3: 145ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE4: 146ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE5: 147ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE6: 148ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE7: return SRC_TEXTURE0 + (src - GL_TEXTURE0); 149ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_CONSTANT: return SRC_CONSTANT; 150ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_PRIMARY_COLOR: return SRC_PRIMARY_COLOR; 151ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_PREVIOUS: return SRC_PREVIOUS; 152ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell default: return SRC_UNKNOWN; 153ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 154ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 155ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 156ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_REPLACE 0 157ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_MODULATE 1 158ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_ADD 2 159ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_ADD_SIGNED 3 160ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_INTERPOLATE 4 161ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_SUBTRACT 5 162ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_DOT3_RGB 6 163ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_DOT3_RGB_EXT 7 164ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_DOT3_RGBA 8 165ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_DOT3_RGBA_EXT 9 166ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_MODULATE_ADD_ATI 10 167ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_MODULATE_SIGNED_ADD_ATI 11 168ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_MODULATE_SUBTRACT_ATI 12 169ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define MODE_UNKNOWN 15 170ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 171ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstatic GLuint translate_mode( GLenum mode ) 172ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 173ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch (mode) { 174ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_REPLACE: return MODE_REPLACE; 175ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_MODULATE: return MODE_MODULATE; 176ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_ADD: return MODE_ADD; 177ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_ADD_SIGNED: return MODE_ADD_SIGNED; 178ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_INTERPOLATE: return MODE_INTERPOLATE; 179ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_SUBTRACT: return MODE_SUBTRACT; 180ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_DOT3_RGB: return MODE_DOT3_RGB; 181ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_DOT3_RGB_EXT: return MODE_DOT3_RGB_EXT; 182ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_DOT3_RGBA: return MODE_DOT3_RGBA; 183ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_DOT3_RGBA_EXT: return MODE_DOT3_RGBA_EXT; 184ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_MODULATE_ADD_ATI: return MODE_MODULATE_ADD_ATI; 185ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_MODULATE_SIGNED_ADD_ATI: return MODE_MODULATE_SIGNED_ADD_ATI; 186ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_MODULATE_SUBTRACT_ATI: return MODE_MODULATE_SUBTRACT_ATI; 187ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell default: return MODE_UNKNOWN; 188ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 189ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 190ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 191ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define TEXTURE_UNKNOWN_INDEX 7 192e00ac11d4dd05c56584622dc2707bbdcfe4b2707Brian Paulstatic GLuint translate_tex_src_bit( GLbitfield bit ) 193ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 1941519b93b7bc519e187d98f99715a01ba866286b1Brian Paul /* make sure number of switch cases is correct */ 1951519b93b7bc519e187d98f99715a01ba866286b1Brian Paul assert(NUM_TEXTURE_TARGETS == 7); 196ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch (bit) { 1971519b93b7bc519e187d98f99715a01ba866286b1Brian Paul case TEXTURE_1D_BIT: return TEXTURE_1D_INDEX; 1981519b93b7bc519e187d98f99715a01ba866286b1Brian Paul case TEXTURE_2D_BIT: return TEXTURE_2D_INDEX; 1991519b93b7bc519e187d98f99715a01ba866286b1Brian Paul case TEXTURE_3D_BIT: return TEXTURE_3D_INDEX; 2001519b93b7bc519e187d98f99715a01ba866286b1Brian Paul case TEXTURE_CUBE_BIT: return TEXTURE_CUBE_INDEX; 2011519b93b7bc519e187d98f99715a01ba866286b1Brian Paul case TEXTURE_RECT_BIT: return TEXTURE_RECT_INDEX; 2021519b93b7bc519e187d98f99715a01ba866286b1Brian Paul case TEXTURE_1D_ARRAY_BIT: return TEXTURE_1D_ARRAY_INDEX; 2031519b93b7bc519e187d98f99715a01ba866286b1Brian Paul case TEXTURE_2D_ARRAY_BIT: return TEXTURE_2D_ARRAY_INDEX; 2041519b93b7bc519e187d98f99715a01ba866286b1Brian Paul default: return TEXTURE_UNKNOWN_INDEX; 205ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 206ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 207ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 2081680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell#define VERT_BIT_TEX_ANY (0xff << VERT_ATTRIB_TEX0) 2091680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell#define VERT_RESULT_TEX_ANY (0xff << VERT_RESULT_TEX0) 2101680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 211239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul/** 212239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul * Identify all possible varying inputs. The fragment program will 2131680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * never reference non-varying inputs, but will track them via state 2141680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * constants instead. 2151680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * 2161680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * This function figures out all the inputs that the fragment program 2171680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * has access to. The bitmask is later reduced to just those which 2181680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * are actually referenced. 2191680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell */ 220239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paulstatic GLbitfield get_fp_input_mask( GLcontext *ctx ) 2211680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell{ 222f0b0794b3885a2fdfb168ec4521c7b5e942d3228Brian Paul const GLboolean vertexShader = (ctx->Shader.CurrentProgram && 223f0b0794b3885a2fdfb168ec4521c7b5e942d3228Brian Paul ctx->Shader.CurrentProgram->VertexProgram); 224f0b0794b3885a2fdfb168ec4521c7b5e942d3228Brian Paul const GLboolean vertexProgram = ctx->VertexProgram._Enabled; 225239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul GLbitfield fp_inputs = 0x0; 2261680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 2276d4d51d647c27288aa625560bc080231099c0b01Brian Paul if (ctx->VertexProgram._Overriden) { 2286d4d51d647c27288aa625560bc080231099c0b01Brian Paul /* Somebody's messing with the vertex program and we don't have 2296d4d51d647c27288aa625560bc080231099c0b01Brian Paul * a clue what's happening. Assume that it could be producing 2306d4d51d647c27288aa625560bc080231099c0b01Brian Paul * all possible outputs. 2316d4d51d647c27288aa625560bc080231099c0b01Brian Paul */ 2326d4d51d647c27288aa625560bc080231099c0b01Brian Paul fp_inputs = ~0; 2336d4d51d647c27288aa625560bc080231099c0b01Brian Paul } 2346d4d51d647c27288aa625560bc080231099c0b01Brian Paul else if (ctx->RenderMode == GL_FEEDBACK) { 2356d4d51d647c27288aa625560bc080231099c0b01Brian Paul fp_inputs = (FRAG_BIT_COL0 | FRAG_BIT_TEX0); 2366d4d51d647c27288aa625560bc080231099c0b01Brian Paul } 237f0b0794b3885a2fdfb168ec4521c7b5e942d3228Brian Paul else if (!(vertexProgram || vertexShader) || 238d7296a1a8e846bc4d41ded1c2406b6f5c658188aBrian Paul !ctx->VertexProgram._Current) { 239f0b0794b3885a2fdfb168ec4521c7b5e942d3228Brian Paul /* Fixed function vertex logic */ 240239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul GLbitfield varying_inputs = ctx->varying_vp_inputs; 2411680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 24297e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell /* These get generated in the setup routine regardless of the 24397e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell * vertex program: 24497e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell */ 24597e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell if (ctx->Point.PointSprite) 24697e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell varying_inputs |= FRAG_BITS_TEX_ANY; 24797e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell 2481680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell /* First look at what values may be computed by the generated 2491680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * vertex program: 2501680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell */ 2511680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell if (ctx->Light.Enabled) { 2521680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell fp_inputs |= FRAG_BIT_COL0; 2531680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 2541680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) 2551680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell fp_inputs |= FRAG_BIT_COL1; 2561680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell } 2571680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 2581680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell fp_inputs |= (ctx->Texture._TexGenEnabled | 2591680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell ctx->Texture._TexMatEnabled) << FRAG_ATTRIB_TEX0; 2601680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 2611680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell /* Then look at what might be varying as a result of enabled 2621680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * arrays, etc: 2631680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell */ 2641680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell if (varying_inputs & VERT_BIT_COLOR0) fp_inputs |= FRAG_BIT_COL0; 2651680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell if (varying_inputs & VERT_BIT_COLOR1) fp_inputs |= FRAG_BIT_COL1; 2661680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 2671680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell fp_inputs |= (((varying_inputs & VERT_BIT_TEX_ANY) >> VERT_ATTRIB_TEX0) 2681680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell << FRAG_ATTRIB_TEX0); 2691680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 2701680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell } 2711680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell else { 2721680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell /* calculate from vp->outputs */ 2732389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul struct gl_vertex_program *vprog; 2742389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul GLbitfield vp_outputs; 2752389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul 2762389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul /* Choose GLSL vertex shader over ARB vertex program. Need this 2772389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul * since vertex shader state validation comes after fragment state 2782389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul * validation (see additional comments in state.c). 2792389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul */ 2802389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul if (vertexShader) 2812389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul vprog = ctx->Shader.CurrentProgram->VertexProgram; 2822389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul else 2832389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul vprog = ctx->VertexProgram._Current; 2842389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul 2852389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul vp_outputs = vprog->Base.OutputsWritten; 2861680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 28797e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell /* These get generated in the setup routine regardless of the 28897e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell * vertex program: 28997e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell */ 29097e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell if (ctx->Point.PointSprite) 29197e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell vp_outputs |= FRAG_BITS_TEX_ANY; 29297e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell 2931680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell if (vp_outputs & (1 << VERT_RESULT_COL0)) fp_inputs |= FRAG_BIT_COL0; 2941680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell if (vp_outputs & (1 << VERT_RESULT_COL1)) fp_inputs |= FRAG_BIT_COL1; 2951680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 2960370d6b359016790c6b879c2a4b6661adac20deaKeith Whitwell fp_inputs |= (((vp_outputs & VERT_RESULT_TEX_ANY) >> VERT_RESULT_TEX0) 2970370d6b359016790c6b879c2a4b6661adac20deaKeith Whitwell << FRAG_ATTRIB_TEX0); 2981680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell } 2991680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 3001680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell return fp_inputs; 3011680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell} 3021680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 3031680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 30422db53577603afef8fdf62c324ff5977de76b9d8Brian Paul/** 30522db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * Examine current texture environment state and generate a unique 30622db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * key to identify it. 30722db53577603afef8fdf62c324ff5977de76b9d8Brian Paul */ 3088065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwellstatic void make_state_key( GLcontext *ctx, struct state_key *key ) 309ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 310ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint i, j; 311239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul GLbitfield inputs_referenced = FRAG_BIT_COL0; 312239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul GLbitfield inputs_available = get_fp_input_mask( ctx ); 3131680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 3148065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell memset(key, 0, sizeof(*key)); 3158065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell 316ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell for (i=0;i<MAX_TEXTURE_UNITS;i++) { 317d9736db6676948e06712d4bcba46b7040452f870Brian Paul const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i]; 318b6bb5e09e0ad1f61f96c65bbc870bd493df12f1aXiang, Haihao GLenum format; 319bf4a0fafc86bba8dc868cf30244a237e33645164Roland Scheidegger 320bf4a0fafc86bba8dc868cf30244a237e33645164Roland Scheidegger if (!texUnit->_ReallyEnabled || !texUnit->Enabled) 321ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell continue; 322ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 323b6bb5e09e0ad1f61f96c65bbc870bd493df12f1aXiang, Haihao format = texUnit->_Current->Image[0][texUnit->_Current->BaseLevel]->_BaseFormat; 324b6bb5e09e0ad1f61f96c65bbc870bd493df12f1aXiang, Haihao 325ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].enabled = 1; 326ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->enabled_units |= (1<<i); 3271680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell key->nr_enabled_units = i+1; 3281680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell inputs_referenced |= FRAG_BIT_TEX(i); 329ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 330ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].source_index = 331ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell translate_tex_src_bit(texUnit->_ReallyEnabled); 332b6bb5e09e0ad1f61f96c65bbc870bd493df12f1aXiang, Haihao key->unit[i].shadow = ((texUnit->_Current->CompareMode == GL_COMPARE_R_TO_TEXTURE) && 333b6bb5e09e0ad1f61f96c65bbc870bd493df12f1aXiang, Haihao ((format == GL_DEPTH_COMPONENT) || 334b6bb5e09e0ad1f61f96c65bbc870bd493df12f1aXiang, Haihao (format == GL_DEPTH_STENCIL_EXT))); 335ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 336ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].NumArgsRGB = texUnit->_CurrentCombine->_NumArgsRGB; 337ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].NumArgsA = texUnit->_CurrentCombine->_NumArgsA; 338ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 339ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].ModeRGB = 340ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell translate_mode(texUnit->_CurrentCombine->ModeRGB); 341ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].ModeA = 342ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell translate_mode(texUnit->_CurrentCombine->ModeA); 343ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 344ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].ScaleShiftRGB = texUnit->_CurrentCombine->ScaleShiftRGB; 34564da16146fed68605f83ccf3b64075c0d5b6f052Keith Whitwell key->unit[i].ScaleShiftA = texUnit->_CurrentCombine->ScaleShiftA; 346ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 347ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell for (j=0;j<3;j++) { 348ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].OptRGB[j].Operand = 349ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell translate_operand(texUnit->_CurrentCombine->OperandRGB[j]); 350ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].OptA[j].Operand = 351ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell translate_operand(texUnit->_CurrentCombine->OperandA[j]); 352ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].OptRGB[j].Source = 353ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell translate_source(texUnit->_CurrentCombine->SourceRGB[j]); 354ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].OptA[j].Source = 355ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell translate_source(texUnit->_CurrentCombine->SourceA[j]); 356ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 357ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 358ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 3591680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) { 360ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->separate_specular = 1; 3611680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell inputs_referenced |= FRAG_BIT_COL1; 3621680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell } 363ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 364ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (ctx->Fog.Enabled) { 365ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->fog_enabled = 1; 366ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->fog_mode = translate_fog_mode(ctx->Fog.Mode); 3671680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell inputs_referenced |= FRAG_BIT_FOGC; /* maybe */ 368ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 3691680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 3701680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell key->inputs_available = (inputs_available & inputs_referenced); 371ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 372ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 373239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul/** 374239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul * Use uregs to represent registers internally, translate to Mesa's 37515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * expected formats on emit. 37615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 37715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * NOTE: These are passed by value extensively in this file rather 37815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * than as usual by pointer reference. If this disturbs you, try 37915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * remembering they are just 32bits in size. 38015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 38115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * GCC is smart enough to deal with these dword-sized structures in 38215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * much the same way as if I had defined them as dwords and was using 38315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * macros to access and set the fields. This is much nicer and easier 38415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * to evolve. 38515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 38615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstruct ureg { 38715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint file:4; 38815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint idx:8; 38915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint negatebase:1; 39015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint abs:1; 39115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint negateabs:1; 39215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint swz:12; 39315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint pad:5; 39415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell}; 39515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 39613abf91b42b00c7eb64c373aff3a4c1bb3d8fb7fBrian Paulstatic const struct ureg undef = { 3978d97265711b172da4f387748f0e72da9267492b0Alan Hourihane PROGRAM_UNDEFINED, 39815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell ~0, 39915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 0, 40015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 0, 40115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 0, 40215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 0, 40315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 0 40415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell}; 40515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 40615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 407239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul/** State used to build the fragment program: 40815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 40915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstruct texenv_fragment_program { 410122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul struct gl_fragment_program *program; 41115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLcontext *ctx; 412ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct state_key *state; 41315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 414239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul GLbitfield alu_temps; /**< Track texture indirections, see spec. */ 415239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul GLbitfield temps_output; /**< Track texture indirections, see spec. */ 416239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul GLbitfield temp_in_use; /**< Tracks temporary regs which are in use. */ 41715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLboolean error; 41815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 4192dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell struct ureg src_texture[MAX_TEXTURE_UNITS]; 420ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell /* Reg containing each texture unit's sampled texture color, 421ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell * else undef. 422ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell */ 42315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 424239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul struct ureg src_previous; /**< Reg containing color from previous 42515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * stage. May need to be decl'd. 42615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 42715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 428239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul GLuint last_tex_stage; /**< Number of last enabled texture unit */ 4292dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 4302dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell struct ureg half; 4312dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell struct ureg one; 4322dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell struct ureg zero; 43315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell}; 43415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 43515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 43615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 43715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg make_ureg(GLuint file, GLuint idx) 43815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 43915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg reg; 44015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.file = file; 44115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.idx = idx; 44215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.negatebase = 0; 44315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.abs = 0; 44415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.negateabs = 0; 44515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.swz = SWIZZLE_NOOP; 44615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.pad = 0; 44715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return reg; 44815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 44915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 45015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg swizzle( struct ureg reg, int x, int y, int z, int w ) 45115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 45215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.swz = MAKE_SWIZZLE4(GET_SWZ(reg.swz, x), 45315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GET_SWZ(reg.swz, y), 45415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GET_SWZ(reg.swz, z), 45515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GET_SWZ(reg.swz, w)); 45615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 45715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return reg; 45815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 45915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 46015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg swizzle1( struct ureg reg, int x ) 46115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 46215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return swizzle(reg, x, x, x, x); 46315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 46415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 4656fe176a64859798db17fbaed6858cccc646aae38Keith Whitwellstatic struct ureg negate( struct ureg reg ) 4666fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell{ 4676fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell reg.negatebase ^= 1; 4686fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell return reg; 4696fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell} 4706fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell 47115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic GLboolean is_undef( struct ureg reg ) 47215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 4738d97265711b172da4f387748f0e72da9267492b0Alan Hourihane return reg.file == PROGRAM_UNDEFINED; 47415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 47515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 476ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 47715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg get_temp( struct texenv_fragment_program *p ) 47815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 47913abf91b42b00c7eb64c373aff3a4c1bb3d8fb7fBrian Paul GLint bit; 480ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 481cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell /* First try and reuse temps which have been used already: 482ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell */ 483b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul bit = _mesa_ffs( ~p->temp_in_use & p->alu_temps ); 484ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 485ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell /* Then any unused temporary: 486ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell */ 487ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell if (!bit) 488b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul bit = _mesa_ffs( ~p->temp_in_use ); 489ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 490ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell if (!bit) { 491bfb5ea307ec48b9b8d0d2eca0c03f6d02273d454Brian Paul _mesa_problem(NULL, "%s: out of temporaries\n", __FILE__); 492b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul _mesa_exit(1); 493ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell } 494ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 49513abf91b42b00c7eb64c373aff3a4c1bb3d8fb7fBrian Paul if ((GLuint) bit > p->program->Base.NumTemporaries) 496b5cbaf945dd5213d5faf7bb7e4d68d0d25a25b55Keith Whitwell p->program->Base.NumTemporaries = bit; 497b5cbaf945dd5213d5faf7bb7e4d68d0d25a25b55Keith Whitwell 49893cd9237d793e38ba4479d1367be7548853f67f4Keith Whitwell p->temp_in_use |= 1<<(bit-1); 499ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell return make_ureg(PROGRAM_TEMPORARY, (bit-1)); 500ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell} 501ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 502ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwellstatic struct ureg get_tex_temp( struct texenv_fragment_program *p ) 503ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell{ 504ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell int bit; 505ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 506d01269a57f4cfdb859352c933bc546296545dd80Brian Paul /* First try to find available temp not previously used (to avoid 507cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell * starting a new texture indirection). According to the spec, the 508cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell * ~p->temps_output isn't necessary, but will keep it there for 509cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell * now: 510ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell */ 511b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul bit = _mesa_ffs( ~p->temp_in_use & ~p->alu_temps & ~p->temps_output ); 512ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 513ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell /* Then any unused temporary: 514ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell */ 515cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if (!bit) 516b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul bit = _mesa_ffs( ~p->temp_in_use ); 517ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 51815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell if (!bit) { 519bfb5ea307ec48b9b8d0d2eca0c03f6d02273d454Brian Paul _mesa_problem(NULL, "%s: out of temporaries\n", __FILE__); 520b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul _mesa_exit(1); 52115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 52215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 52313abf91b42b00c7eb64c373aff3a4c1bb3d8fb7fBrian Paul if ((GLuint) bit > p->program->Base.NumTemporaries) 524b5cbaf945dd5213d5faf7bb7e4d68d0d25a25b55Keith Whitwell p->program->Base.NumTemporaries = bit; 525b5cbaf945dd5213d5faf7bb7e4d68d0d25a25b55Keith Whitwell 52693cd9237d793e38ba4479d1367be7548853f67f4Keith Whitwell p->temp_in_use |= 1<<(bit-1); 52715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return make_ureg(PROGRAM_TEMPORARY, (bit-1)); 52815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 52915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 53015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 5315620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul/** Mark a temp reg as being no longer allocatable. */ 5325620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paulstatic void reserve_temp( struct texenv_fragment_program *p, struct ureg r ) 5335620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul{ 5345620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul if (r.file == PROGRAM_TEMPORARY) 5355620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul p->temps_output |= (1 << r.idx); 5365620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul} 5375620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul 5385620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul 539f18d4e058ed979c6e42e868c7febde4fa62c5810Brianstatic void release_temps(GLcontext *ctx, struct texenv_fragment_program *p ) 54015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 541f18d4e058ed979c6e42e868c7febde4fa62c5810Brian GLuint max_temp = ctx->Const.FragmentProgram.MaxTemps; 54293cd9237d793e38ba4479d1367be7548853f67f4Keith Whitwell 5432dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell /* KW: To support tex_env_crossbar, don't release the registers in 5442dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell * temps_output. 5452dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell */ 54693cd9237d793e38ba4479d1367be7548853f67f4Keith Whitwell if (max_temp >= sizeof(int) * 8) 5472dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell p->temp_in_use = p->temps_output; 54893cd9237d793e38ba4479d1367be7548853f67f4Keith Whitwell else 5492dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell p->temp_in_use = ~((1<<max_temp)-1) | p->temps_output; 55015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 55115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 55215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 5539fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brianstatic struct ureg register_param5( struct texenv_fragment_program *p, 554ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLint s0, 555ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLint s1, 556ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLint s2, 557ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLint s3, 5589fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brian GLint s4) 55915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 5609fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brian gl_state_index tokens[STATE_LENGTH]; 56147b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell GLuint idx; 56247b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell tokens[0] = s0; 56347b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell tokens[1] = s1; 56447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell tokens[2] = s2; 56547b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell tokens[3] = s3; 56647b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell tokens[4] = s4; 567de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul idx = _mesa_add_state_reference( p->program->Base.Parameters, tokens ); 56847b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell return make_ureg(PROGRAM_STATE_VAR, idx); 56947b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell} 57015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 57115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 5729fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brian#define register_param1(p,s0) register_param5(p,s0,0,0,0,0) 5739fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brian#define register_param2(p,s0,s1) register_param5(p,s0,s1,0,0,0) 5749fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brian#define register_param3(p,s0,s1,s2) register_param5(p,s0,s1,s2,0,0) 5759fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brian#define register_param4(p,s0,s1,s2,s3) register_param5(p,s0,s1,s2,s3,0) 57647b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell 5771680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwellstatic GLuint frag_to_vert_attrib( GLuint attrib ) 5781680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell{ 5791680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell switch (attrib) { 5801680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell case FRAG_ATTRIB_COL0: return VERT_ATTRIB_COLOR0; 5811680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell case FRAG_ATTRIB_COL1: return VERT_ATTRIB_COLOR1; 5821680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell default: 5831680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell assert(attrib >= FRAG_ATTRIB_TEX0); 5841680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell assert(attrib <= FRAG_ATTRIB_TEX7); 5851680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell return attrib - FRAG_ATTRIB_TEX0 + VERT_ATTRIB_TEX0; 5861680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell } 5871680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell} 5881680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 58947b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell 59047b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwellstatic struct ureg register_input( struct texenv_fragment_program *p, GLuint input ) 59147b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell{ 5921680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell if (p->state->inputs_available & (1<<input)) { 5931680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell p->program->Base.InputsRead |= (1 << input); 5941680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell return make_ureg(PROGRAM_INPUT, input); 5951680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell } 5961680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell else { 5971680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell GLuint idx = frag_to_vert_attrib( input ); 5981680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell return register_param3( p, STATE_INTERNAL, STATE_CURRENT_ATTRIB, idx ); 5991680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell } 60015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 60115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 60247b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell 6037e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paulstatic void emit_arg( struct prog_src_register *reg, 60415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg ureg ) 60515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 60615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg->File = ureg.file; 60715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg->Index = ureg.idx; 60815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg->Swizzle = ureg.swz; 609f2802c40fff686301a7ff99f0a0b1c57d5cf5625Keith Whitwell reg->NegateBase = ureg.negatebase ? 0xf : 0x0; 61015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg->Abs = ureg.abs; 61115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg->NegateAbs = ureg.negateabs; 61215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 61315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 6147e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paulstatic void emit_dst( struct prog_dst_register *dst, 61515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg ureg, GLuint mask ) 61615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 61715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell dst->File = ureg.file; 61815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell dst->Index = ureg.idx; 61915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell dst->WriteMask = mask; 620c9d495c6f064aacd1e072033b9c17a83b8c37fa1Brian dst->CondMask = COND_TR; /* always pass cond test */ 621c9d495c6f064aacd1e072033b9c17a83b8c37fa1Brian dst->CondSwizzle = SWIZZLE_NOOP; 62215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 62315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 6247e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paulstatic struct prog_instruction * 62515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellemit_op(struct texenv_fragment_program *p, 6265d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul enum prog_opcode op, 62715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg dest, 62815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint mask, 62922db53577603afef8fdf62c324ff5977de76b9d8Brian Paul GLboolean saturate, 63015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg src0, 63115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg src1, 63215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg src2 ) 63315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 63447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell GLuint nr = p->program->Base.NumInstructions++; 635de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul struct prog_instruction *inst = &p->program->Base.Instructions[nr]; 6362a8e9bb00f8cf830783cbc20a2a57f31b19491eaBrian 6372a8e9bb00f8cf830783cbc20a2a57f31b19491eaBrian assert(nr < MAX_INSTRUCTIONS); 6382a8e9bb00f8cf830783cbc20a2a57f31b19491eaBrian 639d6272e06172f7ac7a0d6e8062e8ffba33e1ab3baBrian Paul _mesa_init_instructions(inst, 1); 64015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell inst->Opcode = op; 64115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 64247b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell emit_arg( &inst->SrcReg[0], src0 ); 64347b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell emit_arg( &inst->SrcReg[1], src1 ); 64447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell emit_arg( &inst->SrcReg[2], src2 ); 64515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 646e31ac052236ea615b4995f9ec301d8af4b864531Brian Paul inst->SaturateMode = saturate ? SATURATE_ZERO_ONE : SATURATE_OFF; 64715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 64815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell emit_dst( &inst->DstReg, dest, mask ); 64915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 6505620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul#if 0 651cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell /* Accounting for indirection tracking: 652cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell */ 653cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if (dest.file == PROGRAM_TEMPORARY) 654cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell p->temps_output |= 1 << dest.idx; 6555620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul#endif 656cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell 65715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return inst; 65815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 65915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 66015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 66115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg emit_arith( struct texenv_fragment_program *p, 6625d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul enum prog_opcode op, 66347b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell struct ureg dest, 66447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell GLuint mask, 66522db53577603afef8fdf62c324ff5977de76b9d8Brian Paul GLboolean saturate, 66647b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell struct ureg src0, 66747b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell struct ureg src1, 66847b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell struct ureg src2 ) 66915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 67015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell emit_op(p, op, dest, mask, saturate, src0, src1, src2); 67115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 672cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell /* Accounting for indirection tracking: 673cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell */ 674cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if (src0.file == PROGRAM_TEMPORARY) 675cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell p->alu_temps |= 1 << src0.idx; 676cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell 677cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if (!is_undef(src1) && src1.file == PROGRAM_TEMPORARY) 678cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell p->alu_temps |= 1 << src1.idx; 679cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell 680cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if (!is_undef(src2) && src2.file == PROGRAM_TEMPORARY) 681cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell p->alu_temps |= 1 << src2.idx; 682cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell 683cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if (dest.file == PROGRAM_TEMPORARY) 684cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell p->alu_temps |= 1 << dest.idx; 685cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell 68621f99792a916a62fcfae7c208f50f192d4ce5926Brian p->program->Base.NumAluInstructions++; 68715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return dest; 68815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 68915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 69015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg emit_texld( struct texenv_fragment_program *p, 6915d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul enum prog_opcode op, 692ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct ureg dest, 693ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint destmask, 694ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint tex_unit, 695ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint tex_idx, 696ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct ureg coord ) 69715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 6987e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul struct prog_instruction *inst = emit_op( p, op, 69915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell dest, destmask, 70022db53577603afef8fdf62c324ff5977de76b9d8Brian Paul GL_FALSE, /* don't saturate? */ 70115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell coord, /* arg 0? */ 70215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell undef, 70315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell undef); 70415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 7057e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul inst->TexSrcTarget = tex_idx; 70615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell inst->TexSrcUnit = tex_unit; 70715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 70821f99792a916a62fcfae7c208f50f192d4ce5926Brian p->program->Base.NumTexInstructions++; 70915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 7105620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul /* Accounting for indirection tracking: 7115620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul */ 7125620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul reserve_temp(p, dest); 7135620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul 714cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell /* Is this a texture indirection? 715cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell */ 716cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if ((coord.file == PROGRAM_TEMPORARY && 717cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell (p->temps_output & (1<<coord.idx))) || 718cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell (dest.file == PROGRAM_TEMPORARY && 719cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell (p->alu_temps & (1<<dest.idx)))) { 72021f99792a916a62fcfae7c208f50f192d4ce5926Brian p->program->Base.NumTexIndirections++; 7212dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell p->temps_output = 1<<coord.idx; 722cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell p->alu_temps = 0; 7232dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell assert(0); /* KW: texture env crossbar */ 72415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 72515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 72615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return dest; 72715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 72815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 72915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 73047b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwellstatic struct ureg register_const4f( struct texenv_fragment_program *p, 731ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLfloat s0, 732ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLfloat s1, 733ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLfloat s2, 734ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLfloat s3) 73515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 73647b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell GLfloat values[4]; 737a90046f1097ad95de2aa95ca65741dff5cddced9Brian GLuint idx, swizzle; 738d01269a57f4cfdb859352c933bc546296545dd80Brian Paul struct ureg r; 73947b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell values[0] = s0; 74047b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell values[1] = s1; 74147b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell values[2] = s2; 74247b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell values[3] = s3; 743a90046f1097ad95de2aa95ca65741dff5cddced9Brian idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4, 744a90046f1097ad95de2aa95ca65741dff5cddced9Brian &swizzle ); 745d01269a57f4cfdb859352c933bc546296545dd80Brian Paul r = make_ureg(PROGRAM_CONSTANT, idx); 746d01269a57f4cfdb859352c933bc546296545dd80Brian Paul r.swz = swizzle; 747d01269a57f4cfdb859352c933bc546296545dd80Brian Paul return r; 74815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 74915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 750e490242b9aeb50bd96fed7a9afbf529295a8ac0eKeith Whitwell#define register_scalar_const(p, s0) register_const4f(p, s0, s0, s0, s0) 75147b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell#define register_const1f(p, s0) register_const4f(p, s0, 0, 0, 1) 75247b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell#define register_const2f(p, s0, s1) register_const4f(p, s0, s1, 0, 1) 75347b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell#define register_const3f(p, s0, s1, s2) register_const4f(p, s0, s1, s2, 1) 75415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 75515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 7562dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwellstatic struct ureg get_one( struct texenv_fragment_program *p ) 7572dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell{ 7582dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell if (is_undef(p->one)) 7592dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell p->one = register_scalar_const(p, 1.0); 7602dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell return p->one; 7612dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell} 7622dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 7632dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwellstatic struct ureg get_half( struct texenv_fragment_program *p ) 7642dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell{ 7652dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell if (is_undef(p->half)) 7664dd8a8907e40126e42131a400b59e7d5da5e302aAapo Tahkola p->half = register_scalar_const(p, 0.5); 7672dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell return p->half; 7682dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell} 7692dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 7702dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwellstatic struct ureg get_zero( struct texenv_fragment_program *p ) 7712dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell{ 7722dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell if (is_undef(p->zero)) 7734dd8a8907e40126e42131a400b59e7d5da5e302aAapo Tahkola p->zero = register_scalar_const(p, 0.0); 7742dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell return p->zero; 7752dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell} 7762dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 77715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 77815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic void program_error( struct texenv_fragment_program *p, const char *msg ) 77915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 780bfb5ea307ec48b9b8d0d2eca0c03f6d02273d454Brian Paul _mesa_problem(NULL, msg); 78115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell p->error = 1; 78215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 78315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 78415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg get_source( struct texenv_fragment_program *p, 785ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint src, GLuint unit ) 78615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 78715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell switch (src) { 788ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE: 7892dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell assert(!is_undef(p->src_texture[unit])); 7902dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell return p->src_texture[unit]; 79115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 792ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE0: 793ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE1: 794ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE2: 795ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE3: 796ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE4: 797ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE5: 798ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE6: 799ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE7: 800ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell assert(!is_undef(p->src_texture[src - SRC_TEXTURE0])); 801ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell return p->src_texture[src - SRC_TEXTURE0]; 802ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 803ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_CONSTANT: 80447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell return register_param2(p, STATE_TEXENV_COLOR, unit); 8052dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 806ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_PRIMARY_COLOR: 80747b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell return register_input(p, FRAG_ATTRIB_COL0); 8082dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 809ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_PREVIOUS: 810ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell default: 81147b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell if (is_undef(p->src_previous)) 81247b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell return register_input(p, FRAG_ATTRIB_COL0); 81347b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell else 81447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell return p->src_previous; 81515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 81615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 8172dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 81815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg emit_combine_source( struct texenv_fragment_program *p, 819ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint mask, 820ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint unit, 821ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint source, 822ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint operand ) 82315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 82415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg arg, src, one; 82515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 82615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell src = get_source(p, source, unit); 82715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 82815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell switch (operand) { 829ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE_MINUS_SRC_COLOR: 83015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Get unused tmp, 83115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * Emit tmp = 1.0 - arg.xyzw 83215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 83315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell arg = get_temp( p ); 8342dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell one = get_one( p ); 8357e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_SUB, arg, mask, 0, one, src, undef); 83615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 837ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_SRC_ALPHA: 83815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell if (mask == WRITEMASK_W) 83915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return src; 84015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell else 84122db53577603afef8fdf62c324ff5977de76b9d8Brian Paul return swizzle1( src, SWIZZLE_W ); 842ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE_MINUS_SRC_ALPHA: 84315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Get unused tmp, 84415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * Emit tmp = 1.0 - arg.wwww 84515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 8462dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell arg = get_temp(p); 8472dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell one = get_one(p); 8487e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith(p, OPCODE_SUB, arg, mask, 0, 84922db53577603afef8fdf62c324ff5977de76b9d8Brian Paul one, swizzle1(src, SWIZZLE_W), undef); 850ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ZERO: 8512dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell return get_zero(p); 852ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE: 8532dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell return get_one(p); 854ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_SRC_COLOR: 85515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 85615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return src; 85715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 85815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 85915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 860ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstatic GLboolean args_match( struct state_key *key, GLuint unit ) 86115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 86222db53577603afef8fdf62c324ff5977de76b9d8Brian Paul GLuint i, nr = key->unit[unit].NumArgsRGB; 86315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 86415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell for (i = 0 ; i < nr ; i++) { 865ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->unit[unit].OptA[i].Source != key->unit[unit].OptRGB[i].Source) 86615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return GL_FALSE; 86715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 868ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch(key->unit[unit].OptA[i].Operand) { 869ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_SRC_ALPHA: 870ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch(key->unit[unit].OptRGB[i].Operand) { 871ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_SRC_COLOR: 872ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_SRC_ALPHA: 87315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 87415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 87515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return GL_FALSE; 87615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 87715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 878ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE_MINUS_SRC_ALPHA: 879ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch(key->unit[unit].OptRGB[i].Operand) { 880ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE_MINUS_SRC_COLOR: 881ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE_MINUS_SRC_ALPHA: 88215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 88315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 88415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return GL_FALSE; 88515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 88615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 88715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 88815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return GL_FALSE; /* impossible */ 88915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 89015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 89115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 89215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return GL_TRUE; 89315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 89415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 89515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg emit_combine( struct texenv_fragment_program *p, 896ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct ureg dest, 897ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint mask, 89822db53577603afef8fdf62c324ff5977de76b9d8Brian Paul GLboolean saturate, 899ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint unit, 900ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint nr, 901ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint mode, 902d9736db6676948e06712d4bcba46b7040452f870Brian Paul const struct mode_opt *opt) 903ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 90415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg src[3]; 905cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell struct ureg tmp, half; 90622db53577603afef8fdf62c324ff5977de76b9d8Brian Paul GLuint i; 90715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 9080063084804d62402d80821a86978660663955442Brian Paul tmp = undef; /* silence warning (bug 5318) */ 9090063084804d62402d80821a86978660663955442Brian Paul 91015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell for (i = 0; i < nr; i++) 911ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell src[i] = emit_combine_source( p, mask, unit, opt[i].Source, opt[i].Operand ); 91215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 91315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell switch (mode) { 914ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_REPLACE: 91515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell if (mask == WRITEMASK_XYZW && !saturate) 91615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return src[0]; 91715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell else 9187e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_MOV, dest, mask, saturate, src[0], undef, undef ); 919ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_MODULATE: 9207e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_MUL, dest, mask, saturate, 9216fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell src[0], src[1], undef ); 922ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_ADD: 9237e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_ADD, dest, mask, saturate, 9246fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell src[0], src[1], undef ); 925ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_ADD_SIGNED: 92615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* tmp = arg0 + arg1 927cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell * result = tmp - .5 92815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 9292dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell half = get_half(p); 93099da2d30eb08e50edf4b0067518af3acdf2dabc0Jerome Glisse tmp = get_temp( p ); 9317e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_ADD, tmp, mask, 0, src[0], src[1], undef ); 9327e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_SUB, dest, mask, saturate, tmp, half, undef ); 93315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return dest; 934ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_INTERPOLATE: 93515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Arg0 * (Arg2) + Arg1 * (1-Arg2) -- note arguments are reordered: 93615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 9377e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_LRP, dest, mask, saturate, src[2], src[0], src[1] ); 93815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 939ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_SUBTRACT: 9407e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_SUB, dest, mask, saturate, src[0], src[1], undef ); 94115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 942ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGBA: 943ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGBA_EXT: 944ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGB_EXT: 945ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGB: { 94615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg tmp0 = get_temp( p ); 94715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg tmp1 = get_temp( p ); 948e490242b9aeb50bd96fed7a9afbf529295a8ac0eKeith Whitwell struct ureg neg1 = register_scalar_const(p, -1); 949e490242b9aeb50bd96fed7a9afbf529295a8ac0eKeith Whitwell struct ureg two = register_scalar_const(p, 2); 95015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 95115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* tmp0 = 2*src0 - 1 95215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * tmp1 = 2*src1 - 1 95315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 95415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * dst = tmp0 dot3 tmp1 95515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 9567e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_MAD, tmp0, WRITEMASK_XYZW, 0, 9576fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell two, src[0], neg1); 95815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 959aa2069586d434dd0487b0daa2b583efe801a0d51Brian Paul if (_mesa_memcmp(&src[0], &src[1], sizeof(struct ureg)) == 0) 96015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell tmp1 = tmp0; 96115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell else 9627e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_MAD, tmp1, WRITEMASK_XYZW, 0, 9636fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell two, src[1], neg1); 9647e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_DP3, dest, mask, saturate, tmp0, tmp1, undef); 96515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return dest; 96615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 967ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_MODULATE_ADD_ATI: 9686fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell /* Arg0 * Arg2 + Arg1 */ 9697e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_MAD, dest, mask, saturate, 9706fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell src[0], src[2], src[1] ); 971ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_MODULATE_SIGNED_ADD_ATI: { 9726fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell /* Arg0 * Arg2 + Arg1 - 0.5 */ 9736fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell struct ureg tmp0 = get_temp(p); 9742dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell half = get_half(p); 9757e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_MAD, tmp0, mask, 0, src[0], src[2], src[1] ); 9767e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_SUB, dest, mask, saturate, tmp0, half, undef ); 9776fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell return dest; 9786fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell } 979ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_MODULATE_SUBTRACT_ATI: 9806fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell /* Arg0 * Arg2 - Arg1 */ 9817e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_MAD, dest, mask, 0, src[0], src[2], negate(src[1]) ); 9826fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell return dest; 98315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 98415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return src[0]; 98515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 98615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 98715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 98815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 98922db53577603afef8fdf62c324ff5977de76b9d8Brian Paul/** 99022db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * Generate instructions for one texture unit's env/combiner mode. 99122db53577603afef8fdf62c324ff5977de76b9d8Brian Paul */ 99222db53577603afef8fdf62c324ff5977de76b9d8Brian Paulstatic struct ureg 99322db53577603afef8fdf62c324ff5977de76b9d8Brian Paulemit_texenv(struct texenv_fragment_program *p, GLuint unit) 99415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 995ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct state_key *key = p->state; 99622db53577603afef8fdf62c324ff5977de76b9d8Brian Paul GLboolean saturate = (unit < p->last_tex_stage); 99715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint rgb_shift, alpha_shift; 99815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg out, shift; 999cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell struct ureg dest; 100015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1001ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (!key->unit[unit].enabled) { 1002ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell return get_source(p, SRC_PREVIOUS, 0); 100315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 1004ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 1005ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch (key->unit[unit].ModeRGB) { 1006ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGB_EXT: 1007ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell alpha_shift = key->unit[unit].ScaleShiftA; 100815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell rgb_shift = 0; 100915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 1010ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGBA_EXT: 101115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell alpha_shift = 0; 101215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell rgb_shift = 0; 101315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 101415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 1015ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell rgb_shift = key->unit[unit].ScaleShiftRGB; 1016ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell alpha_shift = key->unit[unit].ScaleShiftA; 101715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 101815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 1019ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 1020cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell /* If this is the very last calculation, emit direct to output reg: 1021cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell */ 1022ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->separate_specular || 1023cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell unit != p->last_tex_stage || 1024cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell alpha_shift || 1025cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell rgb_shift) 1026cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell dest = get_temp( p ); 1027cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell else 102890ebb581e60d29bd565ad4d8a49e642de7b0ce5dBrian Paul dest = make_ureg(PROGRAM_OUTPUT, FRAG_RESULT_COLR); 102915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 103015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Emit the RGB and A combine ops 103115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 1032ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->unit[unit].ModeRGB == key->unit[unit].ModeA && 1033ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell args_match(key, unit)) { 103415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell out = emit_combine( p, dest, WRITEMASK_XYZW, saturate, 103515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell unit, 1036ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].NumArgsRGB, 1037ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].ModeRGB, 1038ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].OptRGB); 103915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 1040ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell else if (key->unit[unit].ModeRGB == MODE_DOT3_RGBA_EXT || 10419a45176dd85a1cd523498efeebd0481950a1bf58Roland Scheidegger key->unit[unit].ModeRGB == MODE_DOT3_RGBA) { 104215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 104315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell out = emit_combine( p, dest, WRITEMASK_XYZW, saturate, 104415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell unit, 1045ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].NumArgsRGB, 1046ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].ModeRGB, 1047ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].OptRGB); 104815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 104915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell else { 105015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Need to do something to stop from re-emitting identical 105115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * argument calculations here: 105215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 105315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell out = emit_combine( p, dest, WRITEMASK_XYZ, saturate, 105415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell unit, 1055ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].NumArgsRGB, 1056ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].ModeRGB, 1057ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].OptRGB); 105815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell out = emit_combine( p, dest, WRITEMASK_W, saturate, 105915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell unit, 1060ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].NumArgsA, 1061ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].ModeA, 1062ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].OptA); 106315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 106415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 106515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Deal with the final shift: 106615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 106715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell if (alpha_shift || rgb_shift) { 106815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell if (rgb_shift == alpha_shift) { 106953174afeeb68a79e471185cb463c13ff90af698fJosé Fonseca shift = register_scalar_const(p, (GLfloat)(1<<rgb_shift)); 107015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 107115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell else { 10722dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell shift = register_const4f(p, 107353174afeeb68a79e471185cb463c13ff90af698fJosé Fonseca (GLfloat)(1<<rgb_shift), 107453174afeeb68a79e471185cb463c13ff90af698fJosé Fonseca (GLfloat)(1<<rgb_shift), 107553174afeeb68a79e471185cb463c13ff90af698fJosé Fonseca (GLfloat)(1<<rgb_shift), 107653174afeeb68a79e471185cb463c13ff90af698fJosé Fonseca (GLfloat)(1<<alpha_shift)); 107715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 10787e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_MUL, dest, WRITEMASK_XYZW, 107915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell saturate, out, shift, undef ); 108015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 108115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell else 108215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return out; 108315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 108415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 10852dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 108622db53577603afef8fdf62c324ff5977de76b9d8Brian Paul/** 108722db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * Generate instruction for getting a texture source term. 108822db53577603afef8fdf62c324ff5977de76b9d8Brian Paul */ 10892dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwellstatic void load_texture( struct texenv_fragment_program *p, GLuint unit ) 10902dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell{ 10912dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell if (is_undef(p->src_texture[unit])) { 1092ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint dim = p->state->unit[unit].source_index; 10932dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell struct ureg texcoord = register_input(p, FRAG_ATTRIB_TEX0+unit); 10942dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell struct ureg tmp = get_tex_temp( p ); 10952dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 1096bfb5ea307ec48b9b8d0d2eca0c03f6d02273d454Brian Paul if (dim == TEXTURE_UNKNOWN_INDEX) 1097bfb5ea307ec48b9b8d0d2eca0c03f6d02273d454Brian Paul program_error(p, "TexSrcBit"); 1098ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 10992dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell /* TODO: Use D0_MASK_XY where possible. 11002dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell */ 110183ad2a756ea8dd1b0ca9746e355ce3de0f29356eNicolai Haehnle if (p->state->unit[unit].enabled) { 1102b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola p->src_texture[unit] = emit_texld( p, OPCODE_TXP, 1103b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola tmp, WRITEMASK_XYZW, 1104b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola unit, dim, texcoord ); 11050397b2bb41b0f337af2949a15bcd7d0e7e8a7dc1Keith Whitwell 110683ad2a756ea8dd1b0ca9746e355ce3de0f29356eNicolai Haehnle if (p->state->unit[unit].shadow) 110783ad2a756ea8dd1b0ca9746e355ce3de0f29356eNicolai Haehnle p->program->Base.ShadowSamplers |= 1 << unit; 11080397b2bb41b0f337af2949a15bcd7d0e7e8a7dc1Keith Whitwell 11091e3b07f363e6bf512ab1a5c620656985aece40fdBrian p->program->Base.SamplersUsed |= (1 << unit); 1110fce4612f8a29ee1798c9326a431a139d856c7a04Brian /* This identity mapping should already be in place 1111fce4612f8a29ee1798c9326a431a139d856c7a04Brian * (see _mesa_init_program_struct()) but let's be safe. 1112fce4612f8a29ee1798c9326a431a139d856c7a04Brian */ 1113fce4612f8a29ee1798c9326a431a139d856c7a04Brian p->program->Base.SamplerUnits[unit] = unit; 11141e3b07f363e6bf512ab1a5c620656985aece40fdBrian } 1115b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola else 1116b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola p->src_texture[unit] = get_zero(p); 11172dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell } 11182dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell} 11192dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 1120241b6b7ab1a1a11c7fc516d1b6ff2c1bc8aba238Keith Whitwellstatic GLboolean load_texenv_source( struct texenv_fragment_program *p, 1121ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint src, GLuint unit ) 11222dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell{ 11232dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell switch (src) { 11244dd8a8907e40126e42131a400b59e7d5da5e302aAapo Tahkola case SRC_TEXTURE: 11252dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell load_texture(p, unit); 11262dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell break; 11272dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 1128ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE0: 1129ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE1: 1130ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE2: 1131ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE3: 1132ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE4: 1133ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE5: 1134ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE6: 1135ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE7: 1136ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell load_texture(p, src - SRC_TEXTURE0); 11372dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell break; 11382dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 11392dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell default: 11402dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell break; 11412dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell } 1142241b6b7ab1a1a11c7fc516d1b6ff2c1bc8aba238Keith Whitwell 1143241b6b7ab1a1a11c7fc516d1b6ff2c1bc8aba238Keith Whitwell return GL_TRUE; 11442dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell} 11452dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 114622db53577603afef8fdf62c324ff5977de76b9d8Brian Paul 114722db53577603afef8fdf62c324ff5977de76b9d8Brian Paul/** 114822db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * Generate instructions for loading all texture source terms. 114922db53577603afef8fdf62c324ff5977de76b9d8Brian Paul */ 115022db53577603afef8fdf62c324ff5977de76b9d8Brian Paulstatic GLboolean 115122db53577603afef8fdf62c324ff5977de76b9d8Brian Paulload_texunit_sources( struct texenv_fragment_program *p, int unit ) 11522dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell{ 1153ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct state_key *key = p->state; 1154b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola GLuint i; 1155b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola 1156b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola for (i = 0; i < key->unit[unit].NumArgsRGB; i++) { 1157b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola load_texenv_source( p, key->unit[unit].OptRGB[i].Source, unit); 1158b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola } 1159b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola 1160b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola for (i = 0; i < key->unit[unit].NumArgsA; i++) { 1161b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola load_texenv_source( p, key->unit[unit].OptA[i].Source, unit ); 11622dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell } 1163b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola 1164241b6b7ab1a1a11c7fc516d1b6ff2c1bc8aba238Keith Whitwell return GL_TRUE; 11652dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell} 11662dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 116722db53577603afef8fdf62c324ff5977de76b9d8Brian Paul 116822db53577603afef8fdf62c324ff5977de76b9d8Brian Paul/** 116922db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * Generate a new fragment program which implements the context's 117022db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * current texture env/combine mode. 117122db53577603afef8fdf62c324ff5977de76b9d8Brian Paul */ 117222db53577603afef8fdf62c324ff5977de76b9d8Brian Paulstatic void 1173e998c346471142db91a1bcb6c61551b8247b87e7Brian Paulcreate_new_program(GLcontext *ctx, struct state_key *key, 1174122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul struct gl_fragment_program *program) 117515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 1176e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul struct prog_instruction instBuffer[MAX_INSTRUCTIONS]; 117715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct texenv_fragment_program p; 117815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint unit; 117915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg cf, out; 1180276330b2412910777f7016f427909085f02acbb8Keith Whitwell 1181e490242b9aeb50bd96fed7a9afbf529295a8ac0eKeith Whitwell _mesa_memset(&p, 0, sizeof(p)); 118215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell p.ctx = ctx; 1183ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell p.state = key; 1184ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell p.program = program; 118515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1186e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul /* During code generation, use locally-allocated instruction buffer, 1187e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul * then alloc dynamic storage below. 1188e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul */ 1189e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul p.program->Base.Instructions = instBuffer; 1190276330b2412910777f7016f427909085f02acbb8Keith Whitwell p.program->Base.Target = GL_FRAGMENT_PROGRAM_ARB; 119121f99792a916a62fcfae7c208f50f192d4ce5926Brian p.program->Base.NumTexIndirections = 1; /* correct? */ 119221f99792a916a62fcfae7c208f50f192d4ce5926Brian p.program->Base.NumTexInstructions = 0; 119321f99792a916a62fcfae7c208f50f192d4ce5926Brian p.program->Base.NumAluInstructions = 0; 11941240eb2683043ba81e81378807170d0d7045581dBrian p.program->Base.String = NULL; 11959ca8815d3ba56ad718ba1c48c73aae3cdc0b8db0Keith Whitwell p.program->Base.NumInstructions = 1196e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul p.program->Base.NumTemporaries = 1197e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul p.program->Base.NumParameters = 1198e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul p.program->Base.NumAttributes = p.program->Base.NumAddressRegs = 0; 1199de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul p.program->Base.Parameters = _mesa_new_parameter_list(); 1200dbeea25bb834479a29712100888c862348112018Keith Whitwell 1201de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul p.program->Base.InputsRead = 0; 1202de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul p.program->Base.OutputsWritten = 1 << FRAG_RESULT_COLR; 120315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 12042dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell for (unit = 0; unit < MAX_TEXTURE_UNITS; unit++) 12052dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell p.src_texture[unit] = undef; 12062dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 120747b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell p.src_previous = undef; 12085ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell p.half = undef; 12095ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell p.zero = undef; 12105ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell p.one = undef; 12115ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell 121215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell p.last_tex_stage = 0; 1213f18d4e058ed979c6e42e868c7febde4fa62c5810Brian release_temps(ctx, &p); 121415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1215ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->enabled_units) { 12162dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell /* First pass - to support texture_env_crossbar, first identify 12172dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell * all referenced texture sources and emit texld instructions 12182dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell * for each: 12192dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell */ 122015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell for (unit = 0 ; unit < ctx->Const.MaxTextureUnits ; unit++) 1221ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->unit[unit].enabled) { 1222b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola load_texunit_sources( &p, unit ); 1223b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola p.last_tex_stage = unit; 122415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 122515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 12262dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell /* Second pass - emit combine instructions to build final color: 12272dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell */ 122815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) 1229ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->enabled_units & (1<<unit)) { 123015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell p.src_previous = emit_texenv( &p, unit ); 12315620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul reserve_temp(&p, p.src_previous); /* don't re-use this temp reg */ 1232f18d4e058ed979c6e42e868c7febde4fa62c5810Brian release_temps(ctx, &p); /* release all temps */ 123315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 123415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 123515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1236ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell cf = get_source( &p, SRC_PREVIOUS, 0 ); 123790ebb581e60d29bd565ad4d8a49e642de7b0ce5dBrian Paul out = make_ureg( PROGRAM_OUTPUT, FRAG_RESULT_COLR ); 123815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1239ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->separate_specular) { 124015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Emit specular add. 124115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 124247b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell struct ureg s = register_input(&p, FRAG_ATTRIB_COL1); 12437e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( &p, OPCODE_ADD, out, WRITEMASK_XYZ, 0, cf, s, undef ); 12447e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( &p, OPCODE_MOV, out, WRITEMASK_W, 0, cf, undef, undef ); 124515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 1246aa2069586d434dd0487b0daa2b583efe801a0d51Brian Paul else if (_mesa_memcmp(&cf, &out, sizeof(cf)) != 0) { 124715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Will wind up in here if no texture enabled or a couple of 124815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * other scenarios (GL_REPLACE for instance). 124915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 12507e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( &p, OPCODE_MOV, out, WRITEMASK_XYZW, 0, cf, undef, undef ); 125115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 125215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 125347b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell /* Finish up: 125447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell */ 12557e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( &p, OPCODE_END, undef, WRITEMASK_XYZW, 0, undef, undef, undef); 125647b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell 1257ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->fog_enabled) { 1258ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell /* Pull fog mode from GLcontext, the value in the state key is 1259ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell * a reduced value and not what is expected in FogOption 1260ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell */ 1261276330b2412910777f7016f427909085f02acbb8Keith Whitwell p.program->FogOption = ctx->Fog.Mode; 126263be96bdc7e9f388a5c49295bd7e150462fd003aBrian p.program->Base.InputsRead |= FRAG_BIT_FOGC; /* XXX new */ 1263ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } else 1264276330b2412910777f7016f427909085f02acbb8Keith Whitwell p.program->FogOption = GL_NONE; 126547b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell 126621f99792a916a62fcfae7c208f50f192d4ce5926Brian if (p.program->Base.NumTexIndirections > ctx->Const.FragmentProgram.MaxTexIndirections) 126715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell program_error(&p, "Exceeded max nr indirect texture lookups"); 126815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 126921f99792a916a62fcfae7c208f50f192d4ce5926Brian if (p.program->Base.NumTexInstructions > ctx->Const.FragmentProgram.MaxTexInstructions) 127015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell program_error(&p, "Exceeded max TEX instructions"); 127115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 127221f99792a916a62fcfae7c208f50f192d4ce5926Brian if (p.program->Base.NumAluInstructions > ctx->Const.FragmentProgram.MaxAluInstructions) 127315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell program_error(&p, "Exceeded max ALU instructions"); 127415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 12755d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul ASSERT(p.program->Base.NumInstructions <= MAX_INSTRUCTIONS); 12768b88f62fbd62153500fc3483003f438561366a00Keith Whitwell 1277e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul /* Allocate final instruction array */ 12783bf8d2ac7108a7f0f1722e411161e013bb8573f0Brian p.program->Base.Instructions 12793bf8d2ac7108a7f0f1722e411161e013bb8573f0Brian = _mesa_alloc_instructions(p.program->Base.NumInstructions); 12803bf8d2ac7108a7f0f1722e411161e013bb8573f0Brian if (!p.program->Base.Instructions) { 1281e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, 1282e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul "generating tex env program"); 1283e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul return; 1284e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul } 12853bf8d2ac7108a7f0f1722e411161e013bb8573f0Brian _mesa_copy_instructions(p.program->Base.Instructions, instBuffer, 12863bf8d2ac7108a7f0f1722e411161e013bb8573f0Brian p.program->Base.NumInstructions); 12873bf8d2ac7108a7f0f1722e411161e013bb8573f0Brian 12883bf8d2ac7108a7f0f1722e411161e013bb8573f0Brian if (p.program->FogOption) { 12893bf8d2ac7108a7f0f1722e411161e013bb8573f0Brian _mesa_append_fog_code(ctx, p.program); 12903bf8d2ac7108a7f0f1722e411161e013bb8573f0Brian p.program->FogOption = GL_NONE; 12913bf8d2ac7108a7f0f1722e411161e013bb8573f0Brian } 12923bf8d2ac7108a7f0f1722e411161e013bb8573f0Brian 1293e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul 1294dbeea25bb834479a29712100888c862348112018Keith Whitwell /* Notify driver the fragment program has (actually) changed. 12958b88f62fbd62153500fc3483003f438561366a00Keith Whitwell */ 1296e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul if (ctx->Driver.ProgramStringNotify) { 1297e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul ctx->Driver.ProgramStringNotify( ctx, GL_FRAGMENT_PROGRAM_ARB, 1298e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul &p.program->Base ); 1299e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul } 1300e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul 1301e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul if (DISASSEM) { 1302e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul _mesa_print_program(&p.program->Base); 1303e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul _mesa_printf("\n"); 1304dbeea25bb834479a29712100888c862348112018Keith Whitwell } 130515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 130615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 13075d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul 1308a90046f1097ad95de2aa95ca65741dff5cddced9Brian/** 130983ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian * Return a fragment program which implements the current 131083ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian * fixed-function texture, fog and color-sum operations. 131183ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian */ 131283ce6c51d7189094cf2a13fdcc0882a051a3bd41Brianstruct gl_fragment_program * 131383ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian_mesa_get_fixed_func_fragment_program(GLcontext *ctx) 1314ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 131583ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian struct gl_fragment_program *prog; 131683ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian struct state_key key; 131783ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian 131883ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian make_state_key(ctx, &key); 131983ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian 1320f4a5ea2ccb472958a4635c606e9510011bceaa3dBrian prog = (struct gl_fragment_program *) 1321f4a5ea2ccb472958a4635c606e9510011bceaa3dBrian _mesa_search_program_cache(ctx->FragmentProgram.Cache, 1322f4a5ea2ccb472958a4635c606e9510011bceaa3dBrian &key, sizeof(key)); 13238065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell 132483ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian if (!prog) { 132583ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian prog = (struct gl_fragment_program *) 132683ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0); 13278065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell 132883ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian create_new_program(ctx, &key, prog); 13295ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell 1330f4a5ea2ccb472958a4635c606e9510011bceaa3dBrian _mesa_program_cache_insert(ctx, ctx->FragmentProgram.Cache, 1331f4a5ea2ccb472958a4635c606e9510011bceaa3dBrian &key, sizeof(key), &prog->Base); 13328065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell } 13335ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell 133483ce6c51d7189094cf2a13fdcc0882a051a3bd41Brian return prog; 1335ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 1336ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 1337ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 1338a90046f1097ad95de2aa95ca65741dff5cddced9Brian 1339a90046f1097ad95de2aa95ca65741dff5cddced9Brian/** 1340a90046f1097ad95de2aa95ca65741dff5cddced9Brian * If _MaintainTexEnvProgram is set we'll generate a fragment program that 1341a90046f1097ad95de2aa95ca65741dff5cddced9Brian * implements the current texture env/combine mode. 1342a90046f1097ad95de2aa95ca65741dff5cddced9Brian * This function generates that program and puts it into effect. 1343af74abab6b9a1e32a1cc5cac7e547b953dcee0abKeith Whitwell * 1344af74abab6b9a1e32a1cc5cac7e547b953dcee0abKeith Whitwell * XXX: remove this function. currently only called by some drivers, 1345af74abab6b9a1e32a1cc5cac7e547b953dcee0abKeith Whitwell * not by mesa core. We now handle this properly from inside mesa. 1346a90046f1097ad95de2aa95ca65741dff5cddced9Brian */ 1347a90046f1097ad95de2aa95ca65741dff5cddced9Brianvoid 1348a90046f1097ad95de2aa95ca65741dff5cddced9Brian_mesa_UpdateTexEnvProgram( GLcontext *ctx ) 1349ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 1350122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul const struct gl_fragment_program *prev = ctx->FragmentProgram._Current; 1351ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 1352a90046f1097ad95de2aa95ca65741dff5cddced9Brian ASSERT(ctx->FragmentProgram._MaintainTexEnvProgram); 1353a90046f1097ad95de2aa95ca65741dff5cddced9Brian 1354a90046f1097ad95de2aa95ca65741dff5cddced9Brian /* If a conventional fragment program/shader isn't in effect... */ 1355efcfdbd4d16071088e60a59cb966abd730d9d111Brian if (!ctx->FragmentProgram._Enabled && 1356d781cdc8fadc802a1f2edbeb13ccb1ee768ce803Brian (!ctx->Shader.CurrentProgram || 13570397b2bb41b0f337af2949a15bcd7d0e7e8a7dc1Keith Whitwell !ctx->Shader.CurrentProgram->FragmentProgram) ) 13580397b2bb41b0f337af2949a15bcd7d0e7e8a7dc1Keith Whitwell { 13595b5c9315275752add1215dba0f86d5f5068d856bBrian Paul struct gl_fragment_program *newProg; 13605b5c9315275752add1215dba0f86d5f5068d856bBrian Paul 13610397b2bb41b0f337af2949a15bcd7d0e7e8a7dc1Keith Whitwell newProg = _mesa_get_fixed_func_fragment_program(ctx); 13625b5c9315275752add1215dba0f86d5f5068d856bBrian Paul 13635b5c9315275752add1215dba0f86d5f5068d856bBrian Paul _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, newProg); 13645b5c9315275752add1215dba0f86d5f5068d856bBrian Paul _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, newProg); 1365c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell } 1366c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell 1367c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell /* Tell the driver about the change. Could define a new target for 1368c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell * this? 1369c3626a91cee5034528f3f92c802a8e5947ea5f92Keith Whitwell */ 13705d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul if (ctx->FragmentProgram._Current != prev && ctx->Driver.BindProgram) { 13715d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 1372a90046f1097ad95de2aa95ca65741dff5cddced9Brian (struct gl_program *) ctx->FragmentProgram._Current); 13735d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul } 1374ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 1375