ff_fragment_shader.cpp revision cdacca4868bbfe2e39f72d524556e7b2c7200ba5
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 29cdacca4868bbfe2e39f72d524556e7b2c7200ba5Eric Anholtextern "C" { 3015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell#include "glheader.h" 3125e5a6f279cec0863dcc341805aa7ca71189b626Brian Paul#include "imports.h" 320117da40cd7edd3d165bb28569c289b37eca12b9Vinson Lee#include "mtypes.h" 33ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/program.h" 34ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/prog_parameter.h" 35ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/prog_cache.h" 36ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/prog_instruction.h" 37ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/prog_print.h" 38ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/prog_statevars.h" 39ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/programopt.h" 4015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell#include "texenvprogram.h" 41cdacca4868bbfe2e39f72d524556e7b2c7200ba5Eric Anholt} 425b5c9315275752add1215dba0f86d5f5068d856bBrian Paul 43e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul/* 44e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul * Note on texture units: 45e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul * 46e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul * The number of texture units supported by fixed-function fragment 47e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul * processing is MAX_TEXTURE_COORD_UNITS, not MAX_TEXTURE_IMAGE_UNITS. 48e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul * That's because there's a one-to-one correspondence between texture 49e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul * coordinates and samplers in fixed-function processing. 50e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul * 51e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul * Since fixed-function vertex processing is limited to MAX_TEXTURE_COORD_UNITS 52e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul * sets of texcoords, so is fixed-function fragment processing. 53e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul * 54e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul * We can safely use ctx->Const.MaxTextureUnits for loop bounds. 55e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul */ 56e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul 57e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul 585b5c9315275752add1215dba0f86d5f5068d856bBrian Paulstruct texenvprog_cache_item 595b5c9315275752add1215dba0f86d5f5068d856bBrian Paul{ 605b5c9315275752add1215dba0f86d5f5068d856bBrian Paul GLuint hash; 615b5c9315275752add1215dba0f86d5f5068d856bBrian Paul void *key; 625b5c9315275752add1215dba0f86d5f5068d856bBrian Paul struct gl_fragment_program *data; 635b5c9315275752add1215dba0f86d5f5068d856bBrian Paul struct texenvprog_cache_item *next; 645b5c9315275752add1215dba0f86d5f5068d856bBrian Paul}; 655b5c9315275752add1215dba0f86d5f5068d856bBrian Paul 669cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholtstatic GLboolean 67f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergtexenv_doing_secondary_color(struct gl_context *ctx) 689cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt{ 699cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt if (ctx->Light.Enabled && 709cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) 719cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt return GL_TRUE; 729cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt 739cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt if (ctx->Fog.ColorSumEnabled) 749cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt return GL_TRUE; 759cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt 769cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt return GL_FALSE; 779cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt} 785b5c9315275752add1215dba0f86d5f5068d856bBrian Paul 79e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul/** 80b5e1a93036b22bd30738abccbb8a2645a515667fBrian Paul * Up to nine instructions per tex unit, plus fog, specular color. 81e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul */ 820815ebccfc0a12d8f3e831928f1c4210b7f75ad8Brian Paul#define MAX_INSTRUCTIONS ((MAX_TEXTURE_COORD_UNITS * 9) + 12) 8315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 84269e3895d9837ac7303b91948f003ca5c12c0fe4Keith Whitwell#define DISASSEM (MESA_VERBOSE & VERBOSE_DISASSEM) 8515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 86ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstruct mode_opt { 8783e4470d9a3367883b3fe699629f1d8648459a89Brian Paul#ifdef __GNUC__ 88d98b9f4edbbee1654b66c8df7b1deeb401b3dc5fGary Wong __extension__ GLubyte Source:4; /**< SRC_x */ 89d98b9f4edbbee1654b66c8df7b1deeb401b3dc5fGary Wong __extension__ GLubyte Operand:3; /**< OPR_x */ 9083e4470d9a3367883b3fe699629f1d8648459a89Brian Paul#else 915e809216a8d2e7ad093a1d25f3f6495f29e57572Brian Paul GLubyte Source; /**< SRC_x */ 925e809216a8d2e7ad093a1d25f3f6495f29e57572Brian Paul GLubyte Operand; /**< OPR_x */ 9383e4470d9a3367883b3fe699629f1d8648459a89Brian Paul#endif 94ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell}; 95ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 96ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstruct state_key { 976280e335706f95ed0ebb089d8f72aeede9b5a1adKeith Whitwell GLuint nr_enabled_units:8; 986280e335706f95ed0ebb089d8f72aeede9b5a1adKeith Whitwell GLuint enabled_units:8; 995d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint separate_specular:1; 1005d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint fog_enabled:1; 1019ed0315271c38f5fe9cdd65020a54cbb7f61ed2bBrian Paul GLuint fog_mode:2; /**< FOG_x */ 1026280e335706f95ed0ebb089d8f72aeede9b5a1adKeith Whitwell GLuint inputs_available:12; 103b6b9b17d27c570cc99ae339e595cf2f63ca5e8d7Brian Paul GLuint num_draw_buffers:4; 104ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 1057a7d5879e28607c151132a8b6a07cf4be36b5b3eBrian Paul /* NOTE: This array of structs must be last! (see "keySize" below) */ 106ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct { 1075d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint enabled:1; 1089ed0315271c38f5fe9cdd65020a54cbb7f61ed2bBrian Paul GLuint source_index:3; /**< TEXTURE_x_INDEX */ 10983ad2a756ea8dd1b0ca9746e355ce3de0f29356eNicolai Haehnle GLuint shadow:1; 1105d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint ScaleShiftRGB:2; 1115d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint ScaleShiftA:2; 112ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 1139ed0315271c38f5fe9cdd65020a54cbb7f61ed2bBrian Paul GLuint NumArgsRGB:3; /**< up to MAX_COMBINER_TERMS */ 114f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul GLuint ModeRGB:5; /**< MODE_x */ 115ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 1169ed0315271c38f5fe9cdd65020a54cbb7f61ed2bBrian Paul GLuint NumArgsA:3; /**< up to MAX_COMBINER_TERMS */ 117f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul GLuint ModeA:5; /**< MODE_x */ 118a46e32787d98192d35bf2834011cfa5537e0e703Chris Wilson 1194a9f1eed2ba02f2ae2bf92d16f89d10f09b2a21eBrian Paul GLuint texture_cyl_wrap:1; /**< For gallium test/debug only */ 1204a9f1eed2ba02f2ae2bf92d16f89d10f09b2a21eBrian Paul 121a46e32787d98192d35bf2834011cfa5537e0e703Chris Wilson struct mode_opt OptRGB[MAX_COMBINER_TERMS]; 122bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul struct mode_opt OptA[MAX_COMBINER_TERMS]; 123d55a28e3dc712342e4a2f25aa9b661add7461e82Brian Paul } unit[MAX_TEXTURE_UNITS]; 124ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell}; 125ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 126ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define FOG_LINEAR 0 127ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define FOG_EXP 1 128ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define FOG_EXP2 2 129ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define FOG_UNKNOWN 3 130ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 131ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstatic GLuint translate_fog_mode( GLenum mode ) 132ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 133ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch (mode) { 134ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_LINEAR: return FOG_LINEAR; 135ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_EXP: return FOG_EXP; 136ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_EXP2: return FOG_EXP2; 137ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell default: return FOG_UNKNOWN; 138ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 139ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 140ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 141ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_SRC_COLOR 0 142ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_ONE_MINUS_SRC_COLOR 1 143ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_SRC_ALPHA 2 144ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_ONE_MINUS_SRC_ALPHA 3 145ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_ZERO 4 146ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_ONE 5 147ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_UNKNOWN 7 148ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 149ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstatic GLuint translate_operand( GLenum operand ) 150ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 151ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch (operand) { 152ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_SRC_COLOR: return OPR_SRC_COLOR; 153ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_ONE_MINUS_SRC_COLOR: return OPR_ONE_MINUS_SRC_COLOR; 154ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_SRC_ALPHA: return OPR_SRC_ALPHA; 155ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_ONE_MINUS_SRC_ALPHA: return OPR_ONE_MINUS_SRC_ALPHA; 156ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_ZERO: return OPR_ZERO; 157ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_ONE: return OPR_ONE; 1586947f85cb5fbc433ba7763530285e470745b009bBrian Paul default: 1596947f85cb5fbc433ba7763530285e470745b009bBrian Paul assert(0); 1606947f85cb5fbc433ba7763530285e470745b009bBrian Paul return OPR_UNKNOWN; 161ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 162ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 163ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 164ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE 0 165ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE0 1 166ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE1 2 167ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE2 3 168ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE3 4 169ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE4 5 170ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE5 6 171ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE6 7 172ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE7 8 173ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_CONSTANT 9 174ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_PRIMARY_COLOR 10 175ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_PREVIOUS 11 1766947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define SRC_ZERO 12 177ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_UNKNOWN 15 178ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 179ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstatic GLuint translate_source( GLenum src ) 180ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 181ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch (src) { 182ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE: return SRC_TEXTURE; 183ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE0: 184ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE1: 185ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE2: 186ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE3: 187ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE4: 188ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE5: 189ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE6: 190ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE7: return SRC_TEXTURE0 + (src - GL_TEXTURE0); 191ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_CONSTANT: return SRC_CONSTANT; 192ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_PRIMARY_COLOR: return SRC_PRIMARY_COLOR; 193ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_PREVIOUS: return SRC_PREVIOUS; 1946947f85cb5fbc433ba7763530285e470745b009bBrian Paul case GL_ZERO: 1956947f85cb5fbc433ba7763530285e470745b009bBrian Paul return SRC_ZERO; 1966947f85cb5fbc433ba7763530285e470745b009bBrian Paul default: 1976947f85cb5fbc433ba7763530285e470745b009bBrian Paul assert(0); 1986947f85cb5fbc433ba7763530285e470745b009bBrian Paul return SRC_UNKNOWN; 199ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 200ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 201ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 2026947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_REPLACE 0 /* r = a0 */ 2036947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_MODULATE 1 /* r = a0 * a1 */ 2046947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_ADD 2 /* r = a0 + a1 */ 2056947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_ADD_SIGNED 3 /* r = a0 + a1 - 0.5 */ 2066947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_INTERPOLATE 4 /* r = a0 * a2 + a1 * (1 - a2) */ 2076947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_SUBTRACT 5 /* r = a0 - a1 */ 2086947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_DOT3_RGB 6 /* r = a0 . a1 */ 2096947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_DOT3_RGB_EXT 7 /* r = a0 . a1 */ 2106947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_DOT3_RGBA 8 /* r = a0 . a1 */ 2116947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_DOT3_RGBA_EXT 9 /* r = a0 . a1 */ 2126947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_MODULATE_ADD_ATI 10 /* r = a0 * a2 + a1 */ 2136947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_MODULATE_SIGNED_ADD_ATI 11 /* r = a0 * a2 + a1 - 0.5 */ 2146947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_MODULATE_SUBTRACT_ATI 12 /* r = a0 * a2 - a1 */ 2156947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_ADD_PRODUCTS 13 /* r = a0 * a1 + a2 * a3 */ 2166947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_ADD_PRODUCTS_SIGNED 14 /* r = a0 * a1 + a2 * a3 - 0.5 */ 217114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger#define MODE_BUMP_ENVMAP_ATI 15 /* special */ 218114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger#define MODE_UNKNOWN 16 2196947f85cb5fbc433ba7763530285e470745b009bBrian Paul 2206947f85cb5fbc433ba7763530285e470745b009bBrian Paul/** 2216947f85cb5fbc433ba7763530285e470745b009bBrian Paul * Translate GL combiner state into a MODE_x value 2226947f85cb5fbc433ba7763530285e470745b009bBrian Paul */ 2236947f85cb5fbc433ba7763530285e470745b009bBrian Paulstatic GLuint translate_mode( GLenum envMode, GLenum mode ) 224ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 225ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch (mode) { 226ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_REPLACE: return MODE_REPLACE; 227ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_MODULATE: return MODE_MODULATE; 2286947f85cb5fbc433ba7763530285e470745b009bBrian Paul case GL_ADD: 2296947f85cb5fbc433ba7763530285e470745b009bBrian Paul if (envMode == GL_COMBINE4_NV) 2306947f85cb5fbc433ba7763530285e470745b009bBrian Paul return MODE_ADD_PRODUCTS; 2316947f85cb5fbc433ba7763530285e470745b009bBrian Paul else 2326947f85cb5fbc433ba7763530285e470745b009bBrian Paul return MODE_ADD; 2336947f85cb5fbc433ba7763530285e470745b009bBrian Paul case GL_ADD_SIGNED: 2346947f85cb5fbc433ba7763530285e470745b009bBrian Paul if (envMode == GL_COMBINE4_NV) 2356947f85cb5fbc433ba7763530285e470745b009bBrian Paul return MODE_ADD_PRODUCTS_SIGNED; 2366947f85cb5fbc433ba7763530285e470745b009bBrian Paul else 2376947f85cb5fbc433ba7763530285e470745b009bBrian Paul return MODE_ADD_SIGNED; 238ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_INTERPOLATE: return MODE_INTERPOLATE; 239ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_SUBTRACT: return MODE_SUBTRACT; 240ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_DOT3_RGB: return MODE_DOT3_RGB; 241ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_DOT3_RGB_EXT: return MODE_DOT3_RGB_EXT; 242ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_DOT3_RGBA: return MODE_DOT3_RGBA; 243ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_DOT3_RGBA_EXT: return MODE_DOT3_RGBA_EXT; 244ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_MODULATE_ADD_ATI: return MODE_MODULATE_ADD_ATI; 245ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_MODULATE_SIGNED_ADD_ATI: return MODE_MODULATE_SIGNED_ADD_ATI; 246ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_MODULATE_SUBTRACT_ATI: return MODE_MODULATE_SUBTRACT_ATI; 247114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger case GL_BUMP_ENVMAP_ATI: return MODE_BUMP_ENVMAP_ATI; 2486947f85cb5fbc433ba7763530285e470745b009bBrian Paul default: 2496947f85cb5fbc433ba7763530285e470745b009bBrian Paul assert(0); 2506947f85cb5fbc433ba7763530285e470745b009bBrian Paul return MODE_UNKNOWN; 251ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 252ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 253ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 254f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul 255f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul/** 256e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul * Do we need to clamp the results of the given texture env/combine mode? 257e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul * If the inputs to the mode are in [0,1] we don't always have to clamp 258e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul * the results. 259e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul */ 260e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paulstatic GLboolean 261e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paulneed_saturate( GLuint mode ) 262e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul{ 263e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul switch (mode) { 264e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul case MODE_REPLACE: 265e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul case MODE_MODULATE: 266e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul case MODE_INTERPOLATE: 267e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul return GL_FALSE; 268e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul case MODE_ADD: 269e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul case MODE_ADD_SIGNED: 270e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul case MODE_SUBTRACT: 271e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul case MODE_DOT3_RGB: 272e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul case MODE_DOT3_RGB_EXT: 273e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul case MODE_DOT3_RGBA: 274e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul case MODE_DOT3_RGBA_EXT: 275e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul case MODE_MODULATE_ADD_ATI: 276e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul case MODE_MODULATE_SIGNED_ADD_ATI: 277e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul case MODE_MODULATE_SUBTRACT_ATI: 278e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul case MODE_ADD_PRODUCTS: 279e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul case MODE_ADD_PRODUCTS_SIGNED: 280e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul case MODE_BUMP_ENVMAP_ATI: 281e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul return GL_TRUE; 282e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul default: 283e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul assert(0); 284a491e25b1fa8683f538ed0d67a6389f2cdf7e4bcBrian Paul return GL_FALSE; 285e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul } 286e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul} 287e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul 288e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul 289e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul 290e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul/** 291f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul * Translate TEXTURE_x_BIT to TEXTURE_x_INDEX. 292f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul */ 293e00ac11d4dd05c56584622dc2707bbdcfe4b2707Brian Paulstatic GLuint translate_tex_src_bit( GLbitfield bit ) 294ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 295b5ec0a68589c5d8f0d4be2556ea6d6b01fd4e37dBrian Paul ASSERT(bit); 296b5ec0a68589c5d8f0d4be2556ea6d6b01fd4e37dBrian Paul return _mesa_ffs(bit) - 1; 297ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 298ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 299f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul 3001680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell#define VERT_BIT_TEX_ANY (0xff << VERT_ATTRIB_TEX0) 3011680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell#define VERT_RESULT_TEX_ANY (0xff << VERT_RESULT_TEX0) 3021680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 303239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul/** 304239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul * Identify all possible varying inputs. The fragment program will 3051680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * never reference non-varying inputs, but will track them via state 3061680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * constants instead. 3071680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * 3081680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * This function figures out all the inputs that the fragment program 3091680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * has access to. The bitmask is later reduced to just those which 3101680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * are actually referenced. 3111680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell */ 312f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic GLbitfield get_fp_input_mask( struct gl_context *ctx ) 3131680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell{ 314e5f63c403b767f9974e8eb5d412c012b8a69287fEric Anholt /* _NEW_PROGRAM */ 31584eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick const GLboolean vertexShader = 31684eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick (ctx->Shader.CurrentVertexProgram && 31784eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick ctx->Shader.CurrentVertexProgram->LinkStatus && 31884eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick ctx->Shader.CurrentVertexProgram->VertexProgram); 319f0b0794b3885a2fdfb168ec4521c7b5e942d3228Brian Paul const GLboolean vertexProgram = ctx->VertexProgram._Enabled; 320239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul GLbitfield fp_inputs = 0x0; 3211680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 3226d4d51d647c27288aa625560bc080231099c0b01Brian Paul if (ctx->VertexProgram._Overriden) { 3236d4d51d647c27288aa625560bc080231099c0b01Brian Paul /* Somebody's messing with the vertex program and we don't have 3246d4d51d647c27288aa625560bc080231099c0b01Brian Paul * a clue what's happening. Assume that it could be producing 3256d4d51d647c27288aa625560bc080231099c0b01Brian Paul * all possible outputs. 3266d4d51d647c27288aa625560bc080231099c0b01Brian Paul */ 3276d4d51d647c27288aa625560bc080231099c0b01Brian Paul fp_inputs = ~0; 3286d4d51d647c27288aa625560bc080231099c0b01Brian Paul } 3296d4d51d647c27288aa625560bc080231099c0b01Brian Paul else if (ctx->RenderMode == GL_FEEDBACK) { 330e5f63c403b767f9974e8eb5d412c012b8a69287fEric Anholt /* _NEW_RENDERMODE */ 3316d4d51d647c27288aa625560bc080231099c0b01Brian Paul fp_inputs = (FRAG_BIT_COL0 | FRAG_BIT_TEX0); 3326d4d51d647c27288aa625560bc080231099c0b01Brian Paul } 333f0b0794b3885a2fdfb168ec4521c7b5e942d3228Brian Paul else if (!(vertexProgram || vertexShader) || 334d7296a1a8e846bc4d41ded1c2406b6f5c658188aBrian Paul !ctx->VertexProgram._Current) { 335f0b0794b3885a2fdfb168ec4521c7b5e942d3228Brian Paul /* Fixed function vertex logic */ 336e5f63c403b767f9974e8eb5d412c012b8a69287fEric Anholt /* _NEW_ARRAY */ 337239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul GLbitfield varying_inputs = ctx->varying_vp_inputs; 3381680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 33997e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell /* These get generated in the setup routine regardless of the 34097e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell * vertex program: 34197e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell */ 342e5f63c403b767f9974e8eb5d412c012b8a69287fEric Anholt /* _NEW_POINT */ 34397e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell if (ctx->Point.PointSprite) 34497e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell varying_inputs |= FRAG_BITS_TEX_ANY; 34597e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell 3461680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell /* First look at what values may be computed by the generated 3471680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * vertex program: 3481680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell */ 349e5f63c403b767f9974e8eb5d412c012b8a69287fEric Anholt /* _NEW_LIGHT */ 3501680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell if (ctx->Light.Enabled) { 3511680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell fp_inputs |= FRAG_BIT_COL0; 3521680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 3539cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt if (texenv_doing_secondary_color(ctx)) 3541680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell fp_inputs |= FRAG_BIT_COL1; 3551680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell } 3561680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 357e5f63c403b767f9974e8eb5d412c012b8a69287fEric Anholt /* _NEW_TEXTURE */ 3581680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell fp_inputs |= (ctx->Texture._TexGenEnabled | 3591680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell ctx->Texture._TexMatEnabled) << FRAG_ATTRIB_TEX0; 3601680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 3611680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell /* Then look at what might be varying as a result of enabled 3621680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * arrays, etc: 3631680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell */ 3646807d96f8efeecd9d71e1e1bff856e7e04f5f364Brian Paul if (varying_inputs & VERT_BIT_COLOR0) 3656807d96f8efeecd9d71e1e1bff856e7e04f5f364Brian Paul fp_inputs |= FRAG_BIT_COL0; 3666807d96f8efeecd9d71e1e1bff856e7e04f5f364Brian Paul if (varying_inputs & VERT_BIT_COLOR1) 3676807d96f8efeecd9d71e1e1bff856e7e04f5f364Brian Paul fp_inputs |= FRAG_BIT_COL1; 3681680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 3691680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell fp_inputs |= (((varying_inputs & VERT_BIT_TEX_ANY) >> VERT_ATTRIB_TEX0) 3701680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell << FRAG_ATTRIB_TEX0); 3711680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 3721680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell } 3731680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell else { 3741680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell /* calculate from vp->outputs */ 3752389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul struct gl_vertex_program *vprog; 3765606dfb572bf4b89b4882265924705bacc8c182bIan Romanick GLbitfield64 vp_outputs; 3772389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul 3782389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul /* Choose GLSL vertex shader over ARB vertex program. Need this 3792389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul * since vertex shader state validation comes after fragment state 3802389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul * validation (see additional comments in state.c). 3812389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul */ 3822389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul if (vertexShader) 38384eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick vprog = ctx->Shader.CurrentVertexProgram->VertexProgram; 3842389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul else 385a9ba1bfeb3a2852c6eda718e73c46c972a286648Eric Anholt vprog = ctx->VertexProgram.Current; 3862389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul 3872389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul vp_outputs = vprog->Base.OutputsWritten; 3881680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 38997e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell /* These get generated in the setup routine regardless of the 39097e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell * vertex program: 39197e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell */ 392e5f63c403b767f9974e8eb5d412c012b8a69287fEric Anholt /* _NEW_POINT */ 39397e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell if (ctx->Point.PointSprite) 39497e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell vp_outputs |= FRAG_BITS_TEX_ANY; 39597e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell 3966807d96f8efeecd9d71e1e1bff856e7e04f5f364Brian Paul if (vp_outputs & (1 << VERT_RESULT_COL0)) 3976807d96f8efeecd9d71e1e1bff856e7e04f5f364Brian Paul fp_inputs |= FRAG_BIT_COL0; 3986807d96f8efeecd9d71e1e1bff856e7e04f5f364Brian Paul if (vp_outputs & (1 << VERT_RESULT_COL1)) 3996807d96f8efeecd9d71e1e1bff856e7e04f5f364Brian Paul fp_inputs |= FRAG_BIT_COL1; 4001680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 4010370d6b359016790c6b879c2a4b6661adac20deaKeith Whitwell fp_inputs |= (((vp_outputs & VERT_RESULT_TEX_ANY) >> VERT_RESULT_TEX0) 4020370d6b359016790c6b879c2a4b6661adac20deaKeith Whitwell << FRAG_ATTRIB_TEX0); 4031680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell } 4041680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 4051680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell return fp_inputs; 4061680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell} 4071680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 4081680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 40922db53577603afef8fdf62c324ff5977de76b9d8Brian Paul/** 41022db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * Examine current texture environment state and generate a unique 41122db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * key to identify it. 41222db53577603afef8fdf62c324ff5977de76b9d8Brian Paul */ 413f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic GLuint make_state_key( struct gl_context *ctx, struct state_key *key ) 414ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 415ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint i, j; 416239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul GLbitfield inputs_referenced = FRAG_BIT_COL0; 417f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul const GLbitfield inputs_available = get_fp_input_mask( ctx ); 4187a7d5879e28607c151132a8b6a07cf4be36b5b3eBrian Paul GLuint keySize; 4191680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 4208065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell memset(key, 0, sizeof(*key)); 4218065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell 422e5f63c403b767f9974e8eb5d412c012b8a69287fEric Anholt /* _NEW_TEXTURE */ 423e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { 424d9736db6676948e06712d4bcba46b7040452f870Brian Paul const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i]; 425f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul const struct gl_texture_object *texObj = texUnit->_Current; 426f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul const struct gl_tex_env_combine_state *comb = texUnit->_CurrentCombine; 427b6bb5e09e0ad1f61f96c65bbc870bd493df12f1aXiang, Haihao GLenum format; 428bf4a0fafc86bba8dc868cf30244a237e33645164Roland Scheidegger 429bf4a0fafc86bba8dc868cf30244a237e33645164Roland Scheidegger if (!texUnit->_ReallyEnabled || !texUnit->Enabled) 430ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell continue; 431ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 432f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul format = texObj->Image[0][texObj->BaseLevel]->_BaseFormat; 433b6bb5e09e0ad1f61f96c65bbc870bd493df12f1aXiang, Haihao 434ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].enabled = 1; 435ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->enabled_units |= (1<<i); 4367a7d5879e28607c151132a8b6a07cf4be36b5b3eBrian Paul key->nr_enabled_units = i + 1; 4371680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell inputs_referenced |= FRAG_BIT_TEX(i); 438ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 439f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul key->unit[i].source_index = 440f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul translate_tex_src_bit(texUnit->_ReallyEnabled); 441f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul 442f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul key->unit[i].shadow = ((texObj->CompareMode == GL_COMPARE_R_TO_TEXTURE) && 443b6bb5e09e0ad1f61f96c65bbc870bd493df12f1aXiang, Haihao ((format == GL_DEPTH_COMPONENT) || 444b6bb5e09e0ad1f61f96c65bbc870bd493df12f1aXiang, Haihao (format == GL_DEPTH_STENCIL_EXT))); 445ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 446f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul key->unit[i].NumArgsRGB = comb->_NumArgsRGB; 447f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul key->unit[i].NumArgsA = comb->_NumArgsA; 448ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 449ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].ModeRGB = 450f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul translate_mode(texUnit->EnvMode, comb->ModeRGB); 451ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].ModeA = 452f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul translate_mode(texUnit->EnvMode, comb->ModeA); 453114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 454f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul key->unit[i].ScaleShiftRGB = comb->ScaleShiftRGB; 455f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul key->unit[i].ScaleShiftA = comb->ScaleShiftA; 456ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 457bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul for (j = 0; j < MAX_COMBINER_TERMS; j++) { 458f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul key->unit[i].OptRGB[j].Operand = translate_operand(comb->OperandRGB[j]); 459f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul key->unit[i].OptA[j].Operand = translate_operand(comb->OperandA[j]); 460f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul key->unit[i].OptRGB[j].Source = translate_source(comb->SourceRGB[j]); 461f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul key->unit[i].OptA[j].Source = translate_source(comb->SourceA[j]); 462ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 463114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 464114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger if (key->unit[i].ModeRGB == MODE_BUMP_ENVMAP_ATI) { 465114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger /* requires some special translation */ 466114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger key->unit[i].NumArgsRGB = 2; 467114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger key->unit[i].ScaleShiftRGB = 0; 468114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger key->unit[i].OptRGB[0].Operand = OPR_SRC_COLOR; 469114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger key->unit[i].OptRGB[0].Source = SRC_TEXTURE; 470114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger key->unit[i].OptRGB[1].Operand = OPR_SRC_COLOR; 471114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger key->unit[i].OptRGB[1].Source = texUnit->BumpTarget - GL_TEXTURE0 + SRC_TEXTURE0; 472114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger } 4734a9f1eed2ba02f2ae2bf92d16f89d10f09b2a21eBrian Paul 4744a9f1eed2ba02f2ae2bf92d16f89d10f09b2a21eBrian Paul /* this is a back-door for enabling cylindrical texture wrap mode */ 4754a9f1eed2ba02f2ae2bf92d16f89d10f09b2a21eBrian Paul if (texObj->Priority == 0.125) 4764a9f1eed2ba02f2ae2bf92d16f89d10f09b2a21eBrian Paul key->unit[i].texture_cyl_wrap = 1; 477ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 478114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 4799cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt /* _NEW_LIGHT | _NEW_FOG */ 4809cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt if (texenv_doing_secondary_color(ctx)) { 481ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->separate_specular = 1; 4821680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell inputs_referenced |= FRAG_BIT_COL1; 4831680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell } 484ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 485e5f63c403b767f9974e8eb5d412c012b8a69287fEric Anholt /* _NEW_FOG */ 486ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (ctx->Fog.Enabled) { 487ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->fog_enabled = 1; 488ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->fog_mode = translate_fog_mode(ctx->Fog.Mode); 4891680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell inputs_referenced |= FRAG_BIT_FOGC; /* maybe */ 490ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 4911680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 492b6b9b17d27c570cc99ae339e595cf2f63ca5e8d7Brian Paul /* _NEW_BUFFERS */ 493b6b9b17d27c570cc99ae339e595cf2f63ca5e8d7Brian Paul key->num_draw_buffers = ctx->DrawBuffer->_NumColorDrawBuffers; 494b6b9b17d27c570cc99ae339e595cf2f63ca5e8d7Brian Paul 4951680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell key->inputs_available = (inputs_available & inputs_referenced); 4967a7d5879e28607c151132a8b6a07cf4be36b5b3eBrian Paul 4977a7d5879e28607c151132a8b6a07cf4be36b5b3eBrian Paul /* compute size of state key, ignoring unused texture units */ 4987a7d5879e28607c151132a8b6a07cf4be36b5b3eBrian Paul keySize = sizeof(*key) - sizeof(key->unit) 4997a7d5879e28607c151132a8b6a07cf4be36b5b3eBrian Paul + key->nr_enabled_units * sizeof(key->unit[0]); 5007a7d5879e28607c151132a8b6a07cf4be36b5b3eBrian Paul 5017a7d5879e28607c151132a8b6a07cf4be36b5b3eBrian Paul return keySize; 502ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 503ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 5047a7d5879e28607c151132a8b6a07cf4be36b5b3eBrian Paul 505239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul/** 506239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul * Use uregs to represent registers internally, translate to Mesa's 50715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * expected formats on emit. 50815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 50915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * NOTE: These are passed by value extensively in this file rather 51015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * than as usual by pointer reference. If this disturbs you, try 51115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * remembering they are just 32bits in size. 51215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 51315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * GCC is smart enough to deal with these dword-sized structures in 51415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * much the same way as if I had defined them as dwords and was using 51515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * macros to access and set the fields. This is much nicer and easier 51615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * to evolve. 51715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 51815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstruct ureg { 51915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint file:4; 52015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint idx:8; 52115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint negatebase:1; 52215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint swz:12; 5231480bcacfec8f215c5827278a5f984c6bf68ba69Brian Paul GLuint pad:7; 52415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell}; 52515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 52613abf91b42b00c7eb64c373aff3a4c1bb3d8fb7fBrian Paulstatic const struct ureg undef = { 5278d97265711b172da4f387748f0e72da9267492b0Alan Hourihane PROGRAM_UNDEFINED, 528cdacca4868bbfe2e39f72d524556e7b2c7200ba5Eric Anholt 255, 52915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 0, 53015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 0, 53115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 0 53215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell}; 53315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 53415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 535239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul/** State used to build the fragment program: 53615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 53715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstruct texenv_fragment_program { 538122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul struct gl_fragment_program *program; 539ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct state_key *state; 54015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 541239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul GLbitfield alu_temps; /**< Track texture indirections, see spec. */ 542239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul GLbitfield temps_output; /**< Track texture indirections, see spec. */ 543239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul GLbitfield temp_in_use; /**< Tracks temporary regs which are in use. */ 54415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLboolean error; 54515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 546e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul struct ureg src_texture[MAX_TEXTURE_COORD_UNITS]; 547ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell /* Reg containing each texture unit's sampled texture color, 548ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell * else undef. 549ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell */ 55015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 551114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger struct ureg texcoord_tex[MAX_TEXTURE_COORD_UNITS]; 552114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger /* Reg containing texcoord for a texture unit, 553114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger * needed for bump mapping, else undef. 554114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger */ 555114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 556239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul struct ureg src_previous; /**< Reg containing color from previous 55715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * stage. May need to be decl'd. 55815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 55915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 560239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul GLuint last_tex_stage; /**< Number of last enabled texture unit */ 5612dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 5622dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell struct ureg half; 5632dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell struct ureg one; 5642dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell struct ureg zero; 56515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell}; 56615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 56715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 56815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 56915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg make_ureg(GLuint file, GLuint idx) 57015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 57115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg reg; 57215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.file = file; 57315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.idx = idx; 57415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.negatebase = 0; 57515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.swz = SWIZZLE_NOOP; 57615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.pad = 0; 57715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return reg; 57815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 57915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 58015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg swizzle( struct ureg reg, int x, int y, int z, int w ) 58115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 58215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg.swz = MAKE_SWIZZLE4(GET_SWZ(reg.swz, x), 58315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GET_SWZ(reg.swz, y), 58415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GET_SWZ(reg.swz, z), 58515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GET_SWZ(reg.swz, w)); 58615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 58715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return reg; 58815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 58915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 59015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg swizzle1( struct ureg reg, int x ) 59115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 59215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return swizzle(reg, x, x, x, x); 59315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 59415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 5956fe176a64859798db17fbaed6858cccc646aae38Keith Whitwellstatic struct ureg negate( struct ureg reg ) 5966fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell{ 5976fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell reg.negatebase ^= 1; 5986fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell return reg; 5996fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell} 6006fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell 60115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic GLboolean is_undef( struct ureg reg ) 60215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 6038d97265711b172da4f387748f0e72da9267492b0Alan Hourihane return reg.file == PROGRAM_UNDEFINED; 60415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 60515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 606ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 60715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg get_temp( struct texenv_fragment_program *p ) 60815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 60913abf91b42b00c7eb64c373aff3a4c1bb3d8fb7fBrian Paul GLint bit; 610ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 611cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell /* First try and reuse temps which have been used already: 612ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell */ 613b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul bit = _mesa_ffs( ~p->temp_in_use & p->alu_temps ); 614ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 615ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell /* Then any unused temporary: 616ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell */ 617ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell if (!bit) 618b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul bit = _mesa_ffs( ~p->temp_in_use ); 619ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 620ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell if (!bit) { 621bfb5ea307ec48b9b8d0d2eca0c03f6d02273d454Brian Paul _mesa_problem(NULL, "%s: out of temporaries\n", __FILE__); 6221a80fe461e162d5b6e25bd270a54e6662f72e5b3Eric Anholt exit(1); 623ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell } 624ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 62513abf91b42b00c7eb64c373aff3a4c1bb3d8fb7fBrian Paul if ((GLuint) bit > p->program->Base.NumTemporaries) 626b5cbaf945dd5213d5faf7bb7e4d68d0d25a25b55Keith Whitwell p->program->Base.NumTemporaries = bit; 627b5cbaf945dd5213d5faf7bb7e4d68d0d25a25b55Keith Whitwell 62893cd9237d793e38ba4479d1367be7548853f67f4Keith Whitwell p->temp_in_use |= 1<<(bit-1); 629ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell return make_ureg(PROGRAM_TEMPORARY, (bit-1)); 630ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell} 631ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 632ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwellstatic struct ureg get_tex_temp( struct texenv_fragment_program *p ) 633ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell{ 634ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell int bit; 635ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 636d01269a57f4cfdb859352c933bc546296545dd80Brian Paul /* First try to find available temp not previously used (to avoid 637cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell * starting a new texture indirection). According to the spec, the 638cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell * ~p->temps_output isn't necessary, but will keep it there for 639cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell * now: 640ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell */ 641b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul bit = _mesa_ffs( ~p->temp_in_use & ~p->alu_temps & ~p->temps_output ); 642ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 643ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell /* Then any unused temporary: 644ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell */ 645cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if (!bit) 646b3aefd1cfb6aacd1695c52911dd39da50d893eceBrian Paul bit = _mesa_ffs( ~p->temp_in_use ); 647ecb6bfc0ce33b1daa84093dceeb58a4b741283e9Keith Whitwell 64815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell if (!bit) { 649bfb5ea307ec48b9b8d0d2eca0c03f6d02273d454Brian Paul _mesa_problem(NULL, "%s: out of temporaries\n", __FILE__); 6501a80fe461e162d5b6e25bd270a54e6662f72e5b3Eric Anholt exit(1); 65115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 65215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 65313abf91b42b00c7eb64c373aff3a4c1bb3d8fb7fBrian Paul if ((GLuint) bit > p->program->Base.NumTemporaries) 654b5cbaf945dd5213d5faf7bb7e4d68d0d25a25b55Keith Whitwell p->program->Base.NumTemporaries = bit; 655b5cbaf945dd5213d5faf7bb7e4d68d0d25a25b55Keith Whitwell 65693cd9237d793e38ba4479d1367be7548853f67f4Keith Whitwell p->temp_in_use |= 1<<(bit-1); 65715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return make_ureg(PROGRAM_TEMPORARY, (bit-1)); 65815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 65915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 66015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 6615620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul/** Mark a temp reg as being no longer allocatable. */ 6625620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paulstatic void reserve_temp( struct texenv_fragment_program *p, struct ureg r ) 6635620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul{ 6645620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul if (r.file == PROGRAM_TEMPORARY) 6655620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul p->temps_output |= (1 << r.idx); 6665620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul} 6675620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul 6685620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul 669f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic void release_temps(struct gl_context *ctx, struct texenv_fragment_program *p ) 67015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 67193fef22d05d0fb6f011d48d2fde533555c1695a2Brian GLuint max_temp = ctx->Const.FragmentProgram.MaxTemps; 67293cd9237d793e38ba4479d1367be7548853f67f4Keith Whitwell 6732dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell /* KW: To support tex_env_crossbar, don't release the registers in 6742dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell * temps_output. 6752dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell */ 67693cd9237d793e38ba4479d1367be7548853f67f4Keith Whitwell if (max_temp >= sizeof(int) * 8) 6772dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell p->temp_in_use = p->temps_output; 67893cd9237d793e38ba4479d1367be7548853f67f4Keith Whitwell else 6792dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell p->temp_in_use = ~((1<<max_temp)-1) | p->temps_output; 68015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 68115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 68215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 6839fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brianstatic struct ureg register_param5( struct texenv_fragment_program *p, 684ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLint s0, 685ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLint s1, 686ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLint s2, 687ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLint s3, 6889fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brian GLint s4) 68915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 690cdacca4868bbfe2e39f72d524556e7b2c7200ba5Eric Anholt int tokens[STATE_LENGTH]; 69147b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell GLuint idx; 69247b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell tokens[0] = s0; 69347b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell tokens[1] = s1; 69447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell tokens[2] = s2; 69547b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell tokens[3] = s3; 69647b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell tokens[4] = s4; 697cdacca4868bbfe2e39f72d524556e7b2c7200ba5Eric Anholt idx = _mesa_add_state_reference(p->program->Base.Parameters, 698cdacca4868bbfe2e39f72d524556e7b2c7200ba5Eric Anholt (gl_state_index *)tokens); 69947b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell return make_ureg(PROGRAM_STATE_VAR, idx); 70047b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell} 70115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 70215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 7039fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brian#define register_param1(p,s0) register_param5(p,s0,0,0,0,0) 7049fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brian#define register_param2(p,s0,s1) register_param5(p,s0,s1,0,0,0) 7059fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brian#define register_param3(p,s0,s1,s2) register_param5(p,s0,s1,s2,0,0) 7069fe3e2efc3a76b2a2fb82031041f6a6170c5b1d9Brian#define register_param4(p,s0,s1,s2,s3) register_param5(p,s0,s1,s2,s3,0) 70747b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell 7081680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwellstatic GLuint frag_to_vert_attrib( GLuint attrib ) 7091680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell{ 7101680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell switch (attrib) { 7111680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell case FRAG_ATTRIB_COL0: return VERT_ATTRIB_COLOR0; 7121680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell case FRAG_ATTRIB_COL1: return VERT_ATTRIB_COLOR1; 7131680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell default: 7141680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell assert(attrib >= FRAG_ATTRIB_TEX0); 7151680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell assert(attrib <= FRAG_ATTRIB_TEX7); 7161680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell return attrib - FRAG_ATTRIB_TEX0 + VERT_ATTRIB_TEX0; 7171680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell } 7181680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell} 7191680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 72047b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell 72147b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwellstatic struct ureg register_input( struct texenv_fragment_program *p, GLuint input ) 72247b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell{ 7231680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell if (p->state->inputs_available & (1<<input)) { 7241680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell p->program->Base.InputsRead |= (1 << input); 7251680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell return make_ureg(PROGRAM_INPUT, input); 7261680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell } 7271680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell else { 7281680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell GLuint idx = frag_to_vert_attrib( input ); 7291680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell return register_param3( p, STATE_INTERNAL, STATE_CURRENT_ATTRIB, idx ); 7301680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell } 73115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 73215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 73347b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell 7347e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paulstatic void emit_arg( struct prog_src_register *reg, 73515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg ureg ) 73615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 73715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg->File = ureg.file; 73815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg->Index = ureg.idx; 73915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell reg->Swizzle = ureg.swz; 7407db7ff878d3e5a6b345228e6eaee4797bb68b360Brian Paul reg->Negate = ureg.negatebase ? NEGATE_XYZW : NEGATE_NONE; 7411480bcacfec8f215c5827278a5f984c6bf68ba69Brian Paul reg->Abs = GL_FALSE; 74215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 74315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 7447e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paulstatic void emit_dst( struct prog_dst_register *dst, 74515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg ureg, GLuint mask ) 74615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 74715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell dst->File = ureg.file; 74815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell dst->Index = ureg.idx; 74915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell dst->WriteMask = mask; 750c9d495c6f064aacd1e072033b9c17a83b8c37fa1Brian dst->CondMask = COND_TR; /* always pass cond test */ 751c9d495c6f064aacd1e072033b9c17a83b8c37fa1Brian dst->CondSwizzle = SWIZZLE_NOOP; 75215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 75315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 7547e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paulstatic struct prog_instruction * 75515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellemit_op(struct texenv_fragment_program *p, 7565d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul enum prog_opcode op, 75715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg dest, 75815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint mask, 75922db53577603afef8fdf62c324ff5977de76b9d8Brian Paul GLboolean saturate, 76015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg src0, 76115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg src1, 76215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg src2 ) 76315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 7649ed0315271c38f5fe9cdd65020a54cbb7f61ed2bBrian Paul const GLuint nr = p->program->Base.NumInstructions++; 765de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul struct prog_instruction *inst = &p->program->Base.Instructions[nr]; 7662a8e9bb00f8cf830783cbc20a2a57f31b19491eaBrian 7672a8e9bb00f8cf830783cbc20a2a57f31b19491eaBrian assert(nr < MAX_INSTRUCTIONS); 7682a8e9bb00f8cf830783cbc20a2a57f31b19491eaBrian 769d6272e06172f7ac7a0d6e8062e8ffba33e1ab3baBrian Paul _mesa_init_instructions(inst, 1); 77015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell inst->Opcode = op; 77115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 77247b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell emit_arg( &inst->SrcReg[0], src0 ); 77347b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell emit_arg( &inst->SrcReg[1], src1 ); 77447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell emit_arg( &inst->SrcReg[2], src2 ); 77515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 776e31ac052236ea615b4995f9ec301d8af4b864531Brian Paul inst->SaturateMode = saturate ? SATURATE_ZERO_ONE : SATURATE_OFF; 77715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 77815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell emit_dst( &inst->DstReg, dest, mask ); 77915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 7805620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul#if 0 781cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell /* Accounting for indirection tracking: 782cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell */ 783cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if (dest.file == PROGRAM_TEMPORARY) 784cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell p->temps_output |= 1 << dest.idx; 7855620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul#endif 786cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell 78715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return inst; 78815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 78915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 79015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 79115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg emit_arith( struct texenv_fragment_program *p, 7925d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul enum prog_opcode op, 79347b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell struct ureg dest, 79447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell GLuint mask, 79522db53577603afef8fdf62c324ff5977de76b9d8Brian Paul GLboolean saturate, 79647b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell struct ureg src0, 79747b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell struct ureg src1, 79847b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell struct ureg src2 ) 79915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 80015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell emit_op(p, op, dest, mask, saturate, src0, src1, src2); 80115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 802cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell /* Accounting for indirection tracking: 803cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell */ 804cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if (src0.file == PROGRAM_TEMPORARY) 805cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell p->alu_temps |= 1 << src0.idx; 806cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell 807cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if (!is_undef(src1) && src1.file == PROGRAM_TEMPORARY) 808cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell p->alu_temps |= 1 << src1.idx; 809cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell 810cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if (!is_undef(src2) && src2.file == PROGRAM_TEMPORARY) 811cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell p->alu_temps |= 1 << src2.idx; 812cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell 813cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if (dest.file == PROGRAM_TEMPORARY) 814cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell p->alu_temps |= 1 << dest.idx; 815cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell 81621f99792a916a62fcfae7c208f50f192d4ce5926Brian p->program->Base.NumAluInstructions++; 81715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return dest; 81815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 81915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 82015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg emit_texld( struct texenv_fragment_program *p, 8215d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul enum prog_opcode op, 822ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct ureg dest, 823ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint destmask, 824ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint tex_unit, 825ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint tex_idx, 82644e018c09e7aeba9fd9f4c380da224bd6622c470Brian Paul GLuint tex_shadow, 827ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct ureg coord ) 82815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 8297e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul struct prog_instruction *inst = emit_op( p, op, 83015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell dest, destmask, 83122db53577603afef8fdf62c324ff5977de76b9d8Brian Paul GL_FALSE, /* don't saturate? */ 83215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell coord, /* arg 0? */ 83315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell undef, 83415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell undef); 83515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 8367e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul inst->TexSrcTarget = tex_idx; 83715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell inst->TexSrcUnit = tex_unit; 83844e018c09e7aeba9fd9f4c380da224bd6622c470Brian Paul inst->TexShadow = tex_shadow; 83915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 84021f99792a916a62fcfae7c208f50f192d4ce5926Brian p->program->Base.NumTexInstructions++; 84115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 8425620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul /* Accounting for indirection tracking: 8435620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul */ 8445620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul reserve_temp(p, dest); 8455620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul 846114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger#if 0 847cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell /* Is this a texture indirection? 848cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell */ 849cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell if ((coord.file == PROGRAM_TEMPORARY && 850cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell (p->temps_output & (1<<coord.idx))) || 851cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell (dest.file == PROGRAM_TEMPORARY && 852cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell (p->alu_temps & (1<<dest.idx)))) { 85321f99792a916a62fcfae7c208f50f192d4ce5926Brian p->program->Base.NumTexIndirections++; 8542dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell p->temps_output = 1<<coord.idx; 855cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell p->alu_temps = 0; 8562dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell assert(0); /* KW: texture env crossbar */ 85715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 858114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger#endif 85915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 86015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return dest; 86115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 86215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 86315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 86447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwellstatic struct ureg register_const4f( struct texenv_fragment_program *p, 865ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLfloat s0, 866ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLfloat s1, 867ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLfloat s2, 868ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLfloat s3) 86915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 87047b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell GLfloat values[4]; 871a90046f1097ad95de2aa95ca65741dff5cddced9Brian GLuint idx, swizzle; 872d01269a57f4cfdb859352c933bc546296545dd80Brian Paul struct ureg r; 87347b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell values[0] = s0; 87447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell values[1] = s1; 87547b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell values[2] = s2; 87647b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell values[3] = s3; 877a90046f1097ad95de2aa95ca65741dff5cddced9Brian idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4, 878a90046f1097ad95de2aa95ca65741dff5cddced9Brian &swizzle ); 879d01269a57f4cfdb859352c933bc546296545dd80Brian Paul r = make_ureg(PROGRAM_CONSTANT, idx); 880d01269a57f4cfdb859352c933bc546296545dd80Brian Paul r.swz = swizzle; 881d01269a57f4cfdb859352c933bc546296545dd80Brian Paul return r; 88215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 88315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 884e490242b9aeb50bd96fed7a9afbf529295a8ac0eKeith Whitwell#define register_scalar_const(p, s0) register_const4f(p, s0, s0, s0, s0) 88547b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell#define register_const1f(p, s0) register_const4f(p, s0, 0, 0, 1) 88647b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell#define register_const2f(p, s0, s1) register_const4f(p, s0, s1, 0, 1) 88747b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell#define register_const3f(p, s0, s1, s2) register_const4f(p, s0, s1, s2, 1) 88815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 88915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 8902dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwellstatic struct ureg get_one( struct texenv_fragment_program *p ) 8912dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell{ 8922dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell if (is_undef(p->one)) 8932dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell p->one = register_scalar_const(p, 1.0); 8942dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell return p->one; 8952dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell} 8962dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 8972dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwellstatic struct ureg get_half( struct texenv_fragment_program *p ) 8982dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell{ 8992dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell if (is_undef(p->half)) 9004dd8a8907e40126e42131a400b59e7d5da5e302aAapo Tahkola p->half = register_scalar_const(p, 0.5); 9012dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell return p->half; 9022dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell} 9032dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 9042dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwellstatic struct ureg get_zero( struct texenv_fragment_program *p ) 9052dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell{ 9062dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell if (is_undef(p->zero)) 9074dd8a8907e40126e42131a400b59e7d5da5e302aAapo Tahkola p->zero = register_scalar_const(p, 0.0); 9082dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell return p->zero; 9092dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell} 9102dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 91115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 91215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic void program_error( struct texenv_fragment_program *p, const char *msg ) 91315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 914c5dde53f4e42612518cd927bb58f08c0e22db17aVinson Lee _mesa_problem(NULL, "%s", msg); 91515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell p->error = 1; 91615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 91715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 91815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg get_source( struct texenv_fragment_program *p, 919ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint src, GLuint unit ) 92015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 92115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell switch (src) { 922ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE: 9232dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell assert(!is_undef(p->src_texture[unit])); 9242dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell return p->src_texture[unit]; 92515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 926ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE0: 927ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE1: 928ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE2: 929ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE3: 930ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE4: 931ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE5: 932ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE6: 933ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE7: 934ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell assert(!is_undef(p->src_texture[src - SRC_TEXTURE0])); 935ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell return p->src_texture[src - SRC_TEXTURE0]; 936ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 937ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_CONSTANT: 93847b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell return register_param2(p, STATE_TEXENV_COLOR, unit); 9392dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 940ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_PRIMARY_COLOR: 94147b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell return register_input(p, FRAG_ATTRIB_COL0); 9422dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 9436947f85cb5fbc433ba7763530285e470745b009bBrian Paul case SRC_ZERO: 9446947f85cb5fbc433ba7763530285e470745b009bBrian Paul return get_zero(p); 9456947f85cb5fbc433ba7763530285e470745b009bBrian Paul 946ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_PREVIOUS: 94747b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell if (is_undef(p->src_previous)) 94847b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell return register_input(p, FRAG_ATTRIB_COL0); 94947b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell else 95047b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell return p->src_previous; 9516947f85cb5fbc433ba7763530285e470745b009bBrian Paul 9526947f85cb5fbc433ba7763530285e470745b009bBrian Paul default: 9536947f85cb5fbc433ba7763530285e470745b009bBrian Paul assert(0); 954c6af9b29476e4e445623e7a2f737ba95003bbe13José Fonseca return undef; 95515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 95615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 9572dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 95815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg emit_combine_source( struct texenv_fragment_program *p, 959ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint mask, 960ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint unit, 961ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint source, 962ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint operand ) 96315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 96415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg arg, src, one; 96515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 96615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell src = get_source(p, source, unit); 96715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 96815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell switch (operand) { 969ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE_MINUS_SRC_COLOR: 97015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Get unused tmp, 97115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * Emit tmp = 1.0 - arg.xyzw 97215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 97315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell arg = get_temp( p ); 9742dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell one = get_one( p ); 9757e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_SUB, arg, mask, 0, one, src, undef); 97615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 977ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_SRC_ALPHA: 97815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell if (mask == WRITEMASK_W) 97915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return src; 98015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell else 98122db53577603afef8fdf62c324ff5977de76b9d8Brian Paul return swizzle1( src, SWIZZLE_W ); 982ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE_MINUS_SRC_ALPHA: 98315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Get unused tmp, 98415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * Emit tmp = 1.0 - arg.wwww 98515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 9862dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell arg = get_temp(p); 9872dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell one = get_one(p); 9887e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith(p, OPCODE_SUB, arg, mask, 0, 98922db53577603afef8fdf62c324ff5977de76b9d8Brian Paul one, swizzle1(src, SWIZZLE_W), undef); 990ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ZERO: 9912dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell return get_zero(p); 992ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE: 9932dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell return get_one(p); 994ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_SRC_COLOR: 9956947f85cb5fbc433ba7763530285e470745b009bBrian Paul return src; 99615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 9976947f85cb5fbc433ba7763530285e470745b009bBrian Paul assert(0); 99815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return src; 99915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 100015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 100115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1002f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul/** 1003f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul * Check if the RGB and Alpha sources and operands match for the given 1004f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul * texture unit's combinder state. When the RGB and A sources and 1005f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul * operands match, we can emit fewer instructions. 1006f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul */ 1007a5e7003565a021ceb82a8b16f4a0ecc7cc6c02e0Brian Paulstatic GLboolean args_match( const struct state_key *key, GLuint unit ) 100815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 10099ed0315271c38f5fe9cdd65020a54cbb7f61ed2bBrian Paul GLuint i, numArgs = key->unit[unit].NumArgsRGB; 101015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1011457e427e32324884acb064b756e327dc131ff135Brian Paul for (i = 0; i < numArgs; i++) { 1012ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->unit[unit].OptA[i].Source != key->unit[unit].OptRGB[i].Source) 101315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return GL_FALSE; 101415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 10159ed0315271c38f5fe9cdd65020a54cbb7f61ed2bBrian Paul switch (key->unit[unit].OptA[i].Operand) { 1016ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_SRC_ALPHA: 10179ed0315271c38f5fe9cdd65020a54cbb7f61ed2bBrian Paul switch (key->unit[unit].OptRGB[i].Operand) { 1018ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_SRC_COLOR: 1019ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_SRC_ALPHA: 102015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 102115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 102215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return GL_FALSE; 102315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 102415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 1025ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE_MINUS_SRC_ALPHA: 10269ed0315271c38f5fe9cdd65020a54cbb7f61ed2bBrian Paul switch (key->unit[unit].OptRGB[i].Operand) { 1027ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE_MINUS_SRC_COLOR: 1028ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE_MINUS_SRC_ALPHA: 102915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 103015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 103115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return GL_FALSE; 103215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 103315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 103415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 103515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return GL_FALSE; /* impossible */ 103615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 103715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 103815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 103915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return GL_TRUE; 104015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 104115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 104215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwellstatic struct ureg emit_combine( struct texenv_fragment_program *p, 1043ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct ureg dest, 1044ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint mask, 104522db53577603afef8fdf62c324ff5977de76b9d8Brian Paul GLboolean saturate, 1046ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint unit, 1047ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint nr, 1048ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint mode, 1049d9736db6676948e06712d4bcba46b7040452f870Brian Paul const struct mode_opt *opt) 1050ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 1051bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul struct ureg src[MAX_COMBINER_TERMS]; 1052cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell struct ureg tmp, half; 105322db53577603afef8fdf62c324ff5977de76b9d8Brian Paul GLuint i; 105415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1055bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul assert(nr <= MAX_COMBINER_TERMS); 10566947f85cb5fbc433ba7763530285e470745b009bBrian Paul 105715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell for (i = 0; i < nr; i++) 1058ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell src[i] = emit_combine_source( p, mask, unit, opt[i].Source, opt[i].Operand ); 105915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 106015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell switch (mode) { 1061ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_REPLACE: 106215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell if (mask == WRITEMASK_XYZW && !saturate) 106315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return src[0]; 106415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell else 10657e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_MOV, dest, mask, saturate, src[0], undef, undef ); 1066ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_MODULATE: 10677e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_MUL, dest, mask, saturate, 10686fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell src[0], src[1], undef ); 1069ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_ADD: 10707e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_ADD, dest, mask, saturate, 10716fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell src[0], src[1], undef ); 1072ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_ADD_SIGNED: 107315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* tmp = arg0 + arg1 1074cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell * result = tmp - .5 107515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 10762dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell half = get_half(p); 107799da2d30eb08e50edf4b0067518af3acdf2dabc0Jerome Glisse tmp = get_temp( p ); 10787e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_ADD, tmp, mask, 0, src[0], src[1], undef ); 10797e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_SUB, dest, mask, saturate, tmp, half, undef ); 108015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return dest; 1081ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_INTERPOLATE: 108215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Arg0 * (Arg2) + Arg1 * (1-Arg2) -- note arguments are reordered: 108315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 10847e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_LRP, dest, mask, saturate, src[2], src[0], src[1] ); 108515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1086ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_SUBTRACT: 10877e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_SUB, dest, mask, saturate, src[0], src[1], undef ); 108815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1089ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGBA: 1090ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGBA_EXT: 1091ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGB_EXT: 1092ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGB: { 109315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg tmp0 = get_temp( p ); 109415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg tmp1 = get_temp( p ); 1095e490242b9aeb50bd96fed7a9afbf529295a8ac0eKeith Whitwell struct ureg neg1 = register_scalar_const(p, -1); 1096e490242b9aeb50bd96fed7a9afbf529295a8ac0eKeith Whitwell struct ureg two = register_scalar_const(p, 2); 109715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 109815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* tmp0 = 2*src0 - 1 109915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * tmp1 = 2*src1 - 1 110015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 110115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * dst = tmp0 dot3 tmp1 110215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 11037e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_MAD, tmp0, WRITEMASK_XYZW, 0, 11046fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell two, src[0], neg1); 110515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 11062efa86ea3040c37965987160733b22e2a0541a3eKenneth Graunke if (memcmp(&src[0], &src[1], sizeof(struct ureg)) == 0) 110715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell tmp1 = tmp0; 110815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell else 11097e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_MAD, tmp1, WRITEMASK_XYZW, 0, 11106fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell two, src[1], neg1); 11117e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_DP3, dest, mask, saturate, tmp0, tmp1, undef); 111215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return dest; 111315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 1114ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_MODULATE_ADD_ATI: 11156fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell /* Arg0 * Arg2 + Arg1 */ 11167e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_MAD, dest, mask, saturate, 11176fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell src[0], src[2], src[1] ); 1118ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_MODULATE_SIGNED_ADD_ATI: { 11196fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell /* Arg0 * Arg2 + Arg1 - 0.5 */ 11206fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell struct ureg tmp0 = get_temp(p); 11212dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell half = get_half(p); 11227e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_MAD, tmp0, mask, 0, src[0], src[2], src[1] ); 11237e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_SUB, dest, mask, saturate, tmp0, half, undef ); 11246fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell return dest; 11256fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell } 1126ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_MODULATE_SUBTRACT_ATI: 11276fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell /* Arg0 * Arg2 - Arg1 */ 11287e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( p, OPCODE_MAD, dest, mask, 0, src[0], src[2], negate(src[1]) ); 11296fe176a64859798db17fbaed6858cccc646aae38Keith Whitwell return dest; 11306947f85cb5fbc433ba7763530285e470745b009bBrian Paul case MODE_ADD_PRODUCTS: 11316947f85cb5fbc433ba7763530285e470745b009bBrian Paul /* Arg0 * Arg1 + Arg2 * Arg3 */ 11326947f85cb5fbc433ba7763530285e470745b009bBrian Paul { 11336947f85cb5fbc433ba7763530285e470745b009bBrian Paul struct ureg tmp0 = get_temp(p); 11346947f85cb5fbc433ba7763530285e470745b009bBrian Paul emit_arith( p, OPCODE_MUL, tmp0, mask, 0, src[0], src[1], undef ); 11356947f85cb5fbc433ba7763530285e470745b009bBrian Paul emit_arith( p, OPCODE_MAD, dest, mask, saturate, src[2], src[3], tmp0 ); 11366947f85cb5fbc433ba7763530285e470745b009bBrian Paul } 11376947f85cb5fbc433ba7763530285e470745b009bBrian Paul return dest; 11386947f85cb5fbc433ba7763530285e470745b009bBrian Paul case MODE_ADD_PRODUCTS_SIGNED: 11396947f85cb5fbc433ba7763530285e470745b009bBrian Paul /* Arg0 * Arg1 + Arg2 * Arg3 - 0.5 */ 11406947f85cb5fbc433ba7763530285e470745b009bBrian Paul { 11416947f85cb5fbc433ba7763530285e470745b009bBrian Paul struct ureg tmp0 = get_temp(p); 11426947f85cb5fbc433ba7763530285e470745b009bBrian Paul half = get_half(p); 11436947f85cb5fbc433ba7763530285e470745b009bBrian Paul emit_arith( p, OPCODE_MUL, tmp0, mask, 0, src[0], src[1], undef ); 11446947f85cb5fbc433ba7763530285e470745b009bBrian Paul emit_arith( p, OPCODE_MAD, tmp0, mask, 0, src[2], src[3], tmp0 ); 11456947f85cb5fbc433ba7763530285e470745b009bBrian Paul emit_arith( p, OPCODE_SUB, dest, mask, saturate, tmp0, half, undef ); 11466947f85cb5fbc433ba7763530285e470745b009bBrian Paul } 11476947f85cb5fbc433ba7763530285e470745b009bBrian Paul return dest; 1148114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger case MODE_BUMP_ENVMAP_ATI: 1149114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger /* special - not handled here */ 1150114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger assert(0); 1151114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger return src[0]; 115215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 11536947f85cb5fbc433ba7763530285e470745b009bBrian Paul assert(0); 115415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return src[0]; 115515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 115615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 115715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 115815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 115922db53577603afef8fdf62c324ff5977de76b9d8Brian Paul/** 116022db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * Generate instructions for one texture unit's env/combiner mode. 116122db53577603afef8fdf62c324ff5977de76b9d8Brian Paul */ 116222db53577603afef8fdf62c324ff5977de76b9d8Brian Paulstatic struct ureg 116322db53577603afef8fdf62c324ff5977de76b9d8Brian Paulemit_texenv(struct texenv_fragment_program *p, GLuint unit) 116415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 1165a5e7003565a021ceb82a8b16f4a0ecc7cc6c02e0Brian Paul const struct state_key *key = p->state; 1166e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul GLboolean rgb_saturate, alpha_saturate; 116715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint rgb_shift, alpha_shift; 1168a5e7003565a021ceb82a8b16f4a0ecc7cc6c02e0Brian Paul struct ureg out, dest; 116915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1170ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (!key->unit[unit].enabled) { 1171ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell return get_source(p, SRC_PREVIOUS, 0); 117215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 1173114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger if (key->unit[unit].ModeRGB == MODE_BUMP_ENVMAP_ATI) { 1174114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger /* this isn't really a env stage delivering a color and handled elsewhere */ 1175114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger return get_source(p, SRC_PREVIOUS, 0); 1176114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger } 1177ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 1178ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch (key->unit[unit].ModeRGB) { 1179ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGB_EXT: 1180ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell alpha_shift = key->unit[unit].ScaleShiftA; 118115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell rgb_shift = 0; 118215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 1183ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGBA_EXT: 118415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell alpha_shift = 0; 118515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell rgb_shift = 0; 118615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 118715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 1188ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell rgb_shift = key->unit[unit].ScaleShiftRGB; 1189ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell alpha_shift = key->unit[unit].ScaleShiftA; 119015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 119115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 1192ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 1193956e6c3978abe918348377cf05e5c92971e50d3fBrian Paul /* If we'll do rgb/alpha shifting don't saturate in emit_combine(). 1194956e6c3978abe918348377cf05e5c92971e50d3fBrian Paul * We don't want to clamp twice. 1195956e6c3978abe918348377cf05e5c92971e50d3fBrian Paul */ 1196e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul if (rgb_shift) 1197e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul rgb_saturate = GL_FALSE; /* saturate after rgb shift */ 1198e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul else if (need_saturate(key->unit[unit].ModeRGB)) 1199e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul rgb_saturate = GL_TRUE; 1200e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul else 1201e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul rgb_saturate = GL_FALSE; 1202e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul 1203e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul if (alpha_shift) 1204e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul alpha_saturate = GL_FALSE; /* saturate after alpha shift */ 1205e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul else if (need_saturate(key->unit[unit].ModeA)) 1206e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul alpha_saturate = GL_TRUE; 1207e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul else 1208e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul alpha_saturate = GL_FALSE; 1209956e6c3978abe918348377cf05e5c92971e50d3fBrian Paul 12106e83420ee0ccb2228fab0f86a6e8bf8a6aefe57aBrian Paul /* If this is the very last calculation (and various other conditions 12116e83420ee0ccb2228fab0f86a6e8bf8a6aefe57aBrian Paul * are met), emit directly to the color output register. Otherwise, 12126e83420ee0ccb2228fab0f86a6e8bf8a6aefe57aBrian Paul * emit to a temporary register. 1213cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell */ 1214ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->separate_specular || 1215cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell unit != p->last_tex_stage || 1216cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell alpha_shift || 12176e83420ee0ccb2228fab0f86a6e8bf8a6aefe57aBrian Paul key->num_draw_buffers != 1 || 1218cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell rgb_shift) 1219cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell dest = get_temp( p ); 1220cf4f3c5061423ab7241ea2a59d4949dbfb9a3278Keith Whitwell else 12218d475822e6e19fa79719c856a2db5b6a205db1b9Brian Paul dest = make_ureg(PROGRAM_OUTPUT, FRAG_RESULT_COLOR); 122215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 122315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Emit the RGB and A combine ops 122415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 1225ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->unit[unit].ModeRGB == key->unit[unit].ModeA && 1226ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell args_match(key, unit)) { 1227e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul out = emit_combine( p, dest, WRITEMASK_XYZW, rgb_saturate, 122815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell unit, 1229ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].NumArgsRGB, 1230ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].ModeRGB, 1231ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].OptRGB); 123215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 1233ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell else if (key->unit[unit].ModeRGB == MODE_DOT3_RGBA_EXT || 12349a45176dd85a1cd523498efeebd0481950a1bf58Roland Scheidegger key->unit[unit].ModeRGB == MODE_DOT3_RGBA) { 1235e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul out = emit_combine( p, dest, WRITEMASK_XYZW, rgb_saturate, 123615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell unit, 1237ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].NumArgsRGB, 1238ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].ModeRGB, 1239ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].OptRGB); 124015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 124115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell else { 124215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Need to do something to stop from re-emitting identical 124315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * argument calculations here: 124415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 1245e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul out = emit_combine( p, dest, WRITEMASK_XYZ, rgb_saturate, 124615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell unit, 1247ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].NumArgsRGB, 1248ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].ModeRGB, 1249ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].OptRGB); 1250e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul out = emit_combine( p, dest, WRITEMASK_W, alpha_saturate, 125115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell unit, 1252ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].NumArgsA, 1253ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].ModeA, 1254ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[unit].OptA); 125515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 125615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 125715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Deal with the final shift: 125815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 125915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell if (alpha_shift || rgb_shift) { 1260a5e7003565a021ceb82a8b16f4a0ecc7cc6c02e0Brian Paul struct ureg shift; 1261e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul GLboolean saturate = GL_TRUE; /* always saturate at this point */ 1262a5e7003565a021ceb82a8b16f4a0ecc7cc6c02e0Brian Paul 126315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell if (rgb_shift == alpha_shift) { 1264452a592ca4b1bac78eee53fb9f2f1deac7832840José Fonseca shift = register_scalar_const(p, (GLfloat)(1<<rgb_shift)); 126515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 126615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell else { 12672dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell shift = register_const4f(p, 1268452a592ca4b1bac78eee53fb9f2f1deac7832840José Fonseca (GLfloat)(1<<rgb_shift), 1269452a592ca4b1bac78eee53fb9f2f1deac7832840José Fonseca (GLfloat)(1<<rgb_shift), 1270452a592ca4b1bac78eee53fb9f2f1deac7832840José Fonseca (GLfloat)(1<<rgb_shift), 1271452a592ca4b1bac78eee53fb9f2f1deac7832840José Fonseca (GLfloat)(1<<alpha_shift)); 127215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 12737e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul return emit_arith( p, OPCODE_MUL, dest, WRITEMASK_XYZW, 127415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell saturate, out, shift, undef ); 127515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 127615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell else 127715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return out; 127815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 127915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 12802dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 128122db53577603afef8fdf62c324ff5977de76b9d8Brian Paul/** 128222db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * Generate instruction for getting a texture source term. 128322db53577603afef8fdf62c324ff5977de76b9d8Brian Paul */ 12842dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwellstatic void load_texture( struct texenv_fragment_program *p, GLuint unit ) 12852dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell{ 12862dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell if (is_undef(p->src_texture[unit])) { 1287b5ec0a68589c5d8f0d4be2556ea6d6b01fd4e37dBrian Paul const GLuint texTarget = p->state->unit[unit].source_index; 1288114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger struct ureg texcoord; 12892dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell struct ureg tmp = get_tex_temp( p ); 12902dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 1291114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger if (is_undef(p->texcoord_tex[unit])) { 1292114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger texcoord = register_input(p, FRAG_ATTRIB_TEX0+unit); 1293114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger } 1294114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger else { 1295114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger /* might want to reuse this reg for tex output actually */ 1296114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger texcoord = p->texcoord_tex[unit]; 1297114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger } 1298114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 12992dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell /* TODO: Use D0_MASK_XY where possible. 13002dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell */ 130183ad2a756ea8dd1b0ca9746e355ce3de0f29356eNicolai Haehnle if (p->state->unit[unit].enabled) { 130244e018c09e7aeba9fd9f4c380da224bd6622c470Brian Paul GLboolean shadow = GL_FALSE; 13030397b2bb41b0f337af2949a15bcd7d0e7e8a7dc1Keith Whitwell 130444e018c09e7aeba9fd9f4c380da224bd6622c470Brian Paul if (p->state->unit[unit].shadow) { 130583ad2a756ea8dd1b0ca9746e355ce3de0f29356eNicolai Haehnle p->program->Base.ShadowSamplers |= 1 << unit; 130644e018c09e7aeba9fd9f4c380da224bd6622c470Brian Paul shadow = GL_TRUE; 130744e018c09e7aeba9fd9f4c380da224bd6622c470Brian Paul } 130844e018c09e7aeba9fd9f4c380da224bd6622c470Brian Paul 130944e018c09e7aeba9fd9f4c380da224bd6622c470Brian Paul p->src_texture[unit] = emit_texld( p, OPCODE_TXP, 131044e018c09e7aeba9fd9f4c380da224bd6622c470Brian Paul tmp, WRITEMASK_XYZW, 131144e018c09e7aeba9fd9f4c380da224bd6622c470Brian Paul unit, texTarget, shadow, 131244e018c09e7aeba9fd9f4c380da224bd6622c470Brian Paul texcoord ); 13139b7e5a51f49e842f4114545f5eb171a597c83a66Brian 13149b7e5a51f49e842f4114545f5eb171a597c83a66Brian p->program->Base.SamplersUsed |= (1 << unit); 13151fe385fdc96688a5249d52184f457910a0c25488Brian /* This identity mapping should already be in place 13161fe385fdc96688a5249d52184f457910a0c25488Brian * (see _mesa_init_program_struct()) but let's be safe. 13171fe385fdc96688a5249d52184f457910a0c25488Brian */ 13181fe385fdc96688a5249d52184f457910a0c25488Brian p->program->Base.SamplerUnits[unit] = unit; 13199b7e5a51f49e842f4114545f5eb171a597c83a66Brian } 13209b7e5a51f49e842f4114545f5eb171a597c83a66Brian else 1321b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola p->src_texture[unit] = get_zero(p); 13224a9f1eed2ba02f2ae2bf92d16f89d10f09b2a21eBrian Paul 13234a9f1eed2ba02f2ae2bf92d16f89d10f09b2a21eBrian Paul if (p->state->unit[unit].texture_cyl_wrap) { 13244a9f1eed2ba02f2ae2bf92d16f89d10f09b2a21eBrian Paul /* set flag which is checked by Mesa->Gallium program translation */ 13254a9f1eed2ba02f2ae2bf92d16f89d10f09b2a21eBrian Paul p->program->Base.InputFlags[0] |= PROG_PARAM_BIT_CYL_WRAP; 13264a9f1eed2ba02f2ae2bf92d16f89d10f09b2a21eBrian Paul } 13274a9f1eed2ba02f2ae2bf92d16f89d10f09b2a21eBrian Paul 13282dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell } 13292dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell} 13302dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 1331241b6b7ab1a1a11c7fc516d1b6ff2c1bc8aba238Keith Whitwellstatic GLboolean load_texenv_source( struct texenv_fragment_program *p, 1332ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint src, GLuint unit ) 13332dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell{ 13342dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell switch (src) { 13354dd8a8907e40126e42131a400b59e7d5da5e302aAapo Tahkola case SRC_TEXTURE: 13362dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell load_texture(p, unit); 13372dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell break; 13382dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 1339ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE0: 1340ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE1: 1341ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE2: 1342ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE3: 1343ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE4: 1344ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE5: 1345ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE6: 1346ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE7: 1347ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell load_texture(p, src - SRC_TEXTURE0); 13482dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell break; 13492dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 13502dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell default: 13516947f85cb5fbc433ba7763530285e470745b009bBrian Paul /* not a texture src - do nothing */ 13522dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell break; 13532dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell } 1354241b6b7ab1a1a11c7fc516d1b6ff2c1bc8aba238Keith Whitwell 1355241b6b7ab1a1a11c7fc516d1b6ff2c1bc8aba238Keith Whitwell return GL_TRUE; 13562dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell} 13572dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 135822db53577603afef8fdf62c324ff5977de76b9d8Brian Paul 135922db53577603afef8fdf62c324ff5977de76b9d8Brian Paul/** 136022db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * Generate instructions for loading all texture source terms. 136122db53577603afef8fdf62c324ff5977de76b9d8Brian Paul */ 136222db53577603afef8fdf62c324ff5977de76b9d8Brian Paulstatic GLboolean 1363457e427e32324884acb064b756e327dc131ff135Brian Paulload_texunit_sources( struct texenv_fragment_program *p, GLuint unit ) 13642dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell{ 1365a5e7003565a021ceb82a8b16f4a0ecc7cc6c02e0Brian Paul const struct state_key *key = p->state; 1366b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola GLuint i; 1367b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola 1368b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola for (i = 0; i < key->unit[unit].NumArgsRGB; i++) { 1369114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger load_texenv_source( p, key->unit[unit].OptRGB[i].Source, unit ); 1370b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola } 1371b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola 1372b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola for (i = 0; i < key->unit[unit].NumArgsA; i++) { 1373b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola load_texenv_source( p, key->unit[unit].OptA[i].Source, unit ); 13742dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell } 1375b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola 1376241b6b7ab1a1a11c7fc516d1b6ff2c1bc8aba238Keith Whitwell return GL_TRUE; 13772dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell} 13782dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 1379114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger/** 1380114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger * Generate instructions for loading bump map textures. 1381114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger */ 1382114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheideggerstatic GLboolean 1383457e427e32324884acb064b756e327dc131ff135Brian Paulload_texunit_bumpmap( struct texenv_fragment_program *p, GLuint unit ) 1384114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger{ 1385a5e7003565a021ceb82a8b16f4a0ecc7cc6c02e0Brian Paul const struct state_key *key = p->state; 1386114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger GLuint bumpedUnitNr = key->unit[unit].OptRGB[1].Source - SRC_TEXTURE0; 1387114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger struct ureg texcDst, bumpMapRes; 1388114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger struct ureg constdudvcolor = register_const4f(p, 0.0, 0.0, 0.0, 1.0); 1389114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger struct ureg texcSrc = register_input(p, FRAG_ATTRIB_TEX0 + bumpedUnitNr); 1390114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger struct ureg rotMat0 = register_param3( p, STATE_INTERNAL, STATE_ROT_MATRIX_0, unit ); 1391114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger struct ureg rotMat1 = register_param3( p, STATE_INTERNAL, STATE_ROT_MATRIX_1, unit ); 1392114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 1393114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger load_texenv_source( p, unit + SRC_TEXTURE0, unit ); 1394114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 1395114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger bumpMapRes = get_source(p, key->unit[unit].OptRGB[0].Source, unit); 1396114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger texcDst = get_tex_temp( p ); 1397114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger p->texcoord_tex[bumpedUnitNr] = texcDst; 1398114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 1399457e427e32324884acb064b756e327dc131ff135Brian Paul /* Apply rot matrix and add coords to be available in next phase. 1400457e427e32324884acb064b756e327dc131ff135Brian Paul * dest = (Arg0.xxxx * rotMat0 + Arg1) + (Arg0.yyyy * rotMat1) 1401457e427e32324884acb064b756e327dc131ff135Brian Paul * note only 2 coords are affected the rest are left unchanged (mul by 0) 1402457e427e32324884acb064b756e327dc131ff135Brian Paul */ 1403114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger emit_arith( p, OPCODE_MAD, texcDst, WRITEMASK_XYZW, 0, 1404114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger swizzle1(bumpMapRes, SWIZZLE_X), rotMat0, texcSrc ); 1405114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger emit_arith( p, OPCODE_MAD, texcDst, WRITEMASK_XYZW, 0, 1406114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger swizzle1(bumpMapRes, SWIZZLE_Y), rotMat1, texcDst ); 1407114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 1408457e427e32324884acb064b756e327dc131ff135Brian Paul /* Move 0,0,0,1 into bumpmap src if someone (crossbar) is foolish 1409457e427e32324884acb064b756e327dc131ff135Brian Paul * enough to access this later, should optimize away. 1410457e427e32324884acb064b756e327dc131ff135Brian Paul */ 1411457e427e32324884acb064b756e327dc131ff135Brian Paul emit_arith( p, OPCODE_MOV, bumpMapRes, WRITEMASK_XYZW, 0, 1412457e427e32324884acb064b756e327dc131ff135Brian Paul constdudvcolor, undef, undef ); 1413114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 1414114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger return GL_TRUE; 1415114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger} 141622db53577603afef8fdf62c324ff5977de76b9d8Brian Paul 141722db53577603afef8fdf62c324ff5977de76b9d8Brian Paul/** 141822db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * Generate a new fragment program which implements the context's 141922db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * current texture env/combine mode. 142022db53577603afef8fdf62c324ff5977de76b9d8Brian Paul */ 142122db53577603afef8fdf62c324ff5977de76b9d8Brian Paulstatic void 1422f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergcreate_new_program(struct gl_context *ctx, struct state_key *key, 1423122629f27925a9dc50029bebc5079f87f416a7e1Brian Paul struct gl_fragment_program *program) 142415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 1425e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul struct prog_instruction instBuffer[MAX_INSTRUCTIONS]; 142615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct texenv_fragment_program p; 142715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint unit; 142815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell struct ureg cf, out; 14294b39a0da89f5b07d4a24bc9ce52693e6c2acfe99Dave Airlie int i; 1430276330b2412910777f7016f427909085f02acbb8Keith Whitwell 143126f8fad1456fdc2b352cea9d3b4c32cb5f6ae947Kenneth Graunke memset(&p, 0, sizeof(p)); 1432ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell p.state = key; 1433ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell p.program = program; 143415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1435e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul /* During code generation, use locally-allocated instruction buffer, 1436e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul * then alloc dynamic storage below. 1437e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul */ 1438e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul p.program->Base.Instructions = instBuffer; 1439276330b2412910777f7016f427909085f02acbb8Keith Whitwell p.program->Base.Target = GL_FRAGMENT_PROGRAM_ARB; 1440457e427e32324884acb064b756e327dc131ff135Brian Paul p.program->Base.String = NULL; 1441457e427e32324884acb064b756e327dc131ff135Brian Paul p.program->Base.NumTexIndirections = 1; /* is this right? */ 144221f99792a916a62fcfae7c208f50f192d4ce5926Brian p.program->Base.NumTexInstructions = 0; 144321f99792a916a62fcfae7c208f50f192d4ce5926Brian p.program->Base.NumAluInstructions = 0; 1444457e427e32324884acb064b756e327dc131ff135Brian Paul p.program->Base.NumInstructions = 0; 1445457e427e32324884acb064b756e327dc131ff135Brian Paul p.program->Base.NumTemporaries = 0; 1446457e427e32324884acb064b756e327dc131ff135Brian Paul p.program->Base.NumParameters = 0; 1447457e427e32324884acb064b756e327dc131ff135Brian Paul p.program->Base.NumAttributes = 0; 1448457e427e32324884acb064b756e327dc131ff135Brian Paul p.program->Base.NumAddressRegs = 0; 1449de99760bf3511d05185799c4fb4347f9e5f420f4Brian Paul p.program->Base.Parameters = _mesa_new_parameter_list(); 1450457e427e32324884acb064b756e327dc131ff135Brian Paul p.program->Base.InputsRead = 0x0; 14514b39a0da89f5b07d4a24bc9ce52693e6c2acfe99Dave Airlie 1452b6b9b17d27c570cc99ae339e595cf2f63ca5e8d7Brian Paul if (key->num_draw_buffers == 1) 14534b39a0da89f5b07d4a24bc9ce52693e6c2acfe99Dave Airlie p.program->Base.OutputsWritten = 1 << FRAG_RESULT_COLOR; 14544b39a0da89f5b07d4a24bc9ce52693e6c2acfe99Dave Airlie else { 1455b6b9b17d27c570cc99ae339e595cf2f63ca5e8d7Brian Paul for (i = 0; i < key->num_draw_buffers; i++) 14564b39a0da89f5b07d4a24bc9ce52693e6c2acfe99Dave Airlie p.program->Base.OutputsWritten |= (1 << (FRAG_RESULT_DATA0 + i)); 14574b39a0da89f5b07d4a24bc9ce52693e6c2acfe99Dave Airlie } 145815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1459114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { 14602dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell p.src_texture[unit] = undef; 1461114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger p.texcoord_tex[unit] = undef; 1462114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger } 14632dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 146447b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell p.src_previous = undef; 14655ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell p.half = undef; 14665ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell p.zero = undef; 14675ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell p.one = undef; 14685ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell 146915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell p.last_tex_stage = 0; 147093fef22d05d0fb6f011d48d2fde533555c1695a2Brian release_temps(ctx, &p); 147115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 14722fa6012f6a0b02de6093cbccba3bf4432f072e57Brian Paul if (key->enabled_units && key->num_draw_buffers) { 1473457e427e32324884acb064b756e327dc131ff135Brian Paul GLboolean needbumpstage = GL_FALSE; 1474457e427e32324884acb064b756e327dc131ff135Brian Paul 1475114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger /* Zeroth pass - bump map textures first */ 14767a7d5879e28607c151132a8b6a07cf4be36b5b3eBrian Paul for (unit = 0; unit < key->nr_enabled_units; unit++) 1477457e427e32324884acb064b756e327dc131ff135Brian Paul if (key->unit[unit].enabled && 1478457e427e32324884acb064b756e327dc131ff135Brian Paul key->unit[unit].ModeRGB == MODE_BUMP_ENVMAP_ATI) { 1479114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger needbumpstage = GL_TRUE; 1480114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger load_texunit_bumpmap( &p, unit ); 1481114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger } 1482114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger if (needbumpstage) 1483114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger p.program->Base.NumTexIndirections++; 1484114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 14852dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell /* First pass - to support texture_env_crossbar, first identify 14862dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell * all referenced texture sources and emit texld instructions 14872dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell * for each: 14882dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell */ 14897a7d5879e28607c151132a8b6a07cf4be36b5b3eBrian Paul for (unit = 0; unit < key->nr_enabled_units; unit++) 1490ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->unit[unit].enabled) { 1491b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola load_texunit_sources( &p, unit ); 1492b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola p.last_tex_stage = unit; 149315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 149415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 14952dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell /* Second pass - emit combine instructions to build final color: 14962dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell */ 14977a7d5879e28607c151132a8b6a07cf4be36b5b3eBrian Paul for (unit = 0; unit < key->nr_enabled_units; unit++) 149884d6bed4d6844110af23a995e2fad0280a92d46cBrian Paul if (key->unit[unit].enabled) { 149915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell p.src_previous = emit_texenv( &p, unit ); 15005620c20b24dc4f780a2246eb5270c4476b487e0aBrian Paul reserve_temp(&p, p.src_previous); /* don't re-use this temp reg */ 150193fef22d05d0fb6f011d48d2fde533555c1695a2Brian release_temps(ctx, &p); /* release all temps */ 150215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 150315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 150415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1505ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell cf = get_source( &p, SRC_PREVIOUS, 0 ); 150615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1507b6b9b17d27c570cc99ae339e595cf2f63ca5e8d7Brian Paul for (i = 0; i < key->num_draw_buffers; i++) { 1508b6b9b17d27c570cc99ae339e595cf2f63ca5e8d7Brian Paul if (key->num_draw_buffers == 1) 15094b39a0da89f5b07d4a24bc9ce52693e6c2acfe99Dave Airlie out = make_ureg( PROGRAM_OUTPUT, FRAG_RESULT_COLOR ); 15104b39a0da89f5b07d4a24bc9ce52693e6c2acfe99Dave Airlie else { 15114b39a0da89f5b07d4a24bc9ce52693e6c2acfe99Dave Airlie out = make_ureg( PROGRAM_OUTPUT, FRAG_RESULT_DATA0 + i ); 15124b39a0da89f5b07d4a24bc9ce52693e6c2acfe99Dave Airlie } 151315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 15144b39a0da89f5b07d4a24bc9ce52693e6c2acfe99Dave Airlie if (key->separate_specular) { 15154b39a0da89f5b07d4a24bc9ce52693e6c2acfe99Dave Airlie /* Emit specular add. 15164b39a0da89f5b07d4a24bc9ce52693e6c2acfe99Dave Airlie */ 15174b39a0da89f5b07d4a24bc9ce52693e6c2acfe99Dave Airlie struct ureg s = register_input(&p, FRAG_ATTRIB_COL1); 15184b39a0da89f5b07d4a24bc9ce52693e6c2acfe99Dave Airlie emit_arith( &p, OPCODE_ADD, out, WRITEMASK_XYZ, 0, cf, s, undef ); 15194b39a0da89f5b07d4a24bc9ce52693e6c2acfe99Dave Airlie emit_arith( &p, OPCODE_MOV, out, WRITEMASK_W, 0, cf, undef, undef ); 15204b39a0da89f5b07d4a24bc9ce52693e6c2acfe99Dave Airlie } 15214b39a0da89f5b07d4a24bc9ce52693e6c2acfe99Dave Airlie else if (memcmp(&cf, &out, sizeof(cf)) != 0) { 15224b39a0da89f5b07d4a24bc9ce52693e6c2acfe99Dave Airlie /* Will wind up in here if no texture enabled or a couple of 15234b39a0da89f5b07d4a24bc9ce52693e6c2acfe99Dave Airlie * other scenarios (GL_REPLACE for instance). 15244b39a0da89f5b07d4a24bc9ce52693e6c2acfe99Dave Airlie */ 15254b39a0da89f5b07d4a24bc9ce52693e6c2acfe99Dave Airlie emit_arith( &p, OPCODE_MOV, out, WRITEMASK_XYZW, 0, cf, undef, undef ); 15264b39a0da89f5b07d4a24bc9ce52693e6c2acfe99Dave Airlie } 15274b39a0da89f5b07d4a24bc9ce52693e6c2acfe99Dave Airlie } 152847b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell /* Finish up: 152947b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell */ 15307e807510d8c3e88ee7ae6c697393201cf08f992fBrian Paul emit_arith( &p, OPCODE_END, undef, WRITEMASK_XYZW, 0, undef, undef, undef); 153147b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell 1532ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->fog_enabled) { 1533f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg /* Pull fog mode from struct gl_context, the value in the state key is 1534ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell * a reduced value and not what is expected in FogOption 1535ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell */ 1536276330b2412910777f7016f427909085f02acbb8Keith Whitwell p.program->FogOption = ctx->Fog.Mode; 1537457e427e32324884acb064b756e327dc131ff135Brian Paul p.program->Base.InputsRead |= FRAG_BIT_FOGC; 1538457e427e32324884acb064b756e327dc131ff135Brian Paul } 1539457e427e32324884acb064b756e327dc131ff135Brian Paul else { 1540276330b2412910777f7016f427909085f02acbb8Keith Whitwell p.program->FogOption = GL_NONE; 1541457e427e32324884acb064b756e327dc131ff135Brian Paul } 154247b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell 154321f99792a916a62fcfae7c208f50f192d4ce5926Brian if (p.program->Base.NumTexIndirections > ctx->Const.FragmentProgram.MaxTexIndirections) 154415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell program_error(&p, "Exceeded max nr indirect texture lookups"); 154515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 154621f99792a916a62fcfae7c208f50f192d4ce5926Brian if (p.program->Base.NumTexInstructions > ctx->Const.FragmentProgram.MaxTexInstructions) 154715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell program_error(&p, "Exceeded max TEX instructions"); 154815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 154921f99792a916a62fcfae7c208f50f192d4ce5926Brian if (p.program->Base.NumAluInstructions > ctx->Const.FragmentProgram.MaxAluInstructions) 155015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell program_error(&p, "Exceeded max ALU instructions"); 155115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 15525d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul ASSERT(p.program->Base.NumInstructions <= MAX_INSTRUCTIONS); 15538b88f62fbd62153500fc3483003f438561366a00Keith Whitwell 1554e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul /* Allocate final instruction array */ 1555c81cce78313a62e0d36a5c80bd9d35b770d0814aBrian p.program->Base.Instructions 1556c81cce78313a62e0d36a5c80bd9d35b770d0814aBrian = _mesa_alloc_instructions(p.program->Base.NumInstructions); 1557c81cce78313a62e0d36a5c80bd9d35b770d0814aBrian if (!p.program->Base.Instructions) { 1558e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul _mesa_error(ctx, GL_OUT_OF_MEMORY, 1559e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul "generating tex env program"); 1560e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul return; 1561e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul } 1562c81cce78313a62e0d36a5c80bd9d35b770d0814aBrian _mesa_copy_instructions(p.program->Base.Instructions, instBuffer, 1563c81cce78313a62e0d36a5c80bd9d35b770d0814aBrian p.program->Base.NumInstructions); 1564c81cce78313a62e0d36a5c80bd9d35b770d0814aBrian 15652fa6012f6a0b02de6093cbccba3bf4432f072e57Brian Paul if (key->num_draw_buffers && p.program->FogOption) { 1566c81cce78313a62e0d36a5c80bd9d35b770d0814aBrian _mesa_append_fog_code(ctx, p.program); 1567c81cce78313a62e0d36a5c80bd9d35b770d0814aBrian p.program->FogOption = GL_NONE; 1568c81cce78313a62e0d36a5c80bd9d35b770d0814aBrian } 1569c81cce78313a62e0d36a5c80bd9d35b770d0814aBrian 1570e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul 1571dbeea25bb834479a29712100888c862348112018Keith Whitwell /* Notify driver the fragment program has (actually) changed. 15728b88f62fbd62153500fc3483003f438561366a00Keith Whitwell */ 1573e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul if (ctx->Driver.ProgramStringNotify) { 15744ac9c80e5beea26e13ccf12ce6bd9ee051c229f5Brian Paul GLboolean ok = ctx->Driver.ProgramStringNotify(ctx, 15754ac9c80e5beea26e13ccf12ce6bd9ee051c229f5Brian Paul GL_FRAGMENT_PROGRAM_ARB, 15764ac9c80e5beea26e13ccf12ce6bd9ee051c229f5Brian Paul &p.program->Base); 15774ac9c80e5beea26e13ccf12ce6bd9ee051c229f5Brian Paul /* Driver should be able to handle any texenv programs as long as 15784ac9c80e5beea26e13ccf12ce6bd9ee051c229f5Brian Paul * the driver correctly reported max number of texture units correctly, 15794ac9c80e5beea26e13ccf12ce6bd9ee051c229f5Brian Paul * etc. 15804ac9c80e5beea26e13ccf12ce6bd9ee051c229f5Brian Paul */ 15814ac9c80e5beea26e13ccf12ce6bd9ee051c229f5Brian Paul ASSERT(ok); 15824ac9c80e5beea26e13ccf12ce6bd9ee051c229f5Brian Paul (void) ok; /* silence unused var warning */ 1583e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul } 1584e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul 1585e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul if (DISASSEM) { 1586e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul _mesa_print_program(&p.program->Base); 1587298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg printf("\n"); 1588dbeea25bb834479a29712100888c862348112018Keith Whitwell } 158915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 159015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1591cdacca4868bbfe2e39f72d524556e7b2c7200ba5Eric Anholtextern "C" { 15925d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul 159332ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell/** 159432ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell * Return a fragment program which implements the current 159532ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell * fixed-function texture, fog and color-sum operations. 159632ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell */ 159732ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwellstruct gl_fragment_program * 1598f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_get_fixed_func_fragment_program(struct gl_context *ctx) 1599ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 160032ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell struct gl_fragment_program *prog; 160132ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell struct state_key key; 16027a7d5879e28607c151132a8b6a07cf4be36b5b3eBrian Paul GLuint keySize; 160332ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell 16047a7d5879e28607c151132a8b6a07cf4be36b5b3eBrian Paul keySize = make_state_key(ctx, &key); 160532ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell 160632ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell prog = (struct gl_fragment_program *) 160732ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell _mesa_search_program_cache(ctx->FragmentProgram.Cache, 16087a7d5879e28607c151132a8b6a07cf4be36b5b3eBrian Paul &key, keySize); 1609ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 161032ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell if (!prog) { 161132ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell prog = (struct gl_fragment_program *) 161232ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0); 16135ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell 161432ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell create_new_program(ctx, &key, prog); 16155ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell 161632ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell _mesa_program_cache_insert(ctx, ctx->FragmentProgram.Cache, 16177a7d5879e28607c151132a8b6a07cf4be36b5b3eBrian Paul &key, keySize, &prog->Base); 16188065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell } 16198065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell 162032ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell return prog; 16218065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell} 1622cdacca4868bbfe2e39f72d524556e7b2c7200ba5Eric Anholt 1623cdacca4868bbfe2e39f72d524556e7b2c7200ba5Eric Anholt} 1624