ff_fragment_shader.cpp revision a46e32787d98192d35bf2834011cfa5537e0e703
115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell/************************************************************************** 215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 332ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * All Rights Reserved. 56947f85cb5fbc433ba7763530285e470745b009bBrian Paul * Copyright 2009 VMware, Inc. All Rights Reserved. 615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a 815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * copy of this software and associated documentation files (the 915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * "Software"), to deal in the Software without restriction, including 1015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * without limitation the rights to use, copy, modify, merge, publish, 1115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * distribute, sub license, and/or sell copies of the Software, and to 1215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * permit persons to whom the Software is furnished to do so, subject to 1315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * the following conditions: 1415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 1515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * The above copyright notice and this permission notice (including the 1615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * next paragraph) shall be included in all copies or substantial portions 1715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * of the Software. 1815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 1915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 2015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 2115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 2215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 2315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 2415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 2515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 2715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell **************************************************************************/ 2815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 2915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell#include "glheader.h" 3025e5a6f279cec0863dcc341805aa7ca71189b626Brian Paul#include "imports.h" 315b5c9315275752add1215dba0f86d5f5068d856bBrian Paul#include "shader/program.h" 32c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "shader/prog_parameter.h" 3332ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell#include "shader/prog_cache.h" 34c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "shader/prog_instruction.h" 35c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "shader/prog_print.h" 36c223c6b663cd5db39ba19c2be74b88cc3b8f53f3Brian#include "shader/prog_statevars.h" 37fb3c41f5044bc0e228470ebf9f2cfdf2c53f191fBrian#include "shader/programopt.h" 3815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell#include "texenvprogram.h" 3915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 405b5c9315275752add1215dba0f86d5f5068d856bBrian Paul 41e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul/* 42e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul * Note on texture units: 43e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul * 44e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul * The number of texture units supported by fixed-function fragment 45e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul * processing is MAX_TEXTURE_COORD_UNITS, not MAX_TEXTURE_IMAGE_UNITS. 46e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul * That's because there's a one-to-one correspondence between texture 47e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul * coordinates and samplers in fixed-function processing. 48e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul * 49e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul * Since fixed-function vertex processing is limited to MAX_TEXTURE_COORD_UNITS 50e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul * sets of texcoords, so is fixed-function fragment processing. 51e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul * 52e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul * We can safely use ctx->Const.MaxTextureUnits for loop bounds. 53e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul */ 54e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul 55e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul 565b5c9315275752add1215dba0f86d5f5068d856bBrian Paulstruct texenvprog_cache_item 575b5c9315275752add1215dba0f86d5f5068d856bBrian Paul{ 585b5c9315275752add1215dba0f86d5f5068d856bBrian Paul GLuint hash; 595b5c9315275752add1215dba0f86d5f5068d856bBrian Paul void *key; 605b5c9315275752add1215dba0f86d5f5068d856bBrian Paul struct gl_fragment_program *data; 615b5c9315275752add1215dba0f86d5f5068d856bBrian Paul struct texenvprog_cache_item *next; 625b5c9315275752add1215dba0f86d5f5068d856bBrian Paul}; 635b5c9315275752add1215dba0f86d5f5068d856bBrian Paul 649cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholtstatic GLboolean 659cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholttexenv_doing_secondary_color(GLcontext *ctx) 669cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt{ 679cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt if (ctx->Light.Enabled && 689cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) 699cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt return GL_TRUE; 709cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt 719cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt if (ctx->Fog.ColorSumEnabled) 729cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt return GL_TRUE; 739cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt 749cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt return GL_FALSE; 759cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt} 765b5c9315275752add1215dba0f86d5f5068d856bBrian Paul 77e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul/** 78b5e1a93036b22bd30738abccbb8a2645a515667fBrian Paul * Up to nine instructions per tex unit, plus fog, specular color. 79e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul */ 800815ebccfc0a12d8f3e831928f1c4210b7f75ad8Brian Paul#define MAX_INSTRUCTIONS ((MAX_TEXTURE_COORD_UNITS * 9) + 12) 8115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 82269e3895d9837ac7303b91948f003ca5c12c0fe4Keith Whitwell#define DISASSEM (MESA_VERBOSE & VERBOSE_DISASSEM) 8315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 84ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstruct mode_opt { 85a46e32787d98192d35bf2834011cfa5537e0e703Chris Wilson GLubyte Source:4; /**< SRC_x */ 86a46e32787d98192d35bf2834011cfa5537e0e703Chris Wilson GLubyte Operand:3; /**< OPR_x */ 87ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell}; 88ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 89ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstruct state_key { 906280e335706f95ed0ebb089d8f72aeede9b5a1adKeith Whitwell GLuint nr_enabled_units:8; 916280e335706f95ed0ebb089d8f72aeede9b5a1adKeith Whitwell GLuint enabled_units:8; 925d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint separate_specular:1; 935d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint fog_enabled:1; 949ed0315271c38f5fe9cdd65020a54cbb7f61ed2bBrian Paul GLuint fog_mode:2; /**< FOG_x */ 956280e335706f95ed0ebb089d8f72aeede9b5a1adKeith Whitwell GLuint inputs_available:12; 96ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 97ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct { 985d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint enabled:1; 999ed0315271c38f5fe9cdd65020a54cbb7f61ed2bBrian Paul GLuint source_index:3; /**< TEXTURE_x_INDEX */ 10083ad2a756ea8dd1b0ca9746e355ce3de0f29356eNicolai Haehnle GLuint shadow:1; 1015d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint ScaleShiftRGB:2; 1025d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint ScaleShiftA:2; 103ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 1049ed0315271c38f5fe9cdd65020a54cbb7f61ed2bBrian Paul GLuint NumArgsRGB:3; /**< up to MAX_COMBINER_TERMS */ 105f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul GLuint ModeRGB:5; /**< MODE_x */ 106ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 1079ed0315271c38f5fe9cdd65020a54cbb7f61ed2bBrian Paul GLuint NumArgsA:3; /**< up to MAX_COMBINER_TERMS */ 108f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul GLuint ModeA:5; /**< MODE_x */ 109a46e32787d98192d35bf2834011cfa5537e0e703Chris Wilson 110a46e32787d98192d35bf2834011cfa5537e0e703Chris Wilson struct mode_opt OptRGB[MAX_COMBINER_TERMS]; 111bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul struct mode_opt OptA[MAX_COMBINER_TERMS]; 112d55a28e3dc712342e4a2f25aa9b661add7461e82Brian Paul } unit[MAX_TEXTURE_UNITS]; 113ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell}; 114ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 115ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define FOG_LINEAR 0 116ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define FOG_EXP 1 117ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define FOG_EXP2 2 118ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define FOG_UNKNOWN 3 119ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 120ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstatic GLuint translate_fog_mode( GLenum mode ) 121ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 122ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch (mode) { 123ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_LINEAR: return FOG_LINEAR; 124ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_EXP: return FOG_EXP; 125ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_EXP2: return FOG_EXP2; 126ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell default: return FOG_UNKNOWN; 127ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 128ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 129ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 130ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_SRC_COLOR 0 131ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_ONE_MINUS_SRC_COLOR 1 132ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_SRC_ALPHA 2 133ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_ONE_MINUS_SRC_ALPHA 3 134ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_ZERO 4 135ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_ONE 5 136ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_UNKNOWN 7 137ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 138ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstatic GLuint translate_operand( GLenum operand ) 139ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 140ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch (operand) { 141ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_SRC_COLOR: return OPR_SRC_COLOR; 142ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_ONE_MINUS_SRC_COLOR: return OPR_ONE_MINUS_SRC_COLOR; 143ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_SRC_ALPHA: return OPR_SRC_ALPHA; 144ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_ONE_MINUS_SRC_ALPHA: return OPR_ONE_MINUS_SRC_ALPHA; 145ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_ZERO: return OPR_ZERO; 146ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_ONE: return OPR_ONE; 1476947f85cb5fbc433ba7763530285e470745b009bBrian Paul default: 1486947f85cb5fbc433ba7763530285e470745b009bBrian Paul assert(0); 1496947f85cb5fbc433ba7763530285e470745b009bBrian Paul return OPR_UNKNOWN; 150ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 151ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 152ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 153ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE 0 154ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE0 1 155ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE1 2 156ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE2 3 157ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE3 4 158ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE4 5 159ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE5 6 160ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE6 7 161ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE7 8 162ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_CONSTANT 9 163ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_PRIMARY_COLOR 10 164ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_PREVIOUS 11 1656947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define SRC_ZERO 12 166ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_UNKNOWN 15 167ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 168ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstatic GLuint translate_source( GLenum src ) 169ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 170ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch (src) { 171ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE: return SRC_TEXTURE; 172ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE0: 173ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE1: 174ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE2: 175ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE3: 176ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE4: 177ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE5: 178ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE6: 179ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE7: return SRC_TEXTURE0 + (src - GL_TEXTURE0); 180ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_CONSTANT: return SRC_CONSTANT; 181ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_PRIMARY_COLOR: return SRC_PRIMARY_COLOR; 182ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_PREVIOUS: return SRC_PREVIOUS; 1836947f85cb5fbc433ba7763530285e470745b009bBrian Paul case GL_ZERO: 1846947f85cb5fbc433ba7763530285e470745b009bBrian Paul return SRC_ZERO; 1856947f85cb5fbc433ba7763530285e470745b009bBrian Paul default: 1866947f85cb5fbc433ba7763530285e470745b009bBrian Paul assert(0); 1876947f85cb5fbc433ba7763530285e470745b009bBrian Paul return SRC_UNKNOWN; 188ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 189ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 190ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 1916947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_REPLACE 0 /* r = a0 */ 1926947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_MODULATE 1 /* r = a0 * a1 */ 1936947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_ADD 2 /* r = a0 + a1 */ 1946947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_ADD_SIGNED 3 /* r = a0 + a1 - 0.5 */ 1956947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_INTERPOLATE 4 /* r = a0 * a2 + a1 * (1 - a2) */ 1966947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_SUBTRACT 5 /* r = a0 - a1 */ 1976947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_DOT3_RGB 6 /* r = a0 . a1 */ 1986947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_DOT3_RGB_EXT 7 /* r = a0 . a1 */ 1996947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_DOT3_RGBA 8 /* r = a0 . a1 */ 2006947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_DOT3_RGBA_EXT 9 /* r = a0 . a1 */ 2016947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_MODULATE_ADD_ATI 10 /* r = a0 * a2 + a1 */ 2026947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_MODULATE_SIGNED_ADD_ATI 11 /* r = a0 * a2 + a1 - 0.5 */ 2036947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_MODULATE_SUBTRACT_ATI 12 /* r = a0 * a2 - a1 */ 2046947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_ADD_PRODUCTS 13 /* r = a0 * a1 + a2 * a3 */ 2056947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_ADD_PRODUCTS_SIGNED 14 /* r = a0 * a1 + a2 * a3 - 0.5 */ 206114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger#define MODE_BUMP_ENVMAP_ATI 15 /* special */ 207114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger#define MODE_UNKNOWN 16 2086947f85cb5fbc433ba7763530285e470745b009bBrian Paul 2096947f85cb5fbc433ba7763530285e470745b009bBrian Paul/** 2106947f85cb5fbc433ba7763530285e470745b009bBrian Paul * Translate GL combiner state into a MODE_x value 2116947f85cb5fbc433ba7763530285e470745b009bBrian Paul */ 2126947f85cb5fbc433ba7763530285e470745b009bBrian Paulstatic GLuint translate_mode( GLenum envMode, GLenum mode ) 213ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 214ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch (mode) { 215ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_REPLACE: return MODE_REPLACE; 216ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_MODULATE: return MODE_MODULATE; 2176947f85cb5fbc433ba7763530285e470745b009bBrian Paul case GL_ADD: 2186947f85cb5fbc433ba7763530285e470745b009bBrian Paul if (envMode == GL_COMBINE4_NV) 2196947f85cb5fbc433ba7763530285e470745b009bBrian Paul return MODE_ADD_PRODUCTS; 2206947f85cb5fbc433ba7763530285e470745b009bBrian Paul else 2216947f85cb5fbc433ba7763530285e470745b009bBrian Paul return MODE_ADD; 2226947f85cb5fbc433ba7763530285e470745b009bBrian Paul case GL_ADD_SIGNED: 2236947f85cb5fbc433ba7763530285e470745b009bBrian Paul if (envMode == GL_COMBINE4_NV) 2246947f85cb5fbc433ba7763530285e470745b009bBrian Paul return MODE_ADD_PRODUCTS_SIGNED; 2256947f85cb5fbc433ba7763530285e470745b009bBrian Paul else 2266947f85cb5fbc433ba7763530285e470745b009bBrian Paul return MODE_ADD_SIGNED; 227ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_INTERPOLATE: return MODE_INTERPOLATE; 228ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_SUBTRACT: return MODE_SUBTRACT; 229ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_DOT3_RGB: return MODE_DOT3_RGB; 230ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_DOT3_RGB_EXT: return MODE_DOT3_RGB_EXT; 231ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_DOT3_RGBA: return MODE_DOT3_RGBA; 232ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_DOT3_RGBA_EXT: return MODE_DOT3_RGBA_EXT; 233ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_MODULATE_ADD_ATI: return MODE_MODULATE_ADD_ATI; 234ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_MODULATE_SIGNED_ADD_ATI: return MODE_MODULATE_SIGNED_ADD_ATI; 235ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_MODULATE_SUBTRACT_ATI: return MODE_MODULATE_SUBTRACT_ATI; 236114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger case GL_BUMP_ENVMAP_ATI: return MODE_BUMP_ENVMAP_ATI; 2376947f85cb5fbc433ba7763530285e470745b009bBrian Paul default: 2386947f85cb5fbc433ba7763530285e470745b009bBrian Paul assert(0); 2396947f85cb5fbc433ba7763530285e470745b009bBrian Paul return MODE_UNKNOWN; 240ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 241ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 242ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 243f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul 244f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul/** 245f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul * Translate TEXTURE_x_BIT to TEXTURE_x_INDEX. 246f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul */ 247e00ac11d4dd05c56584622dc2707bbdcfe4b2707Brian Paulstatic GLuint translate_tex_src_bit( GLbitfield bit ) 248ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 249b5ec0a68589c5d8f0d4be2556ea6d6b01fd4e37dBrian Paul ASSERT(bit); 250b5ec0a68589c5d8f0d4be2556ea6d6b01fd4e37dBrian Paul return _mesa_ffs(bit) - 1; 251ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 252ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 253f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul 2541680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell#define VERT_BIT_TEX_ANY (0xff << VERT_ATTRIB_TEX0) 2551680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell#define VERT_RESULT_TEX_ANY (0xff << VERT_RESULT_TEX0) 2561680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 257239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul/** 258239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul * Identify all possible varying inputs. The fragment program will 2591680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * never reference non-varying inputs, but will track them via state 2601680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * constants instead. 2611680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * 2621680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * This function figures out all the inputs that the fragment program 2631680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * has access to. The bitmask is later reduced to just those which 2641680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * are actually referenced. 2651680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell */ 266239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paulstatic GLbitfield get_fp_input_mask( GLcontext *ctx ) 2671680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell{ 268e5f63c403b767f9974e8eb5d412c012b8a69287fEric Anholt /* _NEW_PROGRAM */ 269f0b0794b3885a2fdfb168ec4521c7b5e942d3228Brian Paul const GLboolean vertexShader = (ctx->Shader.CurrentProgram && 27040990d9dfb20b69585859b2a45596aa46c20140aEric Anholt ctx->Shader.CurrentProgram->LinkStatus && 271f0b0794b3885a2fdfb168ec4521c7b5e942d3228Brian Paul ctx->Shader.CurrentProgram->VertexProgram); 272f0b0794b3885a2fdfb168ec4521c7b5e942d3228Brian Paul const GLboolean vertexProgram = ctx->VertexProgram._Enabled; 273239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul GLbitfield fp_inputs = 0x0; 2741680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 2756d4d51d647c27288aa625560bc080231099c0b01Brian Paul if (ctx->VertexProgram._Overriden) { 2766d4d51d647c27288aa625560bc080231099c0b01Brian Paul /* Somebody's messing with the vertex program and we don't have 2776d4d51d647c27288aa625560bc080231099c0b01Brian Paul * a clue what's happening. Assume that it could be producing 2786d4d51d647c27288aa625560bc080231099c0b01Brian Paul * all possible outputs. 2796d4d51d647c27288aa625560bc080231099c0b01Brian Paul */ 2806d4d51d647c27288aa625560bc080231099c0b01Brian Paul fp_inputs = ~0; 2816d4d51d647c27288aa625560bc080231099c0b01Brian Paul } 2826d4d51d647c27288aa625560bc080231099c0b01Brian Paul else if (ctx->RenderMode == GL_FEEDBACK) { 283e5f63c403b767f9974e8eb5d412c012b8a69287fEric Anholt /* _NEW_RENDERMODE */ 2846d4d51d647c27288aa625560bc080231099c0b01Brian Paul fp_inputs = (FRAG_BIT_COL0 | FRAG_BIT_TEX0); 2856d4d51d647c27288aa625560bc080231099c0b01Brian Paul } 286f0b0794b3885a2fdfb168ec4521c7b5e942d3228Brian Paul else if (!(vertexProgram || vertexShader) || 287d7296a1a8e846bc4d41ded1c2406b6f5c658188aBrian Paul !ctx->VertexProgram._Current) { 288f0b0794b3885a2fdfb168ec4521c7b5e942d3228Brian Paul /* Fixed function vertex logic */ 289e5f63c403b767f9974e8eb5d412c012b8a69287fEric Anholt /* _NEW_ARRAY */ 290239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul GLbitfield varying_inputs = ctx->varying_vp_inputs; 2911680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 29297e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell /* These get generated in the setup routine regardless of the 29397e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell * vertex program: 29497e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell */ 295e5f63c403b767f9974e8eb5d412c012b8a69287fEric Anholt /* _NEW_POINT */ 29697e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell if (ctx->Point.PointSprite) 29797e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell varying_inputs |= FRAG_BITS_TEX_ANY; 29897e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell 2991680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell /* First look at what values may be computed by the generated 3001680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * vertex program: 3011680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell */ 302e5f63c403b767f9974e8eb5d412c012b8a69287fEric Anholt /* _NEW_LIGHT */ 3031680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell if (ctx->Light.Enabled) { 3041680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell fp_inputs |= FRAG_BIT_COL0; 3051680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 3069cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt if (texenv_doing_secondary_color(ctx)) 3071680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell fp_inputs |= FRAG_BIT_COL1; 3081680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell } 3091680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 310e5f63c403b767f9974e8eb5d412c012b8a69287fEric Anholt /* _NEW_TEXTURE */ 3111680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell fp_inputs |= (ctx->Texture._TexGenEnabled | 3121680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell ctx->Texture._TexMatEnabled) << FRAG_ATTRIB_TEX0; 3131680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 3141680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell /* Then look at what might be varying as a result of enabled 3151680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * arrays, etc: 3161680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell */ 3176807d96f8efeecd9d71e1e1bff856e7e04f5f364Brian Paul if (varying_inputs & VERT_BIT_COLOR0) 3186807d96f8efeecd9d71e1e1bff856e7e04f5f364Brian Paul fp_inputs |= FRAG_BIT_COL0; 3196807d96f8efeecd9d71e1e1bff856e7e04f5f364Brian Paul if (varying_inputs & VERT_BIT_COLOR1) 3206807d96f8efeecd9d71e1e1bff856e7e04f5f364Brian Paul fp_inputs |= FRAG_BIT_COL1; 3211680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 3221680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell fp_inputs |= (((varying_inputs & VERT_BIT_TEX_ANY) >> VERT_ATTRIB_TEX0) 3231680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell << FRAG_ATTRIB_TEX0); 3241680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 3251680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell } 3261680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell else { 3271680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell /* calculate from vp->outputs */ 3282389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul struct gl_vertex_program *vprog; 3292389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul GLbitfield vp_outputs; 3302389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul 3312389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul /* Choose GLSL vertex shader over ARB vertex program. Need this 3322389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul * since vertex shader state validation comes after fragment state 3332389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul * validation (see additional comments in state.c). 3342389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul */ 3352389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul if (vertexShader) 3362389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul vprog = ctx->Shader.CurrentProgram->VertexProgram; 3372389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul else 338a9ba1bfeb3a2852c6eda718e73c46c972a286648Eric Anholt vprog = ctx->VertexProgram.Current; 3392389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul 3402389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul vp_outputs = vprog->Base.OutputsWritten; 3411680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 34297e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell /* These get generated in the setup routine regardless of the 34397e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell * vertex program: 34497e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell */ 345e5f63c403b767f9974e8eb5d412c012b8a69287fEric Anholt /* _NEW_POINT */ 34697e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell if (ctx->Point.PointSprite) 34797e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell vp_outputs |= FRAG_BITS_TEX_ANY; 34897e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell 3496807d96f8efeecd9d71e1e1bff856e7e04f5f364Brian Paul if (vp_outputs & (1 << VERT_RESULT_COL0)) 3506807d96f8efeecd9d71e1e1bff856e7e04f5f364Brian Paul fp_inputs |= FRAG_BIT_COL0; 3516807d96f8efeecd9d71e1e1bff856e7e04f5f364Brian Paul if (vp_outputs & (1 << VERT_RESULT_COL1)) 3526807d96f8efeecd9d71e1e1bff856e7e04f5f364Brian Paul fp_inputs |= FRAG_BIT_COL1; 3531680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 3540370d6b359016790c6b879c2a4b6661adac20deaKeith Whitwell fp_inputs |= (((vp_outputs & VERT_RESULT_TEX_ANY) >> VERT_RESULT_TEX0) 3550370d6b359016790c6b879c2a4b6661adac20deaKeith Whitwell << FRAG_ATTRIB_TEX0); 3561680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell } 3571680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 3581680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell return fp_inputs; 3591680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell} 3601680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 3611680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 36222db53577603afef8fdf62c324ff5977de76b9d8Brian Paul/** 36322db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * Examine current texture environment state and generate a unique 36422db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * key to identify it. 36522db53577603afef8fdf62c324ff5977de76b9d8Brian Paul */ 3668065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwellstatic void make_state_key( GLcontext *ctx, struct state_key *key ) 367ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 368ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint i, j; 369239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul GLbitfield inputs_referenced = FRAG_BIT_COL0; 370f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul const GLbitfield inputs_available = get_fp_input_mask( ctx ); 3711680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 3728065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell memset(key, 0, sizeof(*key)); 3738065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell 374e5f63c403b767f9974e8eb5d412c012b8a69287fEric Anholt /* _NEW_TEXTURE */ 375e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { 376d9736db6676948e06712d4bcba46b7040452f870Brian Paul const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i]; 377f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul const struct gl_texture_object *texObj = texUnit->_Current; 378f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul const struct gl_tex_env_combine_state *comb = texUnit->_CurrentCombine; 379b6bb5e09e0ad1f61f96c65bbc870bd493df12f1aXiang, Haihao GLenum format; 380bf4a0fafc86bba8dc868cf30244a237e33645164Roland Scheidegger 381bf4a0fafc86bba8dc868cf30244a237e33645164Roland Scheidegger if (!texUnit->_ReallyEnabled || !texUnit->Enabled) 382ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell continue; 383ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 384f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul format = texObj->Image[0][texObj->BaseLevel]->_BaseFormat; 385b6bb5e09e0ad1f61f96c65bbc870bd493df12f1aXiang, Haihao 386ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].enabled = 1; 387ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->enabled_units |= (1<<i); 3881680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell key->nr_enabled_units = i+1; 3891680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell inputs_referenced |= FRAG_BIT_TEX(i); 390ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 391f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul key->unit[i].source_index = 392f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul translate_tex_src_bit(texUnit->_ReallyEnabled); 393f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul 394f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul key->unit[i].shadow = ((texObj->CompareMode == GL_COMPARE_R_TO_TEXTURE) && 395b6bb5e09e0ad1f61f96c65bbc870bd493df12f1aXiang, Haihao ((format == GL_DEPTH_COMPONENT) || 396b6bb5e09e0ad1f61f96c65bbc870bd493df12f1aXiang, Haihao (format == GL_DEPTH_STENCIL_EXT))); 397ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 398f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul key->unit[i].NumArgsRGB = comb->_NumArgsRGB; 399f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul key->unit[i].NumArgsA = comb->_NumArgsA; 400ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 401ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].ModeRGB = 402f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul translate_mode(texUnit->EnvMode, comb->ModeRGB); 403ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].ModeA = 404f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul translate_mode(texUnit->EnvMode, comb->ModeA); 405114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 406f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul key->unit[i].ScaleShiftRGB = comb->ScaleShiftRGB; 407f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul key->unit[i].ScaleShiftA = comb->ScaleShiftA; 408ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 409bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul for (j = 0; j < MAX_COMBINER_TERMS; j++) { 410f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul key->unit[i].OptRGB[j].Operand = translate_operand(comb->OperandRGB[j]); 411f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul key->unit[i].OptA[j].Operand = translate_operand(comb->OperandA[j]); 412f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul key->unit[i].OptRGB[j].Source = translate_source(comb->SourceRGB[j]); 413f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul key->unit[i].OptA[j].Source = translate_source(comb->SourceA[j]); 414ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 415114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 416114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger if (key->unit[i].ModeRGB == MODE_BUMP_ENVMAP_ATI) { 417114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger /* requires some special translation */ 418114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger key->unit[i].NumArgsRGB = 2; 419114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger key->unit[i].ScaleShiftRGB = 0; 420114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger key->unit[i].OptRGB[0].Operand = OPR_SRC_COLOR; 421114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger key->unit[i].OptRGB[0].Source = SRC_TEXTURE; 422114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger key->unit[i].OptRGB[1].Operand = OPR_SRC_COLOR; 423114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger key->unit[i].OptRGB[1].Source = texUnit->BumpTarget - GL_TEXTURE0 + SRC_TEXTURE0; 424114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger } 425ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 426114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 4279cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt /* _NEW_LIGHT | _NEW_FOG */ 4289cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt if (texenv_doing_secondary_color(ctx)) { 429ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->separate_specular = 1; 4301680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell inputs_referenced |= FRAG_BIT_COL1; 4311680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell } 432ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 433e5f63c403b767f9974e8eb5d412c012b8a69287fEric Anholt /* _NEW_FOG */ 434ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (ctx->Fog.Enabled) { 435ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->fog_enabled = 1; 436ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->fog_mode = translate_fog_mode(ctx->Fog.Mode); 4371680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell inputs_referenced |= FRAG_BIT_FOGC; /* maybe */ 438ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 4391680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 4401680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell key->inputs_available = (inputs_available & inputs_referenced); 441ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 442ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 443239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul/** 444239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul * Use uregs to represent registers internally, translate to Mesa's 44515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * expected formats on emit. 44615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 44715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * NOTE: These are passed by value extensively in this file rather 44815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * than as usual by pointer reference. If this disturbs you, try 44915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * remembering they are just 32bits in size. 45015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 45115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * GCC is smart enough to deal with these dword-sized structures in 45215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * much the same way as if I had defined them as dwords and was using 45315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * macros to access and set the fields. This is much nicer and easier 45415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * to evolve. 45515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 45615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstruct ureg { 45715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint file:4; 45815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint idx:8; 45915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint negatebase:1; 46015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint swz:12; 4611480bcacfec8f215c5827278a5f984c6bf68ba69Brian Paul GLuint pad:7; 46215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell}; 46315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 46413abf91b42b00c7eb64c373aff3a4c1bb3d8fb7fBrian Paulstatic const struct ureg undef = { 4658d97265711b172da4f387748f0e72da9267492b0Alan Hourihane PROGRAM_UNDEFINED, 46615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell ~0, 46715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 0, 46815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 0, 46915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 0 47015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell}; 47115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 47215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 473239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul/** State used to build the fragment program: 47415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 47515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstruct texenv_fragment_program { 476122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul struct gl_fragment_program *program; 477ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct state_key *state; 47815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 479239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul GLbitfield alu_temps; /**< Track texture indirections, see spec. */ 480239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul GLbitfield temps_output; /**< Track texture indirections, see spec. */ 481239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul GLbitfield temp_in_use; /**< Tracks temporary regs which are in use. */ 48215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLboolean error; 48315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 484e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul struct ureg src_texture[MAX_TEXTURE_COORD_UNITS]; 485ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell /* Reg containing each texture unit's sampled texture color, 486ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell * else undef. 487ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell */ 48815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 489114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger struct ureg texcoord_tex[MAX_TEXTURE_COORD_UNITS]; 490114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger /* Reg containing texcoord for a texture unit, 491114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger * needed for bump mapping, else undef. 492114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger */ 493114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 494239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul struct ureg src_previous; /**< Reg containing color from previous 49515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * stage. May need to be decl'd. 49615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 49715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 498239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul GLuint last_tex_stage; /**< Number of last enabled texture unit */ 4992dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 5002dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell struct ureg half; 5012dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell struct ureg one; 5022dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell struct ureg zero; 50315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell}; 50415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 50515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 50615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 50715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg make_ureg(GLuint file, GLuint idx) 50815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 50915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg reg; 51015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.file = file; 51115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.idx = idx; 51215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.negatebase = 0; 51315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.swz = SWIZZLE_NOOP; 51415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.pad = 0; 51515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return reg; 51615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 51715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 51815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg swizzle( struct ureg reg, int x, int y, int z, int w ) 51915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 52015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.swz = MAKE_SWIZZLE4(GET_SWZ(reg.swz, x), 52115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GET_SWZ(reg.swz, y), 52215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GET_SWZ(reg.swz, z), 52315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GET_SWZ(reg.swz, w)); 52415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 52515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return reg; 52615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 52715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 52815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg swizzle1( struct ureg reg, int x ) 52915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 53015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return swizzle(reg, x, x, x, x); 53115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 53215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 5336fe176a64859798db17fbaed6858cccc646aae38Keith Whitwellstatic struct ureg negate( struct ureg reg ) 5346fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell{ 5356fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell reg.negatebase ^= 1; 5366fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell return reg; 5376fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell} 5386fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell 53915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic GLboolean is_undef( struct ureg reg ) 54015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 5418d97265711b172da4f387748f0e72da9267492b0Alan Hourihane return reg.file == PROGRAM_UNDEFINED; 54215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 54315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 544ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 54515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg get_temp( struct texenv_fragment_program *p ) 54615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 54713abf91b42b00c7eb64c373aff3a4c1bb3d8fb7fBrian Paul GLint bit; 548ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 549cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell /* First try and reuse temps which have been used already: 550ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell */ 551b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul bit = _mesa_ffs( ~p->temp_in_use & p->alu_temps ); 552ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 553ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell /* Then any unused temporary: 554ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell */ 555ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell if (!bit) 556b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul bit = _mesa_ffs( ~p->temp_in_use ); 557ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 558ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell if (!bit) { 559bfb5ea307ec48b9b8d0d2eca0c03f6d02273d454Brian Paul _mesa_problem(NULL, "%s: out of temporaries\n", __FILE__); 560b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul _mesa_exit(1); 561ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell } 562ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 56313abf91b42b00c7eb64c373aff3a4c1bb3d8fb7fBrian Paul if ((GLuint) bit > p->program->Base.NumTemporaries) 564b5cbaf945dd5213d5faf7bb7e4d68d0d25a25b55Keith Whitwell p->program->Base.NumTemporaries = bit; 565b5cbaf945dd5213d5faf7bb7e4d68d0d25a25b55Keith Whitwell 56693cd9237d793e38ba4479d1367be7548853f67f4Keith Whitwell p->temp_in_use |= 1<<(bit-1); 567ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell return make_ureg(PROGRAM_TEMPORARY, (bit-1)); 568ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell} 569ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 570ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwellstatic struct ureg get_tex_temp( struct texenv_fragment_program *p ) 571ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell{ 572ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell int bit; 573ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 574d01269a57f4cfdb859352c933bc546296545dd80Brian Paul /* First try to find available temp not previously used (to avoid 575cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell * starting a new texture indirection). According to the spec, the 576cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell * ~p->temps_output isn't necessary, but will keep it there for 577cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell * now: 578ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell */ 579b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul bit = _mesa_ffs( ~p->temp_in_use & ~p->alu_temps & ~p->temps_output ); 580ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 581ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell /* Then any unused temporary: 582ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell */ 583cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if (!bit) 584b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul bit = _mesa_ffs( ~p->temp_in_use ); 585ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 58615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell if (!bit) { 587bfb5ea307ec48b9b8d0d2eca0c03f6d02273d454Brian Paul _mesa_problem(NULL, "%s: out of temporaries\n", __FILE__); 588b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul _mesa_exit(1); 58915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 59015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 59113abf91b42b00c7eb64c373aff3a4c1bb3d8fb7fBrian Paul if ((GLuint) bit > p->program->Base.NumTemporaries) 592b5cbaf945dd5213d5faf7bb7e4d68d0d25a25b55Keith Whitwell p->program->Base.NumTemporaries = bit; 593b5cbaf945dd5213d5faf7bb7e4d68d0d25a25b55Keith Whitwell 59493cd9237d793e38ba4479d1367be7548853f67f4Keith Whitwell p->temp_in_use |= 1<<(bit-1); 59515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return make_ureg(PROGRAM_TEMPORARY, (bit-1)); 59615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 59715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 59815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 5995620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul/** Mark a temp reg as being no longer allocatable. */ 6005620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paulstatic void reserve_temp( struct texenv_fragment_program *p, struct ureg r ) 6015620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul{ 6025620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul if (r.file == PROGRAM_TEMPORARY) 6035620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul p->temps_output |= (1 << r.idx); 6045620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul} 6055620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul 6065620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul 60793fef22d05d0fb6f011d48d2fde533555c1695a2Brianstatic void release_temps(GLcontext *ctx, struct texenv_fragment_program *p ) 60815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 60993fef22d05d0fb6f011d48d2fde533555c1695a2Brian GLuint max_temp = ctx->Const.FragmentProgram.MaxTemps; 61093cd9237d793e38ba4479d1367be7548853f67f4Keith Whitwell 6112dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell /* KW: To support tex_env_crossbar, don't release the registers in 6122dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell * temps_output. 6132dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell */ 61493cd9237d793e38ba4479d1367be7548853f67f4Keith Whitwell if (max_temp >= sizeof(int) * 8) 6152dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell p->temp_in_use = p->temps_output; 61693cd9237d793e38ba4479d1367be7548853f67f4Keith Whitwell else 6172dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell p->temp_in_use = ~((1<<max_temp)-1) | p->temps_output; 61815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 61915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 62015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 6219fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brianstatic struct ureg register_param5( struct texenv_fragment_program *p, 622ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLint s0, 623ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLint s1, 624ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLint s2, 625ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLint s3, 6269fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brian GLint s4) 62715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 6289fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brian gl_state_index tokens[STATE_LENGTH]; 62947b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell GLuint idx; 63047b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell tokens[0] = s0; 63147b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell tokens[1] = s1; 63247b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell tokens[2] = s2; 63347b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell tokens[3] = s3; 63447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell tokens[4] = s4; 635de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul idx = _mesa_add_state_reference( p->program->Base.Parameters, tokens ); 63647b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell return make_ureg(PROGRAM_STATE_VAR, idx); 63747b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell} 63815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 63915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 6409fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brian#define register_param1(p,s0) register_param5(p,s0,0,0,0,0) 6419fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brian#define register_param2(p,s0,s1) register_param5(p,s0,s1,0,0,0) 6429fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brian#define register_param3(p,s0,s1,s2) register_param5(p,s0,s1,s2,0,0) 6439fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brian#define register_param4(p,s0,s1,s2,s3) register_param5(p,s0,s1,s2,s3,0) 64447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell 6451680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwellstatic GLuint frag_to_vert_attrib( GLuint attrib ) 6461680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell{ 6471680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell switch (attrib) { 6481680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell case FRAG_ATTRIB_COL0: return VERT_ATTRIB_COLOR0; 6491680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell case FRAG_ATTRIB_COL1: return VERT_ATTRIB_COLOR1; 6501680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell default: 6511680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell assert(attrib >= FRAG_ATTRIB_TEX0); 6521680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell assert(attrib <= FRAG_ATTRIB_TEX7); 6531680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell return attrib - FRAG_ATTRIB_TEX0 + VERT_ATTRIB_TEX0; 6541680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell } 6551680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell} 6561680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 65747b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell 65847b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwellstatic struct ureg register_input( struct texenv_fragment_program *p, GLuint input ) 65947b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell{ 6601680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell if (p->state->inputs_available & (1<<input)) { 6611680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell p->program->Base.InputsRead |= (1 << input); 6621680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell return make_ureg(PROGRAM_INPUT, input); 6631680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell } 6641680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell else { 6651680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell GLuint idx = frag_to_vert_attrib( input ); 6661680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell return register_param3( p, STATE_INTERNAL, STATE_CURRENT_ATTRIB, idx ); 6671680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell } 66815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 66915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 67047b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell 6717e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paulstatic void emit_arg( struct prog_src_register *reg, 67215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg ureg ) 67315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 67415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg->File = ureg.file; 67515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg->Index = ureg.idx; 67615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg->Swizzle = ureg.swz; 6777db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul reg->Negate = ureg.negatebase ? NEGATE_XYZW : NEGATE_NONE; 6781480bcacfec8f215c5827278a5f984c6bf68ba69Brian Paul reg->Abs = GL_FALSE; 67915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 68015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 6817e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paulstatic void emit_dst( struct prog_dst_register *dst, 68215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg ureg, GLuint mask ) 68315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 68415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell dst->File = ureg.file; 68515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell dst->Index = ureg.idx; 68615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell dst->WriteMask = mask; 687c9d495c6f064aacd1e072033b9c17a83b8c37fa1Brian dst->CondMask = COND_TR; /* always pass cond test */ 688c9d495c6f064aacd1e072033b9c17a83b8c37fa1Brian dst->CondSwizzle = SWIZZLE_NOOP; 68915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 69015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 6917e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paulstatic struct prog_instruction * 69215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellemit_op(struct texenv_fragment_program *p, 6935d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul enum prog_opcode op, 69415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg dest, 69515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint mask, 69622db53577603afef8fdf62c324ff5977de76b9d8Brian Paul GLboolean saturate, 69715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg src0, 69815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg src1, 69915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg src2 ) 70015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 7019ed0315271c38f5fe9cdd65020a54cbb7f61ed2bBrian Paul const GLuint nr = p->program->Base.NumInstructions++; 702de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul struct prog_instruction *inst = &p->program->Base.Instructions[nr]; 7032a8e9bb00f8cf830783cbc20a2a57f31b19491eaBrian 7042a8e9bb00f8cf830783cbc20a2a57f31b19491eaBrian assert(nr < MAX_INSTRUCTIONS); 7052a8e9bb00f8cf830783cbc20a2a57f31b19491eaBrian 706d6272e06172f7ac7a0d6e8062e8ffba33e1ab3baBrian Paul _mesa_init_instructions(inst, 1); 70715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell inst->Opcode = op; 70815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 70947b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell emit_arg( &inst->SrcReg[0], src0 ); 71047b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell emit_arg( &inst->SrcReg[1], src1 ); 71147b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell emit_arg( &inst->SrcReg[2], src2 ); 71215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 713e31ac052236ea615b4995f9ec301d8af4b864531Brian Paul inst->SaturateMode = saturate ? SATURATE_ZERO_ONE : SATURATE_OFF; 71415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 71515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell emit_dst( &inst->DstReg, dest, mask ); 71615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 7175620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul#if 0 718cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell /* Accounting for indirection tracking: 719cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell */ 720cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if (dest.file == PROGRAM_TEMPORARY) 721cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell p->temps_output |= 1 << dest.idx; 7225620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul#endif 723cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell 72415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return inst; 72515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 72615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 72715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 72815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg emit_arith( struct texenv_fragment_program *p, 7295d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul enum prog_opcode op, 73047b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell struct ureg dest, 73147b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell GLuint mask, 73222db53577603afef8fdf62c324ff5977de76b9d8Brian Paul GLboolean saturate, 73347b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell struct ureg src0, 73447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell struct ureg src1, 73547b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell struct ureg src2 ) 73615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 73715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell emit_op(p, op, dest, mask, saturate, src0, src1, src2); 73815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 739cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell /* Accounting for indirection tracking: 740cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell */ 741cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if (src0.file == PROGRAM_TEMPORARY) 742cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell p->alu_temps |= 1 << src0.idx; 743cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell 744cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if (!is_undef(src1) && src1.file == PROGRAM_TEMPORARY) 745cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell p->alu_temps |= 1 << src1.idx; 746cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell 747cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if (!is_undef(src2) && src2.file == PROGRAM_TEMPORARY) 748cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell p->alu_temps |= 1 << src2.idx; 749cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell 750cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if (dest.file == PROGRAM_TEMPORARY) 751cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell p->alu_temps |= 1 << dest.idx; 752cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell 75321f99792a916a62fcfae7c208f50f192d4ce5926Brian p->program->Base.NumAluInstructions++; 75415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return dest; 75515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 75615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 75715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg emit_texld( struct texenv_fragment_program *p, 7585d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul enum prog_opcode op, 759ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct ureg dest, 760ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint destmask, 761ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint tex_unit, 762ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint tex_idx, 76344e018c09e7aeba9fd9f4c380da224bd6622c470Brian Paul GLuint tex_shadow, 764ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct ureg coord ) 76515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 7667e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul struct prog_instruction *inst = emit_op( p, op, 76715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell dest, destmask, 76822db53577603afef8fdf62c324ff5977de76b9d8Brian Paul GL_FALSE, /* don't saturate? */ 76915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell coord, /* arg 0? */ 77015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell undef, 77115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell undef); 77215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 7737e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul inst->TexSrcTarget = tex_idx; 77415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell inst->TexSrcUnit = tex_unit; 77544e018c09e7aeba9fd9f4c380da224bd6622c470Brian Paul inst->TexShadow = tex_shadow; 77615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 77721f99792a916a62fcfae7c208f50f192d4ce5926Brian p->program->Base.NumTexInstructions++; 77815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 7795620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul /* Accounting for indirection tracking: 7805620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul */ 7815620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul reserve_temp(p, dest); 7825620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul 783114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger#if 0 784cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell /* Is this a texture indirection? 785cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell */ 786cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if ((coord.file == PROGRAM_TEMPORARY && 787cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell (p->temps_output & (1<<coord.idx))) || 788cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell (dest.file == PROGRAM_TEMPORARY && 789cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell (p->alu_temps & (1<<dest.idx)))) { 79021f99792a916a62fcfae7c208f50f192d4ce5926Brian p->program->Base.NumTexIndirections++; 7912dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell p->temps_output = 1<<coord.idx; 792cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell p->alu_temps = 0; 7932dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell assert(0); /* KW: texture env crossbar */ 79415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 795114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger#endif 79615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 79715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return dest; 79815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 79915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 80015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 80147b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwellstatic struct ureg register_const4f( struct texenv_fragment_program *p, 802ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLfloat s0, 803ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLfloat s1, 804ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLfloat s2, 805ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLfloat s3) 80615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 80747b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell GLfloat values[4]; 808a90046f1097ad95de2aa95ca65741dff5cddced9Brian GLuint idx, swizzle; 809d01269a57f4cfdb859352c933bc546296545dd80Brian Paul struct ureg r; 81047b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell values[0] = s0; 81147b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell values[1] = s1; 81247b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell values[2] = s2; 81347b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell values[3] = s3; 814a90046f1097ad95de2aa95ca65741dff5cddced9Brian idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4, 815a90046f1097ad95de2aa95ca65741dff5cddced9Brian &swizzle ); 816d01269a57f4cfdb859352c933bc546296545dd80Brian Paul r = make_ureg(PROGRAM_CONSTANT, idx); 817d01269a57f4cfdb859352c933bc546296545dd80Brian Paul r.swz = swizzle; 818d01269a57f4cfdb859352c933bc546296545dd80Brian Paul return r; 81915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 82015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 821e490242b9aeb50bd96fed7a9afbf529295a8ac0eKeith Whitwell#define register_scalar_const(p, s0) register_const4f(p, s0, s0, s0, s0) 82247b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell#define register_const1f(p, s0) register_const4f(p, s0, 0, 0, 1) 82347b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell#define register_const2f(p, s0, s1) register_const4f(p, s0, s1, 0, 1) 82447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell#define register_const3f(p, s0, s1, s2) register_const4f(p, s0, s1, s2, 1) 82515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 82615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 8272dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwellstatic struct ureg get_one( struct texenv_fragment_program *p ) 8282dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell{ 8292dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell if (is_undef(p->one)) 8302dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell p->one = register_scalar_const(p, 1.0); 8312dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell return p->one; 8322dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell} 8332dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 8342dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwellstatic struct ureg get_half( struct texenv_fragment_program *p ) 8352dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell{ 8362dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell if (is_undef(p->half)) 8374dd8a8907e40126e42131a400b59e7d5da5e302aAapo Tahkola p->half = register_scalar_const(p, 0.5); 8382dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell return p->half; 8392dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell} 8402dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 8412dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwellstatic struct ureg get_zero( struct texenv_fragment_program *p ) 8422dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell{ 8432dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell if (is_undef(p->zero)) 8444dd8a8907e40126e42131a400b59e7d5da5e302aAapo Tahkola p->zero = register_scalar_const(p, 0.0); 8452dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell return p->zero; 8462dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell} 8472dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 84815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 84915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic void program_error( struct texenv_fragment_program *p, const char *msg ) 85015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 851bfb5ea307ec48b9b8d0d2eca0c03f6d02273d454Brian Paul _mesa_problem(NULL, msg); 85215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell p->error = 1; 85315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 85415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 85515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg get_source( struct texenv_fragment_program *p, 856ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint src, GLuint unit ) 85715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 85815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell switch (src) { 859ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE: 8602dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell assert(!is_undef(p->src_texture[unit])); 8612dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell return p->src_texture[unit]; 86215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 863ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE0: 864ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE1: 865ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE2: 866ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE3: 867ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE4: 868ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE5: 869ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE6: 870ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE7: 871ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell assert(!is_undef(p->src_texture[src - SRC_TEXTURE0])); 872ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell return p->src_texture[src - SRC_TEXTURE0]; 873ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 874ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_CONSTANT: 87547b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell return register_param2(p, STATE_TEXENV_COLOR, unit); 8762dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 877ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_PRIMARY_COLOR: 87847b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell return register_input(p, FRAG_ATTRIB_COL0); 8792dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 8806947f85cb5fbc433ba7763530285e470745b009bBrian Paul case SRC_ZERO: 8816947f85cb5fbc433ba7763530285e470745b009bBrian Paul return get_zero(p); 8826947f85cb5fbc433ba7763530285e470745b009bBrian Paul 883ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_PREVIOUS: 88447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell if (is_undef(p->src_previous)) 88547b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell return register_input(p, FRAG_ATTRIB_COL0); 88647b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell else 88747b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell return p->src_previous; 8886947f85cb5fbc433ba7763530285e470745b009bBrian Paul 8896947f85cb5fbc433ba7763530285e470745b009bBrian Paul default: 8906947f85cb5fbc433ba7763530285e470745b009bBrian Paul assert(0); 891c6af9b29476e4e445623e7a2f737ba95003bbe13José Fonseca return undef; 89215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 89315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 8942dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 89515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg emit_combine_source( struct texenv_fragment_program *p, 896ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint mask, 897ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint unit, 898ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint source, 899ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint operand ) 90015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 90115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg arg, src, one; 90215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 90315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell src = get_source(p, source, unit); 90415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 90515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell switch (operand) { 906ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE_MINUS_SRC_COLOR: 90715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Get unused tmp, 90815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * Emit tmp = 1.0 - arg.xyzw 90915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 91015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell arg = get_temp( p ); 9112dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell one = get_one( p ); 9127e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_SUB, arg, mask, 0, one, src, undef); 91315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 914ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_SRC_ALPHA: 91515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell if (mask == WRITEMASK_W) 91615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return src; 91715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell else 91822db53577603afef8fdf62c324ff5977de76b9d8Brian Paul return swizzle1( src, SWIZZLE_W ); 919ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE_MINUS_SRC_ALPHA: 92015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Get unused tmp, 92115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * Emit tmp = 1.0 - arg.wwww 92215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 9232dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell arg = get_temp(p); 9242dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell one = get_one(p); 9257e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith(p, OPCODE_SUB, arg, mask, 0, 92622db53577603afef8fdf62c324ff5977de76b9d8Brian Paul one, swizzle1(src, SWIZZLE_W), undef); 927ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ZERO: 9282dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell return get_zero(p); 929ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE: 9302dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell return get_one(p); 931ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_SRC_COLOR: 9326947f85cb5fbc433ba7763530285e470745b009bBrian Paul return src; 93315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 9346947f85cb5fbc433ba7763530285e470745b009bBrian Paul assert(0); 93515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return src; 93615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 93715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 93815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 939f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul/** 940f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul * Check if the RGB and Alpha sources and operands match for the given 941f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul * texture unit's combinder state. When the RGB and A sources and 942f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul * operands match, we can emit fewer instructions. 943f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul */ 944a5e7003565a021ceb82a8b16f4a0ecc7cc6c02e0Brian Paulstatic GLboolean args_match( const struct state_key *key, GLuint unit ) 94515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 9469ed0315271c38f5fe9cdd65020a54cbb7f61ed2bBrian Paul GLuint i, numArgs = key->unit[unit].NumArgsRGB; 94715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 948457e427e32324884acb064b756e327dc131ff135Brian Paul for (i = 0; i < numArgs; i++) { 949ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->unit[unit].OptA[i].Source != key->unit[unit].OptRGB[i].Source) 95015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return GL_FALSE; 95115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 9529ed0315271c38f5fe9cdd65020a54cbb7f61ed2bBrian Paul switch (key->unit[unit].OptA[i].Operand) { 953ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_SRC_ALPHA: 9549ed0315271c38f5fe9cdd65020a54cbb7f61ed2bBrian Paul switch (key->unit[unit].OptRGB[i].Operand) { 955ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_SRC_COLOR: 956ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_SRC_ALPHA: 95715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 95815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 95915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return GL_FALSE; 96015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 96115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 962ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE_MINUS_SRC_ALPHA: 9639ed0315271c38f5fe9cdd65020a54cbb7f61ed2bBrian Paul switch (key->unit[unit].OptRGB[i].Operand) { 964ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE_MINUS_SRC_COLOR: 965ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE_MINUS_SRC_ALPHA: 96615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 96715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 96815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return GL_FALSE; 96915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 97015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 97115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 97215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return GL_FALSE; /* impossible */ 97315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 97415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 97515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 97615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return GL_TRUE; 97715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 97815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 97915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg emit_combine( struct texenv_fragment_program *p, 980ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct ureg dest, 981ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint mask, 98222db53577603afef8fdf62c324ff5977de76b9d8Brian Paul GLboolean saturate, 983ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint unit, 984ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint nr, 985ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint mode, 986d9736db6676948e06712d4bcba46b7040452f870Brian Paul const struct mode_opt *opt) 987ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 988bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul struct ureg src[MAX_COMBINER_TERMS]; 989cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell struct ureg tmp, half; 99022db53577603afef8fdf62c324ff5977de76b9d8Brian Paul GLuint i; 99115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 992bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul assert(nr <= MAX_COMBINER_TERMS); 9936947f85cb5fbc433ba7763530285e470745b009bBrian Paul 9940063084804d62402d80821a86978660663955442Brian Paul tmp = undef; /* silence warning (bug 5318) */ 9950063084804d62402d80821a86978660663955442Brian Paul 99615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell for (i = 0; i < nr; i++) 997ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell src[i] = emit_combine_source( p, mask, unit, opt[i].Source, opt[i].Operand ); 99815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 99915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell switch (mode) { 1000ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_REPLACE: 100115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell if (mask == WRITEMASK_XYZW && !saturate) 100215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return src[0]; 100315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell else 10047e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_MOV, dest, mask, saturate, src[0], undef, undef ); 1005ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_MODULATE: 10067e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_MUL, dest, mask, saturate, 10076fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell src[0], src[1], undef ); 1008ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_ADD: 10097e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_ADD, dest, mask, saturate, 10106fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell src[0], src[1], undef ); 1011ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_ADD_SIGNED: 101215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* tmp = arg0 + arg1 1013cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell * result = tmp - .5 101415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 10152dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell half = get_half(p); 101699da2d30eb08e50edf4b0067518af3acdf2dabc0Jerome Glisse tmp = get_temp( p ); 10177e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_ADD, tmp, mask, 0, src[0], src[1], undef ); 10187e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_SUB, dest, mask, saturate, tmp, half, undef ); 101915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return dest; 1020ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_INTERPOLATE: 102115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Arg0 * (Arg2) + Arg1 * (1-Arg2) -- note arguments are reordered: 102215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 10237e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_LRP, dest, mask, saturate, src[2], src[0], src[1] ); 102415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1025ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_SUBTRACT: 10267e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_SUB, dest, mask, saturate, src[0], src[1], undef ); 102715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1028ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGBA: 1029ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGBA_EXT: 1030ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGB_EXT: 1031ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGB: { 103215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg tmp0 = get_temp( p ); 103315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg tmp1 = get_temp( p ); 1034e490242b9aeb50bd96fed7a9afbf529295a8ac0eKeith Whitwell struct ureg neg1 = register_scalar_const(p, -1); 1035e490242b9aeb50bd96fed7a9afbf529295a8ac0eKeith Whitwell struct ureg two = register_scalar_const(p, 2); 103615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 103715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* tmp0 = 2*src0 - 1 103815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * tmp1 = 2*src1 - 1 103915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 104015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * dst = tmp0 dot3 tmp1 104115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 10427e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_MAD, tmp0, WRITEMASK_XYZW, 0, 10436fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell two, src[0], neg1); 104415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1045aa2069586d434dd0487b0daa2b583efe801a0d51Brian Paul if (_mesa_memcmp(&src[0], &src[1], sizeof(struct ureg)) == 0) 104615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell tmp1 = tmp0; 104715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell else 10487e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_MAD, tmp1, WRITEMASK_XYZW, 0, 10496fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell two, src[1], neg1); 10507e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_DP3, dest, mask, saturate, tmp0, tmp1, undef); 105115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return dest; 105215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 1053ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_MODULATE_ADD_ATI: 10546fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell /* Arg0 * Arg2 + Arg1 */ 10557e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_MAD, dest, mask, saturate, 10566fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell src[0], src[2], src[1] ); 1057ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_MODULATE_SIGNED_ADD_ATI: { 10586fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell /* Arg0 * Arg2 + Arg1 - 0.5 */ 10596fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell struct ureg tmp0 = get_temp(p); 10602dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell half = get_half(p); 10617e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_MAD, tmp0, mask, 0, src[0], src[2], src[1] ); 10627e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_SUB, dest, mask, saturate, tmp0, half, undef ); 10636fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell return dest; 10646fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell } 1065ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_MODULATE_SUBTRACT_ATI: 10666fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell /* Arg0 * Arg2 - Arg1 */ 10677e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_MAD, dest, mask, 0, src[0], src[2], negate(src[1]) ); 10686fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell return dest; 10696947f85cb5fbc433ba7763530285e470745b009bBrian Paul case MODE_ADD_PRODUCTS: 10706947f85cb5fbc433ba7763530285e470745b009bBrian Paul /* Arg0 * Arg1 + Arg2 * Arg3 */ 10716947f85cb5fbc433ba7763530285e470745b009bBrian Paul { 10726947f85cb5fbc433ba7763530285e470745b009bBrian Paul struct ureg tmp0 = get_temp(p); 10736947f85cb5fbc433ba7763530285e470745b009bBrian Paul emit_arith( p, OPCODE_MUL, tmp0, mask, 0, src[0], src[1], undef ); 10746947f85cb5fbc433ba7763530285e470745b009bBrian Paul emit_arith( p, OPCODE_MAD, dest, mask, saturate, src[2], src[3], tmp0 ); 10756947f85cb5fbc433ba7763530285e470745b009bBrian Paul } 10766947f85cb5fbc433ba7763530285e470745b009bBrian Paul return dest; 10776947f85cb5fbc433ba7763530285e470745b009bBrian Paul case MODE_ADD_PRODUCTS_SIGNED: 10786947f85cb5fbc433ba7763530285e470745b009bBrian Paul /* Arg0 * Arg1 + Arg2 * Arg3 - 0.5 */ 10796947f85cb5fbc433ba7763530285e470745b009bBrian Paul { 10806947f85cb5fbc433ba7763530285e470745b009bBrian Paul struct ureg tmp0 = get_temp(p); 10816947f85cb5fbc433ba7763530285e470745b009bBrian Paul half = get_half(p); 10826947f85cb5fbc433ba7763530285e470745b009bBrian Paul emit_arith( p, OPCODE_MUL, tmp0, mask, 0, src[0], src[1], undef ); 10836947f85cb5fbc433ba7763530285e470745b009bBrian Paul emit_arith( p, OPCODE_MAD, tmp0, mask, 0, src[2], src[3], tmp0 ); 10846947f85cb5fbc433ba7763530285e470745b009bBrian Paul emit_arith( p, OPCODE_SUB, dest, mask, saturate, tmp0, half, undef ); 10856947f85cb5fbc433ba7763530285e470745b009bBrian Paul } 10866947f85cb5fbc433ba7763530285e470745b009bBrian Paul return dest; 1087114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger case MODE_BUMP_ENVMAP_ATI: 1088114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger /* special - not handled here */ 1089114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger assert(0); 1090114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger return src[0]; 109115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 10926947f85cb5fbc433ba7763530285e470745b009bBrian Paul assert(0); 109315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return src[0]; 109415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 109515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 109615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 109715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 109822db53577603afef8fdf62c324ff5977de76b9d8Brian Paul/** 109922db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * Generate instructions for one texture unit's env/combiner mode. 110022db53577603afef8fdf62c324ff5977de76b9d8Brian Paul */ 110122db53577603afef8fdf62c324ff5977de76b9d8Brian Paulstatic struct ureg 110222db53577603afef8fdf62c324ff5977de76b9d8Brian Paulemit_texenv(struct texenv_fragment_program *p, GLuint unit) 110315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 1104a5e7003565a021ceb82a8b16f4a0ecc7cc6c02e0Brian Paul const struct state_key *key = p->state; 1105956e6c3978abe918348377cf05e5c92971e50d3fBrian Paul GLboolean saturate; 110615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint rgb_shift, alpha_shift; 1107a5e7003565a021ceb82a8b16f4a0ecc7cc6c02e0Brian Paul struct ureg out, dest; 110815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1109ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (!key->unit[unit].enabled) { 1110ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell return get_source(p, SRC_PREVIOUS, 0); 111115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 1112114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger if (key->unit[unit].ModeRGB == MODE_BUMP_ENVMAP_ATI) { 1113114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger /* this isn't really a env stage delivering a color and handled elsewhere */ 1114114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger return get_source(p, SRC_PREVIOUS, 0); 1115114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger } 1116ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 1117ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch (key->unit[unit].ModeRGB) { 1118ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGB_EXT: 1119ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell alpha_shift = key->unit[unit].ScaleShiftA; 112015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell rgb_shift = 0; 112115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 1122ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGBA_EXT: 112315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell alpha_shift = 0; 112415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell rgb_shift = 0; 112515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 112615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 1127ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell rgb_shift = key->unit[unit].ScaleShiftRGB; 1128ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell alpha_shift = key->unit[unit].ScaleShiftA; 112915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 113015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 1131ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 1132956e6c3978abe918348377cf05e5c92971e50d3fBrian Paul /* If we'll do rgb/alpha shifting don't saturate in emit_combine(). 1133956e6c3978abe918348377cf05e5c92971e50d3fBrian Paul * We don't want to clamp twice. 1134956e6c3978abe918348377cf05e5c92971e50d3fBrian Paul */ 1135956e6c3978abe918348377cf05e5c92971e50d3fBrian Paul saturate = !(rgb_shift || alpha_shift); 1136956e6c3978abe918348377cf05e5c92971e50d3fBrian Paul 1137cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell /* If this is the very last calculation, emit direct to output reg: 1138cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell */ 1139ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->separate_specular || 1140cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell unit != p->last_tex_stage || 1141cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell alpha_shift || 1142cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell rgb_shift) 1143cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell dest = get_temp( p ); 1144cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell else 11458d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul dest = make_ureg(PROGRAM_OUTPUT, FRAG_RESULT_COLOR); 114615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 114715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Emit the RGB and A combine ops 114815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 1149ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->unit[unit].ModeRGB == key->unit[unit].ModeA && 1150ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell args_match(key, unit)) { 115115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell out = emit_combine( p, dest, WRITEMASK_XYZW, saturate, 115215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell unit, 1153ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].NumArgsRGB, 1154ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].ModeRGB, 1155ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].OptRGB); 115615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 1157ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell else if (key->unit[unit].ModeRGB == MODE_DOT3_RGBA_EXT || 11589a45176dd85a1cd523498efeebd0481950a1bf58Roland Scheidegger key->unit[unit].ModeRGB == MODE_DOT3_RGBA) { 115915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell out = emit_combine( p, dest, WRITEMASK_XYZW, saturate, 116015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell unit, 1161ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].NumArgsRGB, 1162ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].ModeRGB, 1163ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].OptRGB); 116415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 116515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell else { 116615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Need to do something to stop from re-emitting identical 116715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * argument calculations here: 116815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 116915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell out = emit_combine( p, dest, WRITEMASK_XYZ, saturate, 117015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell unit, 1171ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].NumArgsRGB, 1172ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].ModeRGB, 1173ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].OptRGB); 117415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell out = emit_combine( p, dest, WRITEMASK_W, saturate, 117515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell unit, 1176ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].NumArgsA, 1177ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].ModeA, 1178ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].OptA); 117915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 118015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 118115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Deal with the final shift: 118215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 118315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell if (alpha_shift || rgb_shift) { 1184a5e7003565a021ceb82a8b16f4a0ecc7cc6c02e0Brian Paul struct ureg shift; 1185a5e7003565a021ceb82a8b16f4a0ecc7cc6c02e0Brian Paul 1186956e6c3978abe918348377cf05e5c92971e50d3fBrian Paul saturate = GL_TRUE; /* always saturate at this point */ 1187a5e7003565a021ceb82a8b16f4a0ecc7cc6c02e0Brian Paul 118815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell if (rgb_shift == alpha_shift) { 1189452a592ca4b1bac78eee53fb9f2f1deac7832840José Fonseca shift = register_scalar_const(p, (GLfloat)(1<<rgb_shift)); 119015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 119115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell else { 11922dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell shift = register_const4f(p, 1193452a592ca4b1bac78eee53fb9f2f1deac7832840José Fonseca (GLfloat)(1<<rgb_shift), 1194452a592ca4b1bac78eee53fb9f2f1deac7832840José Fonseca (GLfloat)(1<<rgb_shift), 1195452a592ca4b1bac78eee53fb9f2f1deac7832840José Fonseca (GLfloat)(1<<rgb_shift), 1196452a592ca4b1bac78eee53fb9f2f1deac7832840José Fonseca (GLfloat)(1<<alpha_shift)); 119715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 11987e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_MUL, dest, WRITEMASK_XYZW, 119915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell saturate, out, shift, undef ); 120015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 120115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell else 120215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return out; 120315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 120415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 12052dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 120622db53577603afef8fdf62c324ff5977de76b9d8Brian Paul/** 120722db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * Generate instruction for getting a texture source term. 120822db53577603afef8fdf62c324ff5977de76b9d8Brian Paul */ 12092dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwellstatic void load_texture( struct texenv_fragment_program *p, GLuint unit ) 12102dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell{ 12112dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell if (is_undef(p->src_texture[unit])) { 1212b5ec0a68589c5d8f0d4be2556ea6d6b01fd4e37dBrian Paul const GLuint texTarget = p->state->unit[unit].source_index; 1213114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger struct ureg texcoord; 12142dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell struct ureg tmp = get_tex_temp( p ); 12152dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 1216114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger if (is_undef(p->texcoord_tex[unit])) { 1217114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger texcoord = register_input(p, FRAG_ATTRIB_TEX0+unit); 1218114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger } 1219114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger else { 1220114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger /* might want to reuse this reg for tex output actually */ 1221114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger texcoord = p->texcoord_tex[unit]; 1222114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger } 1223114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 12242dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell /* TODO: Use D0_MASK_XY where possible. 12252dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell */ 122683ad2a756ea8dd1b0ca9746e355ce3de0f29356eNicolai Haehnle if (p->state->unit[unit].enabled) { 122744e018c09e7aeba9fd9f4c380da224bd6622c470Brian Paul GLboolean shadow = GL_FALSE; 12280397b2bb41b0f337af2949a15bcd7d0e7e8a7dc1Keith Whitwell 122944e018c09e7aeba9fd9f4c380da224bd6622c470Brian Paul if (p->state->unit[unit].shadow) { 123083ad2a756ea8dd1b0ca9746e355ce3de0f29356eNicolai Haehnle p->program->Base.ShadowSamplers |= 1 << unit; 123144e018c09e7aeba9fd9f4c380da224bd6622c470Brian Paul shadow = GL_TRUE; 123244e018c09e7aeba9fd9f4c380da224bd6622c470Brian Paul } 123344e018c09e7aeba9fd9f4c380da224bd6622c470Brian Paul 123444e018c09e7aeba9fd9f4c380da224bd6622c470Brian Paul p->src_texture[unit] = emit_texld( p, OPCODE_TXP, 123544e018c09e7aeba9fd9f4c380da224bd6622c470Brian Paul tmp, WRITEMASK_XYZW, 123644e018c09e7aeba9fd9f4c380da224bd6622c470Brian Paul unit, texTarget, shadow, 123744e018c09e7aeba9fd9f4c380da224bd6622c470Brian Paul texcoord ); 12389b7e5a51f49e842f4114545f5eb171a597c83a66Brian 12399b7e5a51f49e842f4114545f5eb171a597c83a66Brian p->program->Base.SamplersUsed |= (1 << unit); 12401fe385fdc96688a5249d52184f457910a0c25488Brian /* This identity mapping should already be in place 12411fe385fdc96688a5249d52184f457910a0c25488Brian * (see _mesa_init_program_struct()) but let's be safe. 12421fe385fdc96688a5249d52184f457910a0c25488Brian */ 12431fe385fdc96688a5249d52184f457910a0c25488Brian p->program->Base.SamplerUnits[unit] = unit; 12449b7e5a51f49e842f4114545f5eb171a597c83a66Brian } 12459b7e5a51f49e842f4114545f5eb171a597c83a66Brian else 1246b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola p->src_texture[unit] = get_zero(p); 12472dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell } 12482dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell} 12492dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 1250241b6b7ab1a1a11c7fc516d1b6ff2c1bc8aba238Keith Whitwellstatic GLboolean load_texenv_source( struct texenv_fragment_program *p, 1251ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint src, GLuint unit ) 12522dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell{ 12532dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell switch (src) { 12544dd8a8907e40126e42131a400b59e7d5da5e302aAapo Tahkola case SRC_TEXTURE: 12552dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell load_texture(p, unit); 12562dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell break; 12572dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 1258ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE0: 1259ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE1: 1260ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE2: 1261ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE3: 1262ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE4: 1263ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE5: 1264ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE6: 1265ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE7: 1266ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell load_texture(p, src - SRC_TEXTURE0); 12672dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell break; 12682dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 12692dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell default: 12706947f85cb5fbc433ba7763530285e470745b009bBrian Paul /* not a texture src - do nothing */ 12712dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell break; 12722dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell } 1273241b6b7ab1a1a11c7fc516d1b6ff2c1bc8aba238Keith Whitwell 1274241b6b7ab1a1a11c7fc516d1b6ff2c1bc8aba238Keith Whitwell return GL_TRUE; 12752dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell} 12762dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 127722db53577603afef8fdf62c324ff5977de76b9d8Brian Paul 127822db53577603afef8fdf62c324ff5977de76b9d8Brian Paul/** 127922db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * Generate instructions for loading all texture source terms. 128022db53577603afef8fdf62c324ff5977de76b9d8Brian Paul */ 128122db53577603afef8fdf62c324ff5977de76b9d8Brian Paulstatic GLboolean 1282457e427e32324884acb064b756e327dc131ff135Brian Paulload_texunit_sources( struct texenv_fragment_program *p, GLuint unit ) 12832dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell{ 1284a5e7003565a021ceb82a8b16f4a0ecc7cc6c02e0Brian Paul const struct state_key *key = p->state; 1285b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola GLuint i; 1286b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola 1287b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola for (i = 0; i < key->unit[unit].NumArgsRGB; i++) { 1288114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger load_texenv_source( p, key->unit[unit].OptRGB[i].Source, unit ); 1289b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola } 1290b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola 1291b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola for (i = 0; i < key->unit[unit].NumArgsA; i++) { 1292b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola load_texenv_source( p, key->unit[unit].OptA[i].Source, unit ); 12932dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell } 1294b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola 1295241b6b7ab1a1a11c7fc516d1b6ff2c1bc8aba238Keith Whitwell return GL_TRUE; 12962dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell} 12972dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 1298114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger/** 1299114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger * Generate instructions for loading bump map textures. 1300114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger */ 1301114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheideggerstatic GLboolean 1302457e427e32324884acb064b756e327dc131ff135Brian Paulload_texunit_bumpmap( struct texenv_fragment_program *p, GLuint unit ) 1303114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger{ 1304a5e7003565a021ceb82a8b16f4a0ecc7cc6c02e0Brian Paul const struct state_key *key = p->state; 1305114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger GLuint bumpedUnitNr = key->unit[unit].OptRGB[1].Source - SRC_TEXTURE0; 1306114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger struct ureg texcDst, bumpMapRes; 1307114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger struct ureg constdudvcolor = register_const4f(p, 0.0, 0.0, 0.0, 1.0); 1308114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger struct ureg texcSrc = register_input(p, FRAG_ATTRIB_TEX0 + bumpedUnitNr); 1309114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger struct ureg rotMat0 = register_param3( p, STATE_INTERNAL, STATE_ROT_MATRIX_0, unit ); 1310114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger struct ureg rotMat1 = register_param3( p, STATE_INTERNAL, STATE_ROT_MATRIX_1, unit ); 1311114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 1312114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger load_texenv_source( p, unit + SRC_TEXTURE0, unit ); 1313114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 1314114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger bumpMapRes = get_source(p, key->unit[unit].OptRGB[0].Source, unit); 1315114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger texcDst = get_tex_temp( p ); 1316114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger p->texcoord_tex[bumpedUnitNr] = texcDst; 1317114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 1318457e427e32324884acb064b756e327dc131ff135Brian Paul /* Apply rot matrix and add coords to be available in next phase. 1319457e427e32324884acb064b756e327dc131ff135Brian Paul * dest = (Arg0.xxxx * rotMat0 + Arg1) + (Arg0.yyyy * rotMat1) 1320457e427e32324884acb064b756e327dc131ff135Brian Paul * note only 2 coords are affected the rest are left unchanged (mul by 0) 1321457e427e32324884acb064b756e327dc131ff135Brian Paul */ 1322114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger emit_arith( p, OPCODE_MAD, texcDst, WRITEMASK_XYZW, 0, 1323114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger swizzle1(bumpMapRes, SWIZZLE_X), rotMat0, texcSrc ); 1324114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger emit_arith( p, OPCODE_MAD, texcDst, WRITEMASK_XYZW, 0, 1325114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger swizzle1(bumpMapRes, SWIZZLE_Y), rotMat1, texcDst ); 1326114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 1327457e427e32324884acb064b756e327dc131ff135Brian Paul /* Move 0,0,0,1 into bumpmap src if someone (crossbar) is foolish 1328457e427e32324884acb064b756e327dc131ff135Brian Paul * enough to access this later, should optimize away. 1329457e427e32324884acb064b756e327dc131ff135Brian Paul */ 1330457e427e32324884acb064b756e327dc131ff135Brian Paul emit_arith( p, OPCODE_MOV, bumpMapRes, WRITEMASK_XYZW, 0, 1331457e427e32324884acb064b756e327dc131ff135Brian Paul constdudvcolor, undef, undef ); 1332114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 1333114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger return GL_TRUE; 1334114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger} 133522db53577603afef8fdf62c324ff5977de76b9d8Brian Paul 133622db53577603afef8fdf62c324ff5977de76b9d8Brian Paul/** 133722db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * Generate a new fragment program which implements the context's 133822db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * current texture env/combine mode. 133922db53577603afef8fdf62c324ff5977de76b9d8Brian Paul */ 134022db53577603afef8fdf62c324ff5977de76b9d8Brian Paulstatic void 1341e998c346471142db91a1bcb6c61551b8247b87e7Brian Paulcreate_new_program(GLcontext *ctx, struct state_key *key, 1342122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul struct gl_fragment_program *program) 134315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 1344e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul struct prog_instruction instBuffer[MAX_INSTRUCTIONS]; 134515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct texenv_fragment_program p; 134615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint unit; 134715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg cf, out; 1348276330b2412910777f7016f427909085f02acbb8Keith Whitwell 1349e490242b9aeb50bd96fed7a9afbf529295a8ac0eKeith Whitwell _mesa_memset(&p, 0, sizeof(p)); 1350ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell p.state = key; 1351ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell p.program = program; 135215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1353e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul /* During code generation, use locally-allocated instruction buffer, 1354e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul * then alloc dynamic storage below. 1355e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul */ 1356e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul p.program->Base.Instructions = instBuffer; 1357276330b2412910777f7016f427909085f02acbb8Keith Whitwell p.program->Base.Target = GL_FRAGMENT_PROGRAM_ARB; 1358457e427e32324884acb064b756e327dc131ff135Brian Paul p.program->Base.String = NULL; 1359457e427e32324884acb064b756e327dc131ff135Brian Paul p.program->Base.NumTexIndirections = 1; /* is this right? */ 136021f99792a916a62fcfae7c208f50f192d4ce5926Brian p.program->Base.NumTexInstructions = 0; 136121f99792a916a62fcfae7c208f50f192d4ce5926Brian p.program->Base.NumAluInstructions = 0; 1362457e427e32324884acb064b756e327dc131ff135Brian Paul p.program->Base.NumInstructions = 0; 1363457e427e32324884acb064b756e327dc131ff135Brian Paul p.program->Base.NumTemporaries = 0; 1364457e427e32324884acb064b756e327dc131ff135Brian Paul p.program->Base.NumParameters = 0; 1365457e427e32324884acb064b756e327dc131ff135Brian Paul p.program->Base.NumAttributes = 0; 1366457e427e32324884acb064b756e327dc131ff135Brian Paul p.program->Base.NumAddressRegs = 0; 1367de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul p.program->Base.Parameters = _mesa_new_parameter_list(); 1368457e427e32324884acb064b756e327dc131ff135Brian Paul p.program->Base.InputsRead = 0x0; 13698d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul p.program->Base.OutputsWritten = 1 << FRAG_RESULT_COLOR; 137015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1371114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { 13722dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell p.src_texture[unit] = undef; 1373114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger p.texcoord_tex[unit] = undef; 1374114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger } 13752dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 137647b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell p.src_previous = undef; 13775ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell p.half = undef; 13785ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell p.zero = undef; 13795ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell p.one = undef; 13805ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell 138115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell p.last_tex_stage = 0; 138293fef22d05d0fb6f011d48d2fde533555c1695a2Brian release_temps(ctx, &p); 138315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1384ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->enabled_units) { 1385457e427e32324884acb064b756e327dc131ff135Brian Paul GLboolean needbumpstage = GL_FALSE; 1386457e427e32324884acb064b756e327dc131ff135Brian Paul 1387114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger /* Zeroth pass - bump map textures first */ 1388457e427e32324884acb064b756e327dc131ff135Brian Paul for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) 1389457e427e32324884acb064b756e327dc131ff135Brian Paul if (key->unit[unit].enabled && 1390457e427e32324884acb064b756e327dc131ff135Brian Paul key->unit[unit].ModeRGB == MODE_BUMP_ENVMAP_ATI) { 1391114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger needbumpstage = GL_TRUE; 1392114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger load_texunit_bumpmap( &p, unit ); 1393114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger } 1394114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger if (needbumpstage) 1395114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger p.program->Base.NumTexIndirections++; 1396114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 13972dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell /* First pass - to support texture_env_crossbar, first identify 13982dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell * all referenced texture sources and emit texld instructions 13992dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell * for each: 14002dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell */ 1401457e427e32324884acb064b756e327dc131ff135Brian Paul for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) 1402ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->unit[unit].enabled) { 1403b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola load_texunit_sources( &p, unit ); 1404b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola p.last_tex_stage = unit; 140515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 140615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 14072dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell /* Second pass - emit combine instructions to build final color: 14082dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell */ 1409457e427e32324884acb064b756e327dc131ff135Brian Paul for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) 141084d6bed4d6844110af23a995e2fad0280a92d46cBrian Paul if (key->unit[unit].enabled) { 141115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell p.src_previous = emit_texenv( &p, unit ); 14125620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul reserve_temp(&p, p.src_previous); /* don't re-use this temp reg */ 141393fef22d05d0fb6f011d48d2fde533555c1695a2Brian release_temps(ctx, &p); /* release all temps */ 141415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 141515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 141615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1417ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell cf = get_source( &p, SRC_PREVIOUS, 0 ); 14188d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul out = make_ureg( PROGRAM_OUTPUT, FRAG_RESULT_COLOR ); 141915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1420ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->separate_specular) { 142115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Emit specular add. 142215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 142347b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell struct ureg s = register_input(&p, FRAG_ATTRIB_COL1); 14247e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( &p, OPCODE_ADD, out, WRITEMASK_XYZ, 0, cf, s, undef ); 14257e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( &p, OPCODE_MOV, out, WRITEMASK_W, 0, cf, undef, undef ); 142615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 1427aa2069586d434dd0487b0daa2b583efe801a0d51Brian Paul else if (_mesa_memcmp(&cf, &out, sizeof(cf)) != 0) { 142815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Will wind up in here if no texture enabled or a couple of 142915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * other scenarios (GL_REPLACE for instance). 143015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 14317e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( &p, OPCODE_MOV, out, WRITEMASK_XYZW, 0, cf, undef, undef ); 143215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 143315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 143447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell /* Finish up: 143547b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell */ 14367e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( &p, OPCODE_END, undef, WRITEMASK_XYZW, 0, undef, undef, undef); 143747b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell 1438ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->fog_enabled) { 1439ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell /* Pull fog mode from GLcontext, the value in the state key is 1440ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell * a reduced value and not what is expected in FogOption 1441ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell */ 1442276330b2412910777f7016f427909085f02acbb8Keith Whitwell p.program->FogOption = ctx->Fog.Mode; 1443457e427e32324884acb064b756e327dc131ff135Brian Paul p.program->Base.InputsRead |= FRAG_BIT_FOGC; 1444457e427e32324884acb064b756e327dc131ff135Brian Paul } 1445457e427e32324884acb064b756e327dc131ff135Brian Paul else { 1446276330b2412910777f7016f427909085f02acbb8Keith Whitwell p.program->FogOption = GL_NONE; 1447457e427e32324884acb064b756e327dc131ff135Brian Paul } 144847b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell 144921f99792a916a62fcfae7c208f50f192d4ce5926Brian if (p.program->Base.NumTexIndirections > ctx->Const.FragmentProgram.MaxTexIndirections) 145015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell program_error(&p, "Exceeded max nr indirect texture lookups"); 145115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 145221f99792a916a62fcfae7c208f50f192d4ce5926Brian if (p.program->Base.NumTexInstructions > ctx->Const.FragmentProgram.MaxTexInstructions) 145315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell program_error(&p, "Exceeded max TEX instructions"); 145415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 145521f99792a916a62fcfae7c208f50f192d4ce5926Brian if (p.program->Base.NumAluInstructions > ctx->Const.FragmentProgram.MaxAluInstructions) 145615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell program_error(&p, "Exceeded max ALU instructions"); 145715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 14585d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul ASSERT(p.program->Base.NumInstructions <= MAX_INSTRUCTIONS); 14598b88f62fbd62153500fc3483003f438561366a00Keith Whitwell 1460e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul /* Allocate final instruction array */ 1461c81cce78313a62e0d36a5c80bd9d35b770d0814aBrian p.program->Base.Instructions 1462c81cce78313a62e0d36a5c80bd9d35b770d0814aBrian = _mesa_alloc_instructions(p.program->Base.NumInstructions); 1463c81cce78313a62e0d36a5c80bd9d35b770d0814aBrian if (!p.program->Base.Instructions) { 1464e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, 1465e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul "generating tex env program"); 1466e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul return; 1467e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul } 1468c81cce78313a62e0d36a5c80bd9d35b770d0814aBrian _mesa_copy_instructions(p.program->Base.Instructions, instBuffer, 1469c81cce78313a62e0d36a5c80bd9d35b770d0814aBrian p.program->Base.NumInstructions); 1470c81cce78313a62e0d36a5c80bd9d35b770d0814aBrian 1471c81cce78313a62e0d36a5c80bd9d35b770d0814aBrian if (p.program->FogOption) { 1472c81cce78313a62e0d36a5c80bd9d35b770d0814aBrian _mesa_append_fog_code(ctx, p.program); 1473c81cce78313a62e0d36a5c80bd9d35b770d0814aBrian p.program->FogOption = GL_NONE; 1474c81cce78313a62e0d36a5c80bd9d35b770d0814aBrian } 1475c81cce78313a62e0d36a5c80bd9d35b770d0814aBrian 1476e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul 1477dbeea25bb834479a29712100888c862348112018Keith Whitwell /* Notify driver the fragment program has (actually) changed. 14788b88f62fbd62153500fc3483003f438561366a00Keith Whitwell */ 1479e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul if (ctx->Driver.ProgramStringNotify) { 1480e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul ctx->Driver.ProgramStringNotify( ctx, GL_FRAGMENT_PROGRAM_ARB, 1481e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul &p.program->Base ); 1482e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul } 1483e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul 1484e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul if (DISASSEM) { 1485e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul _mesa_print_program(&p.program->Base); 1486e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul _mesa_printf("\n"); 1487dbeea25bb834479a29712100888c862348112018Keith Whitwell } 148815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 148915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 14905d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul 149132ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell/** 149232ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell * Return a fragment program which implements the current 149332ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell * fixed-function texture, fog and color-sum operations. 149432ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell */ 149532ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwellstruct gl_fragment_program * 149632ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell_mesa_get_fixed_func_fragment_program(GLcontext *ctx) 1497ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 149832ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell struct gl_fragment_program *prog; 149932ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell struct state_key key; 150032ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell 1501a46e32787d98192d35bf2834011cfa5537e0e703Chris Wilson printf("SIZE OF KEY %d\n", sizeof(key)); 150232ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell make_state_key(ctx, &key); 150332ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell 150432ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell prog = (struct gl_fragment_program *) 150532ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell _mesa_search_program_cache(ctx->FragmentProgram.Cache, 150632ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell &key, sizeof(key)); 1507ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 150832ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell if (!prog) { 150932ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell prog = (struct gl_fragment_program *) 151032ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0); 15115ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell 151232ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell create_new_program(ctx, &key, prog); 15135ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell 151432ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell _mesa_program_cache_insert(ctx, ctx->FragmentProgram.Cache, 151532ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell &key, sizeof(key), &prog->Base); 15168065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell } 15178065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell 151832ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell return prog; 15198065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell} 1520