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. 67ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt * Copyright © 2010-2011 Intel Corporation 715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a 915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * copy of this software and associated documentation files (the 1015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * "Software"), to deal in the Software without restriction, including 1115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * without limitation the rights to use, copy, modify, merge, publish, 1215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * distribute, sub license, and/or sell copies of the Software, and to 1315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * permit persons to whom the Software is furnished to do so, subject to 1415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * the following conditions: 1515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 1615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * The above copyright notice and this permission notice (including the 1715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * next paragraph) shall be included in all copies or substantial portions 1815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * of the Software. 1915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 2015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 2115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 2215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 2315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 2415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 2515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 2615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * 2815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell **************************************************************************/ 2915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 30cdacca4868bbfe2e39f72d524556e7b2c7200ba5Eric Anholtextern "C" { 3115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell#include "glheader.h" 3225e5a6f279cec0863dcc341805aa7ca71189b626Brian Paul#include "imports.h" 330117da40cd7edd3d165bb28569c289b37eca12b9Vinson Lee#include "mtypes.h" 347ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt#include "main/uniforms.h" 357ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt#include "main/macros.h" 36cae76368523b2dd25f26069b9872a8993384fa57Pauli Nieminen#include "main/samplerobj.h" 37ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/program.h" 38ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/prog_parameter.h" 39ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/prog_cache.h" 40ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/prog_instruction.h" 41ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/prog_print.h" 42ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/prog_statevars.h" 43ec2b92f98c2e7f161521b447cc1d9a36bce3707cBrian Paul#include "program/programopt.h" 4415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell#include "texenvprogram.h" 45cdacca4868bbfe2e39f72d524556e7b2c7200ba5Eric Anholt} 46f409a710e3562856a53a3b43ed526b877639a27cIan Romanick#include "main/uniforms.h" 477ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt#include "../glsl/glsl_types.h" 487ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt#include "../glsl/ir.h" 49599aac95ff2149d881177ed75a48d97d3dcf47bdEric Anholt#include "../glsl/ir_builder.h" 507ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt#include "../glsl/glsl_symbol_table.h" 517ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt#include "../glsl/glsl_parser_extras.h" 527ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt#include "../glsl/ir_optimization.h" 537ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt#include "../glsl/ir_print_visitor.h" 547ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt#include "../program/ir_to_mesa.h" 555b5c9315275752add1215dba0f86d5f5068d856bBrian Paul 56599aac95ff2149d881177ed75a48d97d3dcf47bdEric Anholtusing namespace ir_builder; 57599aac95ff2149d881177ed75a48d97d3dcf47bdEric Anholt 58e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul/* 59e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul * Note on texture units: 60e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul * 61e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul * The number of texture units supported by fixed-function fragment 62e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul * processing is MAX_TEXTURE_COORD_UNITS, not MAX_TEXTURE_IMAGE_UNITS. 63e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul * That's because there's a one-to-one correspondence between texture 64e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul * coordinates and samplers in fixed-function processing. 65e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul * 66e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul * Since fixed-function vertex processing is limited to MAX_TEXTURE_COORD_UNITS 67e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul * sets of texcoords, so is fixed-function fragment processing. 68e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul * 69e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul * We can safely use ctx->Const.MaxTextureUnits for loop bounds. 70e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul */ 71e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul 72e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul 735b5c9315275752add1215dba0f86d5f5068d856bBrian Paulstruct texenvprog_cache_item 745b5c9315275752add1215dba0f86d5f5068d856bBrian Paul{ 755b5c9315275752add1215dba0f86d5f5068d856bBrian Paul GLuint hash; 765b5c9315275752add1215dba0f86d5f5068d856bBrian Paul void *key; 777ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt struct gl_shader_program *data; 785b5c9315275752add1215dba0f86d5f5068d856bBrian Paul struct texenvprog_cache_item *next; 795b5c9315275752add1215dba0f86d5f5068d856bBrian Paul}; 805b5c9315275752add1215dba0f86d5f5068d856bBrian Paul 819cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholtstatic GLboolean 82f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergtexenv_doing_secondary_color(struct gl_context *ctx) 839cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt{ 849cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt if (ctx->Light.Enabled && 859cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) 869cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt return GL_TRUE; 879cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt 889cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt if (ctx->Fog.ColorSumEnabled) 899cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt return GL_TRUE; 909cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt 919cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt return GL_FALSE; 929cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt} 935b5c9315275752add1215dba0f86d5f5068d856bBrian Paul 94ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstruct mode_opt { 9583e4470d9a3367883b3fe699629f1d8648459a89Brian Paul#ifdef __GNUC__ 96d98b9f4edbbee1654b66c8df7b1deeb401b3dc5fGary Wong __extension__ GLubyte Source:4; /**< SRC_x */ 97d98b9f4edbbee1654b66c8df7b1deeb401b3dc5fGary Wong __extension__ GLubyte Operand:3; /**< OPR_x */ 9883e4470d9a3367883b3fe699629f1d8648459a89Brian Paul#else 995e809216a8d2e7ad093a1d25f3f6495f29e57572Brian Paul GLubyte Source; /**< SRC_x */ 1005e809216a8d2e7ad093a1d25f3f6495f29e57572Brian Paul GLubyte Operand; /**< OPR_x */ 10183e4470d9a3367883b3fe699629f1d8648459a89Brian Paul#endif 102ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell}; 103ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 104ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstruct state_key { 1056280e335706f95ed0ebb089d8f72aeede9b5a1adKeith Whitwell GLuint nr_enabled_units:8; 1066280e335706f95ed0ebb089d8f72aeede9b5a1adKeith Whitwell GLuint enabled_units:8; 1075d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint separate_specular:1; 1085d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint fog_enabled:1; 1099ed0315271c38f5fe9cdd65020a54cbb7f61ed2bBrian Paul GLuint fog_mode:2; /**< FOG_x */ 1106280e335706f95ed0ebb089d8f72aeede9b5a1adKeith Whitwell GLuint inputs_available:12; 111b6b9b17d27c570cc99ae339e595cf2f63ca5e8d7Brian Paul GLuint num_draw_buffers:4; 112ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 1137a7d5879e28607c151132a8b6a07cf4be36b5b3eBrian Paul /* NOTE: This array of structs must be last! (see "keySize" below) */ 114ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct { 1155d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint enabled:1; 1161ab1b15e9d0da1c5215a20770735b5477f5313dfChia-I Wu GLuint source_index:4; /**< TEXTURE_x_INDEX */ 11783ad2a756ea8dd1b0ca9746e355ce3de0f29356eNicolai Haehnle GLuint shadow:1; 1185d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint ScaleShiftRGB:2; 1195d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul GLuint ScaleShiftA:2; 120ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 1219ed0315271c38f5fe9cdd65020a54cbb7f61ed2bBrian Paul GLuint NumArgsRGB:3; /**< up to MAX_COMBINER_TERMS */ 122f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul GLuint ModeRGB:5; /**< MODE_x */ 123ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 1249ed0315271c38f5fe9cdd65020a54cbb7f61ed2bBrian Paul GLuint NumArgsA:3; /**< up to MAX_COMBINER_TERMS */ 125f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul GLuint ModeA:5; /**< MODE_x */ 126a46e32787d98192d35bf2834011cfa5537e0e703Chris Wilson 127a46e32787d98192d35bf2834011cfa5537e0e703Chris Wilson struct mode_opt OptRGB[MAX_COMBINER_TERMS]; 128bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul struct mode_opt OptA[MAX_COMBINER_TERMS]; 129d55a28e3dc712342e4a2f25aa9b661add7461e82Brian Paul } unit[MAX_TEXTURE_UNITS]; 130ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell}; 131ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 132ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define FOG_LINEAR 0 133ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define FOG_EXP 1 134ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define FOG_EXP2 2 135ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define FOG_UNKNOWN 3 136ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 137ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstatic GLuint translate_fog_mode( GLenum mode ) 138ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 139ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch (mode) { 140ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_LINEAR: return FOG_LINEAR; 141ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_EXP: return FOG_EXP; 142ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_EXP2: return FOG_EXP2; 143ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell default: return FOG_UNKNOWN; 144ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 145ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 146ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 147ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_SRC_COLOR 0 148ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_ONE_MINUS_SRC_COLOR 1 149ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_SRC_ALPHA 2 150ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_ONE_MINUS_SRC_ALPHA 3 151ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_ZERO 4 152ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_ONE 5 153ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define OPR_UNKNOWN 7 154ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 155ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstatic GLuint translate_operand( GLenum operand ) 156ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 157ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch (operand) { 158ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_SRC_COLOR: return OPR_SRC_COLOR; 159ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_ONE_MINUS_SRC_COLOR: return OPR_ONE_MINUS_SRC_COLOR; 160ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_SRC_ALPHA: return OPR_SRC_ALPHA; 161ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_ONE_MINUS_SRC_ALPHA: return OPR_ONE_MINUS_SRC_ALPHA; 162ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_ZERO: return OPR_ZERO; 163ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_ONE: return OPR_ONE; 1646947f85cb5fbc433ba7763530285e470745b009bBrian Paul default: 1656947f85cb5fbc433ba7763530285e470745b009bBrian Paul assert(0); 1666947f85cb5fbc433ba7763530285e470745b009bBrian Paul return OPR_UNKNOWN; 167ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 168ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 169ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 170ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE 0 171ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE0 1 172ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE1 2 173ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE2 3 174ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE3 4 175ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE4 5 176ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE5 6 177ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE6 7 178ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_TEXTURE7 8 179ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_CONSTANT 9 180ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_PRIMARY_COLOR 10 181ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_PREVIOUS 11 1826947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define SRC_ZERO 12 183ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell#define SRC_UNKNOWN 15 184ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 185ce721143b4d44d239baefe965e499606149b15cbKeith Whitwellstatic GLuint translate_source( GLenum src ) 186ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 187ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch (src) { 188ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE: return SRC_TEXTURE; 189ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE0: 190ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE1: 191ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE2: 192ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE3: 193ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE4: 194ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE5: 195ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE6: 196ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_TEXTURE7: return SRC_TEXTURE0 + (src - GL_TEXTURE0); 197ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_CONSTANT: return SRC_CONSTANT; 198ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_PRIMARY_COLOR: return SRC_PRIMARY_COLOR; 199ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_PREVIOUS: return SRC_PREVIOUS; 2006947f85cb5fbc433ba7763530285e470745b009bBrian Paul case GL_ZERO: 2016947f85cb5fbc433ba7763530285e470745b009bBrian Paul return SRC_ZERO; 2026947f85cb5fbc433ba7763530285e470745b009bBrian Paul default: 2036947f85cb5fbc433ba7763530285e470745b009bBrian Paul assert(0); 2046947f85cb5fbc433ba7763530285e470745b009bBrian Paul return SRC_UNKNOWN; 205ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 206ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 207ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 2086947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_REPLACE 0 /* r = a0 */ 2096947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_MODULATE 1 /* r = a0 * a1 */ 2106947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_ADD 2 /* r = a0 + a1 */ 2116947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_ADD_SIGNED 3 /* r = a0 + a1 - 0.5 */ 2126947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_INTERPOLATE 4 /* r = a0 * a2 + a1 * (1 - a2) */ 2136947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_SUBTRACT 5 /* r = a0 - a1 */ 2146947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_DOT3_RGB 6 /* r = a0 . a1 */ 2156947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_DOT3_RGB_EXT 7 /* r = a0 . a1 */ 2166947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_DOT3_RGBA 8 /* r = a0 . a1 */ 2176947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_DOT3_RGBA_EXT 9 /* r = a0 . a1 */ 2186947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_MODULATE_ADD_ATI 10 /* r = a0 * a2 + a1 */ 2196947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_MODULATE_SIGNED_ADD_ATI 11 /* r = a0 * a2 + a1 - 0.5 */ 2206947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_MODULATE_SUBTRACT_ATI 12 /* r = a0 * a2 - a1 */ 2216947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_ADD_PRODUCTS 13 /* r = a0 * a1 + a2 * a3 */ 2226947f85cb5fbc433ba7763530285e470745b009bBrian Paul#define MODE_ADD_PRODUCTS_SIGNED 14 /* r = a0 * a1 + a2 * a3 - 0.5 */ 223114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger#define MODE_BUMP_ENVMAP_ATI 15 /* special */ 224114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger#define MODE_UNKNOWN 16 2256947f85cb5fbc433ba7763530285e470745b009bBrian Paul 2266947f85cb5fbc433ba7763530285e470745b009bBrian Paul/** 2276947f85cb5fbc433ba7763530285e470745b009bBrian Paul * Translate GL combiner state into a MODE_x value 2286947f85cb5fbc433ba7763530285e470745b009bBrian Paul */ 2296947f85cb5fbc433ba7763530285e470745b009bBrian Paulstatic GLuint translate_mode( GLenum envMode, GLenum mode ) 230ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 231ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch (mode) { 232ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_REPLACE: return MODE_REPLACE; 233ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_MODULATE: return MODE_MODULATE; 2346947f85cb5fbc433ba7763530285e470745b009bBrian Paul case GL_ADD: 2356947f85cb5fbc433ba7763530285e470745b009bBrian Paul if (envMode == GL_COMBINE4_NV) 2366947f85cb5fbc433ba7763530285e470745b009bBrian Paul return MODE_ADD_PRODUCTS; 2376947f85cb5fbc433ba7763530285e470745b009bBrian Paul else 2386947f85cb5fbc433ba7763530285e470745b009bBrian Paul return MODE_ADD; 2396947f85cb5fbc433ba7763530285e470745b009bBrian Paul case GL_ADD_SIGNED: 2406947f85cb5fbc433ba7763530285e470745b009bBrian Paul if (envMode == GL_COMBINE4_NV) 2416947f85cb5fbc433ba7763530285e470745b009bBrian Paul return MODE_ADD_PRODUCTS_SIGNED; 2426947f85cb5fbc433ba7763530285e470745b009bBrian Paul else 2436947f85cb5fbc433ba7763530285e470745b009bBrian Paul return MODE_ADD_SIGNED; 244ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_INTERPOLATE: return MODE_INTERPOLATE; 245ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_SUBTRACT: return MODE_SUBTRACT; 246ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_DOT3_RGB: return MODE_DOT3_RGB; 247ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_DOT3_RGB_EXT: return MODE_DOT3_RGB_EXT; 248ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_DOT3_RGBA: return MODE_DOT3_RGBA; 249ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_DOT3_RGBA_EXT: return MODE_DOT3_RGBA_EXT; 250ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_MODULATE_ADD_ATI: return MODE_MODULATE_ADD_ATI; 251ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_MODULATE_SIGNED_ADD_ATI: return MODE_MODULATE_SIGNED_ADD_ATI; 252ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case GL_MODULATE_SUBTRACT_ATI: return MODE_MODULATE_SUBTRACT_ATI; 253114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger case GL_BUMP_ENVMAP_ATI: return MODE_BUMP_ENVMAP_ATI; 2546947f85cb5fbc433ba7763530285e470745b009bBrian Paul default: 2556947f85cb5fbc433ba7763530285e470745b009bBrian Paul assert(0); 2566947f85cb5fbc433ba7763530285e470745b009bBrian Paul return MODE_UNKNOWN; 257ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 258ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 259ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 260f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul 261f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul/** 262e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul * Do we need to clamp the results of the given texture env/combine mode? 263e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul * If the inputs to the mode are in [0,1] we don't always have to clamp 264e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul * the results. 265e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul */ 266e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paulstatic GLboolean 267e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paulneed_saturate( GLuint mode ) 268e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul{ 269e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul switch (mode) { 270e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul case MODE_REPLACE: 271e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul case MODE_MODULATE: 272e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul case MODE_INTERPOLATE: 273e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul return GL_FALSE; 274e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul case MODE_ADD: 275e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul case MODE_ADD_SIGNED: 276e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul case MODE_SUBTRACT: 277e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul case MODE_DOT3_RGB: 278e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul case MODE_DOT3_RGB_EXT: 279e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul case MODE_DOT3_RGBA: 280e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul case MODE_DOT3_RGBA_EXT: 281e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul case MODE_MODULATE_ADD_ATI: 282e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul case MODE_MODULATE_SIGNED_ADD_ATI: 283e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul case MODE_MODULATE_SUBTRACT_ATI: 284e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul case MODE_ADD_PRODUCTS: 285e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul case MODE_ADD_PRODUCTS_SIGNED: 286e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul case MODE_BUMP_ENVMAP_ATI: 287e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul return GL_TRUE; 288e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul default: 289e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul assert(0); 290a491e25b1fa8683f538ed0d67a6389f2cdf7e4bcBrian Paul return GL_FALSE; 291e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul } 292e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul} 293e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul 294e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul 295e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul 296e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul/** 297f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul * Translate TEXTURE_x_BIT to TEXTURE_x_INDEX. 298f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul */ 299e00ac11d4dd05c56584622dc2707bbdcfe4b2707Brian Paulstatic GLuint translate_tex_src_bit( GLbitfield bit ) 300ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 301b5ec0a68589c5d8f0d4be2556ea6d6b01fd4e37dBrian Paul ASSERT(bit); 3029a548c27aa704236cc1d8a5d4ebf68cea9c5c99cBrian Paul return ffs(bit) - 1; 303ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 304ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 305f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul 3061680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell#define VERT_BIT_TEX_ANY (0xff << VERT_ATTRIB_TEX0) 3071680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell#define VERT_RESULT_TEX_ANY (0xff << VERT_RESULT_TEX0) 3081680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 309239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul/** 310239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul * Identify all possible varying inputs. The fragment program will 3111680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * never reference non-varying inputs, but will track them via state 3121680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * constants instead. 3131680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * 3141680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * This function figures out all the inputs that the fragment program 3151680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * has access to. The bitmask is later reduced to just those which 3161680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * are actually referenced. 3171680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell */ 318f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic GLbitfield get_fp_input_mask( struct gl_context *ctx ) 3191680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell{ 320e5f63c403b767f9974e8eb5d412c012b8a69287fEric Anholt /* _NEW_PROGRAM */ 32184eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick const GLboolean vertexShader = 32284eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick (ctx->Shader.CurrentVertexProgram && 32384eba3ef71dfa822e5ff0463032cdd2e3515b888Ian Romanick ctx->Shader.CurrentVertexProgram->LinkStatus && 324010cc547ca8c1fb2107106b0ad0de560780ce9aaIan Romanick ctx->Shader.CurrentVertexProgram->_LinkedShaders[MESA_SHADER_VERTEX]); 325f0b0794b3885a2fdfb168ec4521c7b5e942d3228Brian Paul const GLboolean vertexProgram = ctx->VertexProgram._Enabled; 326239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul GLbitfield fp_inputs = 0x0; 3271680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 3286d4d51d647c27288aa625560bc080231099c0b01Brian Paul if (ctx->VertexProgram._Overriden) { 3296d4d51d647c27288aa625560bc080231099c0b01Brian Paul /* Somebody's messing with the vertex program and we don't have 3306d4d51d647c27288aa625560bc080231099c0b01Brian Paul * a clue what's happening. Assume that it could be producing 3316d4d51d647c27288aa625560bc080231099c0b01Brian Paul * all possible outputs. 3326d4d51d647c27288aa625560bc080231099c0b01Brian Paul */ 3336d4d51d647c27288aa625560bc080231099c0b01Brian Paul fp_inputs = ~0; 3346d4d51d647c27288aa625560bc080231099c0b01Brian Paul } 3356d4d51d647c27288aa625560bc080231099c0b01Brian Paul else if (ctx->RenderMode == GL_FEEDBACK) { 336e5f63c403b767f9974e8eb5d412c012b8a69287fEric Anholt /* _NEW_RENDERMODE */ 3376d4d51d647c27288aa625560bc080231099c0b01Brian Paul fp_inputs = (FRAG_BIT_COL0 | FRAG_BIT_TEX0); 3386d4d51d647c27288aa625560bc080231099c0b01Brian Paul } 339ef1854d09021b6601e59e39fcb71a88fb5e5efb2Eric Anholt else if (!(vertexProgram || vertexShader)) { 340f0b0794b3885a2fdfb168ec4521c7b5e942d3228Brian Paul /* Fixed function vertex logic */ 341576c8c592a4be7047a00b0c8fe3851b09f10d8d4Marek Olšák /* _NEW_VARYING_VP_INPUTS */ 342dca6a28a14f22d77273d79d44f57b0d853c0242dMathias Fröhlich GLbitfield64 varying_inputs = ctx->varying_vp_inputs; 3431680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 34497e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell /* These get generated in the setup routine regardless of the 34597e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell * vertex program: 34697e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell */ 347e5f63c403b767f9974e8eb5d412c012b8a69287fEric Anholt /* _NEW_POINT */ 34897e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell if (ctx->Point.PointSprite) 34997e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell varying_inputs |= FRAG_BITS_TEX_ANY; 35097e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell 3511680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell /* First look at what values may be computed by the generated 3521680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * vertex program: 3531680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell */ 354e5f63c403b767f9974e8eb5d412c012b8a69287fEric Anholt /* _NEW_LIGHT */ 3551680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell if (ctx->Light.Enabled) { 3561680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell fp_inputs |= FRAG_BIT_COL0; 3571680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 3589cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt if (texenv_doing_secondary_color(ctx)) 3591680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell fp_inputs |= FRAG_BIT_COL1; 3601680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell } 3611680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 362e5f63c403b767f9974e8eb5d412c012b8a69287fEric Anholt /* _NEW_TEXTURE */ 3631680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell fp_inputs |= (ctx->Texture._TexGenEnabled | 3641680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell ctx->Texture._TexMatEnabled) << FRAG_ATTRIB_TEX0; 3651680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 3661680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell /* Then look at what might be varying as a result of enabled 3671680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell * arrays, etc: 3681680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell */ 3696807d96f8efeecd9d71e1e1bff856e7e04f5f364Brian Paul if (varying_inputs & VERT_BIT_COLOR0) 3706807d96f8efeecd9d71e1e1bff856e7e04f5f364Brian Paul fp_inputs |= FRAG_BIT_COL0; 3716807d96f8efeecd9d71e1e1bff856e7e04f5f364Brian Paul if (varying_inputs & VERT_BIT_COLOR1) 3726807d96f8efeecd9d71e1e1bff856e7e04f5f364Brian Paul fp_inputs |= FRAG_BIT_COL1; 3731680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 3741680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell fp_inputs |= (((varying_inputs & VERT_BIT_TEX_ANY) >> VERT_ATTRIB_TEX0) 3751680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell << FRAG_ATTRIB_TEX0); 3761680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 3771680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell } 3781680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell else { 3791680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell /* calculate from vp->outputs */ 380010cc547ca8c1fb2107106b0ad0de560780ce9aaIan Romanick struct gl_program *vprog; 3815606dfb572bf4b89b4882265924705bacc8c182bIan Romanick GLbitfield64 vp_outputs; 3822389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul 3832389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul /* Choose GLSL vertex shader over ARB vertex program. Need this 3842389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul * since vertex shader state validation comes after fragment state 3852389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul * validation (see additional comments in state.c). 3862389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul */ 3872389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul if (vertexShader) 388010cc547ca8c1fb2107106b0ad0de560780ce9aaIan Romanick vprog = ctx->Shader.CurrentVertexProgram->_LinkedShaders[MESA_SHADER_VERTEX]->Program; 3892389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul else 390010cc547ca8c1fb2107106b0ad0de560780ce9aaIan Romanick vprog = &ctx->VertexProgram.Current->Base; 3912389c055ed4c26ba5f3979c4a7871a333725dd88Brian Paul 392010cc547ca8c1fb2107106b0ad0de560780ce9aaIan Romanick vp_outputs = vprog->OutputsWritten; 3931680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 39497e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell /* These get generated in the setup routine regardless of the 39597e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell * vertex program: 39697e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell */ 397e5f63c403b767f9974e8eb5d412c012b8a69287fEric Anholt /* _NEW_POINT */ 39897e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell if (ctx->Point.PointSprite) 39997e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell vp_outputs |= FRAG_BITS_TEX_ANY; 40097e63437dc216c7fdb25220655ecbf26042cfec8Keith Whitwell 4016807d96f8efeecd9d71e1e1bff856e7e04f5f364Brian Paul if (vp_outputs & (1 << VERT_RESULT_COL0)) 4026807d96f8efeecd9d71e1e1bff856e7e04f5f364Brian Paul fp_inputs |= FRAG_BIT_COL0; 4036807d96f8efeecd9d71e1e1bff856e7e04f5f364Brian Paul if (vp_outputs & (1 << VERT_RESULT_COL1)) 4046807d96f8efeecd9d71e1e1bff856e7e04f5f364Brian Paul fp_inputs |= FRAG_BIT_COL1; 4051680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 4060370d6b359016790c6b879c2a4b6661adac20deaKeith Whitwell fp_inputs |= (((vp_outputs & VERT_RESULT_TEX_ANY) >> VERT_RESULT_TEX0) 4070370d6b359016790c6b879c2a4b6661adac20deaKeith Whitwell << FRAG_ATTRIB_TEX0); 4081680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell } 4091680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 4101680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell return fp_inputs; 4111680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell} 4121680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 4131680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 41422db53577603afef8fdf62c324ff5977de76b9d8Brian Paul/** 41522db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * Examine current texture environment state and generate a unique 41622db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * key to identify it. 41722db53577603afef8fdf62c324ff5977de76b9d8Brian Paul */ 418f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergstatic GLuint make_state_key( struct gl_context *ctx, struct state_key *key ) 419ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 420ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell GLuint i, j; 421239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul GLbitfield inputs_referenced = FRAG_BIT_COL0; 422f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul const GLbitfield inputs_available = get_fp_input_mask( ctx ); 4237a7d5879e28607c151132a8b6a07cf4be36b5b3eBrian Paul GLuint keySize; 4241680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 4258065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell memset(key, 0, sizeof(*key)); 4268065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell 427e5f63c403b767f9974e8eb5d412c012b8a69287fEric Anholt /* _NEW_TEXTURE */ 428e9b34885b8ff2ccb67a801cd1ce07e0df1b0e397Brian Paul for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { 429d9736db6676948e06712d4bcba46b7040452f870Brian Paul const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i]; 430f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul const struct gl_texture_object *texObj = texUnit->_Current; 431f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul const struct gl_tex_env_combine_state *comb = texUnit->_CurrentCombine; 432cae76368523b2dd25f26069b9872a8993384fa57Pauli Nieminen const struct gl_sampler_object *samp; 433b6bb5e09e0ad1f61f96c65bbc870bd493df12f1aXiang, Haihao GLenum format; 434bf4a0fafc86bba8dc868cf30244a237e33645164Roland Scheidegger 435bf4a0fafc86bba8dc868cf30244a237e33645164Roland Scheidegger if (!texUnit->_ReallyEnabled || !texUnit->Enabled) 436ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell continue; 437ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 438cae76368523b2dd25f26069b9872a8993384fa57Pauli Nieminen samp = _mesa_get_samplerobj(ctx, i); 439f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul format = texObj->Image[0][texObj->BaseLevel]->_BaseFormat; 440b6bb5e09e0ad1f61f96c65bbc870bd493df12f1aXiang, Haihao 441ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].enabled = 1; 442ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->enabled_units |= (1<<i); 4437a7d5879e28607c151132a8b6a07cf4be36b5b3eBrian Paul key->nr_enabled_units = i + 1; 4441680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell inputs_referenced |= FRAG_BIT_TEX(i); 445ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 446f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul key->unit[i].source_index = 447f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul translate_tex_src_bit(texUnit->_ReallyEnabled); 448f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul 449ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul key->unit[i].shadow = 450cae76368523b2dd25f26069b9872a8993384fa57Pauli Nieminen ((samp->CompareMode == GL_COMPARE_R_TO_TEXTURE) && 451ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul ((format == GL_DEPTH_COMPONENT) || 452ecfaab88b2577bd0395bc05d75a036126806a9c4Brian Paul (format == GL_DEPTH_STENCIL_EXT))); 453ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 454f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul key->unit[i].NumArgsRGB = comb->_NumArgsRGB; 455f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul key->unit[i].NumArgsA = comb->_NumArgsA; 456ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 457ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].ModeRGB = 458f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul translate_mode(texUnit->EnvMode, comb->ModeRGB); 459ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->unit[i].ModeA = 460f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul translate_mode(texUnit->EnvMode, comb->ModeA); 461114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 462f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul key->unit[i].ScaleShiftRGB = comb->ScaleShiftRGB; 463f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul key->unit[i].ScaleShiftA = comb->ScaleShiftA; 464ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 465bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul for (j = 0; j < MAX_COMBINER_TERMS; j++) { 466f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul key->unit[i].OptRGB[j].Operand = translate_operand(comb->OperandRGB[j]); 467f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul key->unit[i].OptA[j].Operand = translate_operand(comb->OperandA[j]); 468f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul key->unit[i].OptRGB[j].Source = translate_source(comb->SourceRGB[j]); 469f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul key->unit[i].OptA[j].Source = translate_source(comb->SourceA[j]); 470ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 471114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 472114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger if (key->unit[i].ModeRGB == MODE_BUMP_ENVMAP_ATI) { 473114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger /* requires some special translation */ 474114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger key->unit[i].NumArgsRGB = 2; 475114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger key->unit[i].ScaleShiftRGB = 0; 476114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger key->unit[i].OptRGB[0].Operand = OPR_SRC_COLOR; 477114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger key->unit[i].OptRGB[0].Source = SRC_TEXTURE; 478114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger key->unit[i].OptRGB[1].Operand = OPR_SRC_COLOR; 479114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger key->unit[i].OptRGB[1].Source = texUnit->BumpTarget - GL_TEXTURE0 + SRC_TEXTURE0; 480114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger } 481ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 482114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 4839cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt /* _NEW_LIGHT | _NEW_FOG */ 4849cea84b6b5f96bf3bb42546e49b76024d7126e30Eric Anholt if (texenv_doing_secondary_color(ctx)) { 485ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->separate_specular = 1; 4861680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell inputs_referenced |= FRAG_BIT_COL1; 4871680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell } 488ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 489e5f63c403b767f9974e8eb5d412c012b8a69287fEric Anholt /* _NEW_FOG */ 490ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (ctx->Fog.Enabled) { 491ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->fog_enabled = 1; 492ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell key->fog_mode = translate_fog_mode(ctx->Fog.Mode); 4931680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell inputs_referenced |= FRAG_BIT_FOGC; /* maybe */ 494ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell } 4951680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell 496b6b9b17d27c570cc99ae339e595cf2f63ca5e8d7Brian Paul /* _NEW_BUFFERS */ 497b6b9b17d27c570cc99ae339e595cf2f63ca5e8d7Brian Paul key->num_draw_buffers = ctx->DrawBuffer->_NumColorDrawBuffers; 498b6b9b17d27c570cc99ae339e595cf2f63ca5e8d7Brian Paul 499e68994494b159d4f44e34b6b6c1d489a184a2dfeBrian Paul /* _NEW_COLOR */ 500e68994494b159d4f44e34b6b6c1d489a184a2dfeBrian Paul if (ctx->Color.AlphaEnabled && key->num_draw_buffers == 0) { 501e68994494b159d4f44e34b6b6c1d489a184a2dfeBrian Paul /* if alpha test is enabled we need to emit at least one color */ 502e68994494b159d4f44e34b6b6c1d489a184a2dfeBrian Paul key->num_draw_buffers = 1; 503e68994494b159d4f44e34b6b6c1d489a184a2dfeBrian Paul } 504e68994494b159d4f44e34b6b6c1d489a184a2dfeBrian Paul 5051680ef869625dc1fe9cf481b180382a34e0738e7Keith Whitwell key->inputs_available = (inputs_available & inputs_referenced); 5067a7d5879e28607c151132a8b6a07cf4be36b5b3eBrian Paul 5077a7d5879e28607c151132a8b6a07cf4be36b5b3eBrian Paul /* compute size of state key, ignoring unused texture units */ 5087a7d5879e28607c151132a8b6a07cf4be36b5b3eBrian Paul keySize = sizeof(*key) - sizeof(key->unit) 5097a7d5879e28607c151132a8b6a07cf4be36b5b3eBrian Paul + key->nr_enabled_units * sizeof(key->unit[0]); 5107a7d5879e28607c151132a8b6a07cf4be36b5b3eBrian Paul 5117a7d5879e28607c151132a8b6a07cf4be36b5b3eBrian Paul return keySize; 512ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell} 513ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 5147a7d5879e28607c151132a8b6a07cf4be36b5b3eBrian Paul 515239617fbe22d4dd7b2794510a6665f09602b5adfBrian Paul/** State used to build the fragment program: 51615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 5177e88f8ce8f9d72bbda248554e0630b4aca7e1154Eric Anholtclass texenv_fragment_program : public ir_factory { 5187e88f8ce8f9d72bbda248554e0630b4aca7e1154Eric Anholtpublic: 5197ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt struct gl_shader_program *shader_program; 5207ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt struct gl_shader *shader; 5217ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt exec_list *top_instructions; 522ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell struct state_key *state; 52315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 5247ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_variable *src_texture[MAX_TEXTURE_COORD_UNITS]; 525ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell /* Reg containing each texture unit's sampled texture color, 526ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell * else undef. 527ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell */ 52815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 5297ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt /* Texcoord override from bumpmapping. */ 530decd018b992eb0f7f85338ee39083daca04885b6Brian Paul ir_variable *texcoord_tex[MAX_TEXTURE_COORD_UNITS]; 5317ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 532114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger /* Reg containing texcoord for a texture unit, 533114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger * needed for bump mapping, else undef. 534114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger */ 535114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 5367ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_rvalue *src_previous; /**< Reg containing color from previous 53715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * stage. May need to be decl'd. 53815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 53915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell}; 54015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 5417ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholtstatic ir_rvalue * 5427ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholtget_current_attrib(struct texenv_fragment_program *p, GLuint attrib) 543098f9c5325de16bfb5bf8b0e93e0ec1871db4a76Eric Anholt{ 5447ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_variable *current; 5457ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_rvalue *val; 5467ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 5477ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt current = p->shader->symbols->get_variable("gl_CurrentAttribFragMESA"); 5487ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt current->max_array_access = MAX2(current->max_array_access, attrib); 5497ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt val = new(p->mem_ctx) ir_dereference_variable(current); 5507ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_rvalue *index = new(p->mem_ctx) ir_constant(attrib); 5517ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt return new(p->mem_ctx) ir_dereference_array(val, index); 552098f9c5325de16bfb5bf8b0e93e0ec1871db4a76Eric Anholt} 553098f9c5325de16bfb5bf8b0e93e0ec1871db4a76Eric Anholt 5547ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholtstatic ir_rvalue * 5557ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholtget_gl_Color(struct texenv_fragment_program *p) 556098f9c5325de16bfb5bf8b0e93e0ec1871db4a76Eric Anholt{ 5577ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt if (p->state->inputs_available & FRAG_BIT_COL0) { 5587ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_variable *var = p->shader->symbols->get_variable("gl_Color"); 5597ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt assert(var); 5607ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt return new(p->mem_ctx) ir_dereference_variable(var); 5617ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt } else { 5627ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt return get_current_attrib(p, VERT_ATTRIB_COLOR0); 563098f9c5325de16bfb5bf8b0e93e0ec1871db4a76Eric Anholt } 564098f9c5325de16bfb5bf8b0e93e0ec1871db4a76Eric Anholt} 565098f9c5325de16bfb5bf8b0e93e0ec1871db4a76Eric Anholt 5667ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholtstatic ir_rvalue * 5677ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholtget_source(struct texenv_fragment_program *p, 5687ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt GLuint src, GLuint unit) 569098f9c5325de16bfb5bf8b0e93e0ec1871db4a76Eric Anholt{ 5707ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_variable *var; 5717ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_dereference *deref; 572098f9c5325de16bfb5bf8b0e93e0ec1871db4a76Eric Anholt 57315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell switch (src) { 574ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE: 5757ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt return new(p->mem_ctx) ir_dereference_variable(p->src_texture[unit]); 57615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 577ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE0: 578ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE1: 579ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE2: 580ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE3: 581ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE4: 582ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE5: 583ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE6: 584ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE7: 5857ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt return new(p->mem_ctx) 5867ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_dereference_variable(p->src_texture[src - SRC_TEXTURE0]); 587ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 588ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_CONSTANT: 5897ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt var = p->shader->symbols->get_variable("gl_TextureEnvColor"); 5907ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt assert(var); 5917ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt deref = new(p->mem_ctx) ir_dereference_variable(var); 5927ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt var->max_array_access = MAX2(var->max_array_access, unit); 5937ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt return new(p->mem_ctx) ir_dereference_array(deref, 5947ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt new(p->mem_ctx) ir_constant(unit)); 5952dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 596ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_PRIMARY_COLOR: 5977ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt var = p->shader->symbols->get_variable("gl_Color"); 5987ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt assert(var); 5997ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt return new(p->mem_ctx) ir_dereference_variable(var); 6002dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 6016947f85cb5fbc433ba7763530285e470745b009bBrian Paul case SRC_ZERO: 6027ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt return new(p->mem_ctx) ir_constant(0.0f); 6036947f85cb5fbc433ba7763530285e470745b009bBrian Paul 604ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_PREVIOUS: 6057ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt if (!p->src_previous) { 6067ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt return get_gl_Color(p); 6077ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt } else { 6087ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt return p->src_previous->clone(p->mem_ctx, NULL); 6097ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt } 6106947f85cb5fbc433ba7763530285e470745b009bBrian Paul 6116947f85cb5fbc433ba7763530285e470745b009bBrian Paul default: 6126947f85cb5fbc433ba7763530285e470745b009bBrian Paul assert(0); 6137ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt return NULL; 61415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 61515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 6162dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 6177ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholtstatic ir_rvalue * 6187ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholtemit_combine_source(struct texenv_fragment_program *p, 6197ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt GLuint unit, 6207ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt GLuint source, 6217ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt GLuint operand) 62215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 6237ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_rvalue *src; 62415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 62515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell src = get_source(p, source, unit); 62615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 62715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell switch (operand) { 628ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE_MINUS_SRC_COLOR: 629599aac95ff2149d881177ed75a48d97d3dcf47bdEric Anholt return sub(new(p->mem_ctx) ir_constant(1.0f), src); 63015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 6314535874c1a6da74d9130e494d514284302e4d08eIan Romanick case OPR_SRC_ALPHA: 632b782352745d322596a9122969f5c0e57ea032c1bEric Anholt return src->type->is_scalar() ? src : swizzle_w(src); 6334535874c1a6da74d9130e494d514284302e4d08eIan Romanick 6344535874c1a6da74d9130e494d514284302e4d08eIan Romanick case OPR_ONE_MINUS_SRC_ALPHA: { 635b782352745d322596a9122969f5c0e57ea032c1bEric Anholt ir_rvalue *const scalar = src->type->is_scalar() ? src : swizzle_w(src); 6367ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 637599aac95ff2149d881177ed75a48d97d3dcf47bdEric Anholt return sub(new(p->mem_ctx) ir_constant(1.0f), scalar); 6384535874c1a6da74d9130e494d514284302e4d08eIan Romanick } 6394535874c1a6da74d9130e494d514284302e4d08eIan Romanick 640ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ZERO: 6417ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt return new(p->mem_ctx) ir_constant(0.0f); 642ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE: 6437ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt return new(p->mem_ctx) ir_constant(1.0f); 644ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_SRC_COLOR: 6456947f85cb5fbc433ba7763530285e470745b009bBrian Paul return src; 64615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 6476947f85cb5fbc433ba7763530285e470745b009bBrian Paul assert(0); 64815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return src; 64915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 65015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 65115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 652f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul/** 653f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul * Check if the RGB and Alpha sources and operands match for the given 654f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul * texture unit's combinder state. When the RGB and A sources and 655f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul * operands match, we can emit fewer instructions. 656f337e2c4954b4779dcf2c2b4e0e068cb3ed7b841Brian Paul */ 657a5e7003565a021ceb82a8b16f4a0ecc7cc6c02e0Brian Paulstatic GLboolean args_match( const struct state_key *key, GLuint unit ) 65815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 6599ed0315271c38f5fe9cdd65020a54cbb7f61ed2bBrian Paul GLuint i, numArgs = key->unit[unit].NumArgsRGB; 66015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 661457e427e32324884acb064b756e327dc131ff135Brian Paul for (i = 0; i < numArgs; i++) { 662ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->unit[unit].OptA[i].Source != key->unit[unit].OptRGB[i].Source) 66315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return GL_FALSE; 66415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 6659ed0315271c38f5fe9cdd65020a54cbb7f61ed2bBrian Paul switch (key->unit[unit].OptA[i].Operand) { 666ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_SRC_ALPHA: 6679ed0315271c38f5fe9cdd65020a54cbb7f61ed2bBrian Paul switch (key->unit[unit].OptRGB[i].Operand) { 668ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_SRC_COLOR: 669ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_SRC_ALPHA: 67015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 67115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 67215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return GL_FALSE; 67315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 67415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 675ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE_MINUS_SRC_ALPHA: 6769ed0315271c38f5fe9cdd65020a54cbb7f61ed2bBrian Paul switch (key->unit[unit].OptRGB[i].Operand) { 677ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE_MINUS_SRC_COLOR: 678ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case OPR_ONE_MINUS_SRC_ALPHA: 67915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 68015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 68115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return GL_FALSE; 68215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 68315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 68415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 68515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return GL_FALSE; /* impossible */ 68615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 68715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 68815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 68915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return GL_TRUE; 69015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 69115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 6927ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholtstatic ir_rvalue * 6937ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholtsmear(struct texenv_fragment_program *p, ir_rvalue *val) 6947ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt{ 6957ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt if (!val->type->is_scalar()) 6967ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt return val; 6977ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 698b782352745d322596a9122969f5c0e57ea032c1bEric Anholt return swizzle_xxxx(val); 6997ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt} 7007ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 7017ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholtstatic ir_rvalue * 7027ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholtemit_combine(struct texenv_fragment_program *p, 7037ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt GLuint unit, 7047ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt GLuint nr, 7057ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt GLuint mode, 7067ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt const struct mode_opt *opt) 707ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 7087ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_rvalue *src[MAX_COMBINER_TERMS]; 7097ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_rvalue *tmp0, *tmp1; 71022db53577603afef8fdf62c324ff5977de76b9d8Brian Paul GLuint i; 71115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 712bd9b2be8284fda3f8aac235908ded118b5648a38Brian Paul assert(nr <= MAX_COMBINER_TERMS); 7136947f85cb5fbc433ba7763530285e470745b009bBrian Paul 71415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell for (i = 0; i < nr; i++) 7157ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt src[i] = emit_combine_source( p, unit, opt[i].Source, opt[i].Operand ); 71615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 71715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell switch (mode) { 718ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_REPLACE: 7197ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt return src[0]; 7207ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 721ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_MODULATE: 722599aac95ff2149d881177ed75a48d97d3dcf47bdEric Anholt return mul(src[0], src[1]); 7237ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 724ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_ADD: 725599aac95ff2149d881177ed75a48d97d3dcf47bdEric Anholt return add(src[0], src[1]); 7267ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 727ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_ADD_SIGNED: 728599aac95ff2149d881177ed75a48d97d3dcf47bdEric Anholt return add(add(src[0], src[1]), new(p->mem_ctx) ir_constant(-0.5f)); 7297ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 730ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_INTERPOLATE: 7317ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt /* Arg0 * (Arg2) + Arg1 * (1-Arg2) */ 732599aac95ff2149d881177ed75a48d97d3dcf47bdEric Anholt tmp0 = mul(src[0], src[2]); 733599aac95ff2149d881177ed75a48d97d3dcf47bdEric Anholt tmp1 = mul(src[1], sub(new(p->mem_ctx) ir_constant(1.0f), 734599aac95ff2149d881177ed75a48d97d3dcf47bdEric Anholt src[2]->clone(p->mem_ctx, NULL))); 735599aac95ff2149d881177ed75a48d97d3dcf47bdEric Anholt return add(tmp0, tmp1); 73615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 737ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_SUBTRACT: 738599aac95ff2149d881177ed75a48d97d3dcf47bdEric Anholt return sub(src[0], src[1]); 73915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 740ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGBA: 741ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGBA_EXT: 742ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGB_EXT: 743ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGB: { 744599aac95ff2149d881177ed75a48d97d3dcf47bdEric Anholt tmp0 = mul(src[0], new(p->mem_ctx) ir_constant(2.0f)); 745599aac95ff2149d881177ed75a48d97d3dcf47bdEric Anholt tmp0 = add(tmp0, new(p->mem_ctx) ir_constant(-1.0f)); 7467ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 747599aac95ff2149d881177ed75a48d97d3dcf47bdEric Anholt tmp1 = mul(src[1], new(p->mem_ctx) ir_constant(2.0f)); 748599aac95ff2149d881177ed75a48d97d3dcf47bdEric Anholt tmp1 = add(tmp1, new(p->mem_ctx) ir_constant(-1.0f)); 7497ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 750b782352745d322596a9122969f5c0e57ea032c1bEric Anholt return dot(swizzle_xyz(smear(p, tmp0)), swizzle_xyz(smear(p, tmp1))); 751098f9c5325de16bfb5bf8b0e93e0ec1871db4a76Eric Anholt } 752098f9c5325de16bfb5bf8b0e93e0ec1871db4a76Eric Anholt case MODE_MODULATE_ADD_ATI: 753599aac95ff2149d881177ed75a48d97d3dcf47bdEric Anholt return add(mul(src[0], src[2]), src[1]); 7547ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 7557ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt case MODE_MODULATE_SIGNED_ADD_ATI: 756599aac95ff2149d881177ed75a48d97d3dcf47bdEric Anholt return add(add(mul(src[0], src[2]), src[1]), 757599aac95ff2149d881177ed75a48d97d3dcf47bdEric Anholt new(p->mem_ctx) ir_constant(-0.5f)); 7587ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 759ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_MODULATE_SUBTRACT_ATI: 760599aac95ff2149d881177ed75a48d97d3dcf47bdEric Anholt return sub(mul(src[0], src[2]), src[1]); 7617ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 7626947f85cb5fbc433ba7763530285e470745b009bBrian Paul case MODE_ADD_PRODUCTS: 763599aac95ff2149d881177ed75a48d97d3dcf47bdEric Anholt return add(mul(src[0], src[1]), mul(src[2], src[3])); 7647ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 7656947f85cb5fbc433ba7763530285e470745b009bBrian Paul case MODE_ADD_PRODUCTS_SIGNED: 766599aac95ff2149d881177ed75a48d97d3dcf47bdEric Anholt return add(add(mul(src[0], src[1]), mul(src[2], src[3])), 767599aac95ff2149d881177ed75a48d97d3dcf47bdEric Anholt new(p->mem_ctx) ir_constant(-0.5f)); 7687ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 769114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger case MODE_BUMP_ENVMAP_ATI: 770114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger /* special - not handled here */ 771114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger assert(0); 772114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger return src[0]; 77315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 7746947f85cb5fbc433ba7763530285e470745b009bBrian Paul assert(0); 77515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell return src[0]; 77615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 77715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 77815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 77922db53577603afef8fdf62c324ff5977de76b9d8Brian Paul/** 78022db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * Generate instructions for one texture unit's env/combiner mode. 78122db53577603afef8fdf62c324ff5977de76b9d8Brian Paul */ 7827ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholtstatic ir_rvalue * 78322db53577603afef8fdf62c324ff5977de76b9d8Brian Paulemit_texenv(struct texenv_fragment_program *p, GLuint unit) 78415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 785a5e7003565a021ceb82a8b16f4a0ecc7cc6c02e0Brian Paul const struct state_key *key = p->state; 786e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul GLboolean rgb_saturate, alpha_saturate; 78715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell GLuint rgb_shift, alpha_shift; 78815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 789ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (!key->unit[unit].enabled) { 790ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell return get_source(p, SRC_PREVIOUS, 0); 79115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 792114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger if (key->unit[unit].ModeRGB == MODE_BUMP_ENVMAP_ATI) { 793114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger /* this isn't really a env stage delivering a color and handled elsewhere */ 794114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger return get_source(p, SRC_PREVIOUS, 0); 795114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger } 796ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 797ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell switch (key->unit[unit].ModeRGB) { 798ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGB_EXT: 799ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell alpha_shift = key->unit[unit].ScaleShiftA; 80015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell rgb_shift = 0; 80115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 802ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case MODE_DOT3_RGBA_EXT: 80315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell alpha_shift = 0; 80415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell rgb_shift = 0; 80515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 80615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell default: 807ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell rgb_shift = key->unit[unit].ScaleShiftRGB; 808ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell alpha_shift = key->unit[unit].ScaleShiftA; 80915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell break; 81015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 811ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 812956e6c3978abe918348377cf05e5c92971e50d3fBrian Paul /* If we'll do rgb/alpha shifting don't saturate in emit_combine(). 813956e6c3978abe918348377cf05e5c92971e50d3fBrian Paul * We don't want to clamp twice. 814956e6c3978abe918348377cf05e5c92971e50d3fBrian Paul */ 815e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul if (rgb_shift) 816e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul rgb_saturate = GL_FALSE; /* saturate after rgb shift */ 817e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul else if (need_saturate(key->unit[unit].ModeRGB)) 818e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul rgb_saturate = GL_TRUE; 819e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul else 820e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul rgb_saturate = GL_FALSE; 821e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul 822e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul if (alpha_shift) 823e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul alpha_saturate = GL_FALSE; /* saturate after alpha shift */ 824e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul else if (need_saturate(key->unit[unit].ModeA)) 825e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul alpha_saturate = GL_TRUE; 826e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul else 827e9ba9ffc9aa5dcc2de02dc3e58279ffda2318c79Brian Paul alpha_saturate = GL_FALSE; 828956e6c3978abe918348377cf05e5c92971e50d3fBrian Paul 8298bb0091e6838aeee2a5819850c334fde71b5a439Eric Anholt ir_variable *temp_var = p->make_temp(glsl_type::vec4_type, "texenv_combine"); 8307ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_dereference *deref; 8317ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_rvalue *val; 83215e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 83315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Emit the RGB and A combine ops 83415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 835ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->unit[unit].ModeRGB == key->unit[unit].ModeA && 836ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell args_match(key, unit)) { 8377ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt val = emit_combine(p, unit, 8387ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt key->unit[unit].NumArgsRGB, 8397ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt key->unit[unit].ModeRGB, 8407ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt key->unit[unit].OptRGB); 8417ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt val = smear(p, val); 8427ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt if (rgb_saturate) 843599aac95ff2149d881177ed75a48d97d3dcf47bdEric Anholt val = saturate(val); 8447ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 845d32780d5041a6d241834fe565739104f86300425Eric Anholt p->emit(assign(temp_var, val)); 84615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 847ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell else if (key->unit[unit].ModeRGB == MODE_DOT3_RGBA_EXT || 8489a45176dd85a1cd523498efeebd0481950a1bf58Roland Scheidegger key->unit[unit].ModeRGB == MODE_DOT3_RGBA) { 8497ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_rvalue *val = emit_combine(p, unit, 8507ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt key->unit[unit].NumArgsRGB, 8517ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt key->unit[unit].ModeRGB, 8527ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt key->unit[unit].OptRGB); 8537ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt val = smear(p, val); 8547ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt if (rgb_saturate) 855599aac95ff2149d881177ed75a48d97d3dcf47bdEric Anholt val = saturate(val); 856d32780d5041a6d241834fe565739104f86300425Eric Anholt p->emit(assign(temp_var, val)); 85715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 85815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell else { 85915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Need to do something to stop from re-emitting identical 86015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell * argument calculations here: 86115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 8627ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt val = emit_combine(p, unit, 8637ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt key->unit[unit].NumArgsRGB, 8647ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt key->unit[unit].ModeRGB, 8657ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt key->unit[unit].OptRGB); 866b782352745d322596a9122969f5c0e57ea032c1bEric Anholt val = swizzle_xyz(smear(p, val)); 8677ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt if (rgb_saturate) 868599aac95ff2149d881177ed75a48d97d3dcf47bdEric Anholt val = saturate(val); 869d32780d5041a6d241834fe565739104f86300425Eric Anholt p->emit(assign(temp_var, val, WRITEMASK_XYZ)); 8707ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 8717ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt val = emit_combine(p, unit, 8727ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt key->unit[unit].NumArgsA, 8737ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt key->unit[unit].ModeA, 8747ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt key->unit[unit].OptA); 875b782352745d322596a9122969f5c0e57ea032c1bEric Anholt val = swizzle_w(smear(p, val)); 8767ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt if (alpha_saturate) 877599aac95ff2149d881177ed75a48d97d3dcf47bdEric Anholt val = saturate(val); 878d32780d5041a6d241834fe565739104f86300425Eric Anholt p->emit(assign(temp_var, val, WRITEMASK_W)); 87915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 88015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 8817ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt deref = new(p->mem_ctx) ir_dereference_variable(temp_var); 8827ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 88315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell /* Deal with the final shift: 88415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell */ 88515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell if (alpha_shift || rgb_shift) { 8867ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_constant *shift; 887a5e7003565a021ceb82a8b16f4a0ecc7cc6c02e0Brian Paul 88815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell if (rgb_shift == alpha_shift) { 8897ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt shift = new(p->mem_ctx) ir_constant((float)(1 << rgb_shift)); 89015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 89115e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell else { 8927ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt float const_data[4] = { 8937ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 1 << rgb_shift, 8947ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 1 << rgb_shift, 8957ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 1 << rgb_shift, 8967ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 1 << alpha_shift 8977ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt }; 8987ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt shift = new(p->mem_ctx) ir_constant(glsl_type::vec4_type, 8997ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt (ir_constant_data *)const_data); 90015e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 9017ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 902599aac95ff2149d881177ed75a48d97d3dcf47bdEric Anholt return saturate(mul(deref, shift)); 90315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 90415e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell else 9057ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt return deref; 90615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 90715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 9082dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 90922db53577603afef8fdf62c324ff5977de76b9d8Brian Paul/** 91022db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * Generate instruction for getting a texture source term. 91122db53577603afef8fdf62c324ff5977de76b9d8Brian Paul */ 912098f9c5325de16bfb5bf8b0e93e0ec1871db4a76Eric Anholtstatic void load_texture( struct texenv_fragment_program *p, GLuint unit ) 913098f9c5325de16bfb5bf8b0e93e0ec1871db4a76Eric Anholt{ 9147ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_dereference *deref; 9152dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 9167ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt if (p->src_texture[unit]) 9177ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt return; 918098f9c5325de16bfb5bf8b0e93e0ec1871db4a76Eric Anholt 9197ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt const GLuint texTarget = p->state->unit[unit].source_index; 9207ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_rvalue *texcoord; 9217ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 9227ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt if (!(p->state->inputs_available & (FRAG_BIT_TEX0 << unit))) { 9237ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt texcoord = get_current_attrib(p, VERT_ATTRIB_TEX0 + unit); 9247ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt } else if (p->texcoord_tex[unit]) { 9257ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt texcoord = new(p->mem_ctx) ir_dereference_variable(p->texcoord_tex[unit]); 9267ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt } else { 9277ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_variable *tc_array = p->shader->symbols->get_variable("gl_TexCoord"); 9287ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt assert(tc_array); 9297ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt texcoord = new(p->mem_ctx) ir_dereference_variable(tc_array); 9307ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_rvalue *index = new(p->mem_ctx) ir_constant(unit); 9317ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt texcoord = new(p->mem_ctx) ir_dereference_array(texcoord, index); 9327ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt tc_array->max_array_access = MAX2(tc_array->max_array_access, unit); 9337ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt } 9347ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 9357ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt if (!p->state->unit[unit].enabled) { 9368bb0091e6838aeee2a5819850c334fde71b5a439Eric Anholt p->src_texture[unit] = p->make_temp(glsl_type::vec4_type, 9378bb0091e6838aeee2a5819850c334fde71b5a439Eric Anholt "dummy_tex"); 9387e88f8ce8f9d72bbda248554e0630b4aca7e1154Eric Anholt p->emit(p->src_texture[unit]); 9397ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 940d32780d5041a6d241834fe565739104f86300425Eric Anholt p->emit(assign(p->src_texture[unit], new(p->mem_ctx) ir_constant(0.0f))); 9417ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt return ; 9427ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt } 9437ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 9447ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt const glsl_type *sampler_type = NULL; 9457ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt int coords = 0; 9467ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 9477ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt switch (texTarget) { 9487ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt case TEXTURE_1D_INDEX: 9497ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt if (p->state->unit[unit].shadow) 9507ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt sampler_type = p->shader->symbols->get_type("sampler1DShadow"); 9517ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt else 9527ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt sampler_type = p->shader->symbols->get_type("sampler1D"); 9537ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt coords = 1; 9547ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt break; 9557ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt case TEXTURE_1D_ARRAY_INDEX: 9567ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt if (p->state->unit[unit].shadow) 9577ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt sampler_type = p->shader->symbols->get_type("sampler1DArrayShadow"); 9587ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt else 9597ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt sampler_type = p->shader->symbols->get_type("sampler1DArray"); 9607ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt coords = 2; 9617ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt break; 9627ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt case TEXTURE_2D_INDEX: 9637ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt if (p->state->unit[unit].shadow) 9647ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt sampler_type = p->shader->symbols->get_type("sampler2DShadow"); 965098f9c5325de16bfb5bf8b0e93e0ec1871db4a76Eric Anholt else 9667ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt sampler_type = p->shader->symbols->get_type("sampler2D"); 9677ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt coords = 2; 9687ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt break; 9697ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt case TEXTURE_2D_ARRAY_INDEX: 9707ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt if (p->state->unit[unit].shadow) 9717ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt sampler_type = p->shader->symbols->get_type("sampler2DArrayShadow"); 9727ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt else 9737ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt sampler_type = p->shader->symbols->get_type("sampler2DArray"); 9747ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt coords = 3; 9757ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt break; 9767ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt case TEXTURE_RECT_INDEX: 9777ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt if (p->state->unit[unit].shadow) 9787ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt sampler_type = p->shader->symbols->get_type("sampler2DRectShadow"); 9797ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt else 9807ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt sampler_type = p->shader->symbols->get_type("sampler2DRect"); 9817ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt coords = 2; 9827ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt break; 9837ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt case TEXTURE_3D_INDEX: 9847ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt assert(!p->state->unit[unit].shadow); 9857ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt sampler_type = p->shader->symbols->get_type("sampler3D"); 9867ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt coords = 3; 9877ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt break; 9887ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt case TEXTURE_CUBE_INDEX: 9897ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt if (p->state->unit[unit].shadow) 9907ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt sampler_type = p->shader->symbols->get_type("samplerCubeShadow"); 9917ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt else 9927ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt sampler_type = p->shader->symbols->get_type("samplerCube"); 9937ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt coords = 3; 9947ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt break; 9950c87f16817ff0bf1f05e0d634944fd47b097faeeChia-I Wu case TEXTURE_EXTERNAL_INDEX: 9960c87f16817ff0bf1f05e0d634944fd47b097faeeChia-I Wu assert(!p->state->unit[unit].shadow); 9970c87f16817ff0bf1f05e0d634944fd47b097faeeChia-I Wu sampler_type = p->shader->symbols->get_type("samplerExternalOES"); 9980c87f16817ff0bf1f05e0d634944fd47b097faeeChia-I Wu coords = 2; 9990c87f16817ff0bf1f05e0d634944fd47b097faeeChia-I Wu break; 10007ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt } 1001098f9c5325de16bfb5bf8b0e93e0ec1871db4a76Eric Anholt 10028bb0091e6838aeee2a5819850c334fde71b5a439Eric Anholt p->src_texture[unit] = p->make_temp(glsl_type::vec4_type, 10038bb0091e6838aeee2a5819850c334fde71b5a439Eric Anholt "tex"); 10047ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 10057ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_texture *tex = new(p->mem_ctx) ir_texture(ir_tex); 10067ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 10077ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 10087ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt char *sampler_name = ralloc_asprintf(p->mem_ctx, "sampler_%d", unit); 10097ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_variable *sampler = new(p->mem_ctx) ir_variable(sampler_type, 10107ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt sampler_name, 10117ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_var_uniform); 10127ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt p->top_instructions->push_head(sampler); 101349da2590c24529e44de9993e2981cc970cf0135bIan Romanick 101449da2590c24529e44de9993e2981cc970cf0135bIan Romanick /* Set the texture unit for this sampler. The linker will pick this value 101549da2590c24529e44de9993e2981cc970cf0135bIan Romanick * up and do-the-right-thing. 101649da2590c24529e44de9993e2981cc970cf0135bIan Romanick * 101749da2590c24529e44de9993e2981cc970cf0135bIan Romanick * NOTE: The cast to int is important. Without it, the constant will have 101849da2590c24529e44de9993e2981cc970cf0135bIan Romanick * type uint, and things later on may get confused. 101949da2590c24529e44de9993e2981cc970cf0135bIan Romanick */ 102049da2590c24529e44de9993e2981cc970cf0135bIan Romanick sampler->constant_value = new(p->mem_ctx) ir_constant(int(unit)); 102149da2590c24529e44de9993e2981cc970cf0135bIan Romanick 10227ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt deref = new(p->mem_ctx) ir_dereference_variable(sampler); 10237ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt tex->set_sampler(deref, glsl_type::vec4_type); 10247ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 10257ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt tex->coordinate = new(p->mem_ctx) ir_swizzle(texcoord, 0, 1, 2, 3, coords); 1026098f9c5325de16bfb5bf8b0e93e0ec1871db4a76Eric Anholt 10277ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt if (p->state->unit[unit].shadow) { 10287ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt texcoord = texcoord->clone(p->mem_ctx, NULL); 10297ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt tex->shadow_comparitor = new(p->mem_ctx) ir_swizzle(texcoord, 10307ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt coords, 0, 0, 0, 10317ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 1); 10327ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt coords++; 1033098f9c5325de16bfb5bf8b0e93e0ec1871db4a76Eric Anholt } 10347ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 10357ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt texcoord = texcoord->clone(p->mem_ctx, NULL); 1036b782352745d322596a9122969f5c0e57ea032c1bEric Anholt tex->projector = swizzle_w(texcoord); 10377ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 1038d32780d5041a6d241834fe565739104f86300425Eric Anholt p->emit(assign(p->src_texture[unit], tex)); 1039098f9c5325de16bfb5bf8b0e93e0ec1871db4a76Eric Anholt} 1040098f9c5325de16bfb5bf8b0e93e0ec1871db4a76Eric Anholt 10417ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholtstatic void 10427ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholtload_texenv_source(struct texenv_fragment_program *p, 10437ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt GLuint src, GLuint unit) 10442dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell{ 10452dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell switch (src) { 10464dd8a8907e40126e42131a400b59e7d5da5e302aAapo Tahkola case SRC_TEXTURE: 10472dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell load_texture(p, unit); 10482dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell break; 10492dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 1050ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE0: 1051ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE1: 1052ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE2: 1053ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE3: 1054ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE4: 1055ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE5: 1056ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE6: 1057ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell case SRC_TEXTURE7: 1058ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell load_texture(p, src - SRC_TEXTURE0); 10592dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell break; 10602dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 10612dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell default: 10626947f85cb5fbc433ba7763530285e470745b009bBrian Paul /* not a texture src - do nothing */ 10632dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell break; 10642dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell } 10652dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell} 10662dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 106722db53577603afef8fdf62c324ff5977de76b9d8Brian Paul 106822db53577603afef8fdf62c324ff5977de76b9d8Brian Paul/** 106922db53577603afef8fdf62c324ff5977de76b9d8Brian Paul * Generate instructions for loading all texture source terms. 107022db53577603afef8fdf62c324ff5977de76b9d8Brian Paul */ 107122db53577603afef8fdf62c324ff5977de76b9d8Brian Paulstatic GLboolean 1072457e427e32324884acb064b756e327dc131ff135Brian Paulload_texunit_sources( struct texenv_fragment_program *p, GLuint unit ) 10732dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell{ 1074a5e7003565a021ceb82a8b16f4a0ecc7cc6c02e0Brian Paul const struct state_key *key = p->state; 1075b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola GLuint i; 1076b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola 1077b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola for (i = 0; i < key->unit[unit].NumArgsRGB; i++) { 1078114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger load_texenv_source( p, key->unit[unit].OptRGB[i].Source, unit ); 1079b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola } 1080b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola 1081b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola for (i = 0; i < key->unit[unit].NumArgsA; i++) { 1082b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola load_texenv_source( p, key->unit[unit].OptA[i].Source, unit ); 10832dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell } 1084b8915340eab706776244e04547f64444f0ff2f8bAapo Tahkola 1085241b6b7ab1a1a11c7fc516d1b6ff2c1bc8aba238Keith Whitwell return GL_TRUE; 10862dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell} 10872dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell 1088114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger/** 1089114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger * Generate instructions for loading bump map textures. 1090114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger */ 10917ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholtstatic void 1092457e427e32324884acb064b756e327dc131ff135Brian Paulload_texunit_bumpmap( struct texenv_fragment_program *p, GLuint unit ) 1093114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger{ 1094a5e7003565a021ceb82a8b16f4a0ecc7cc6c02e0Brian Paul const struct state_key *key = p->state; 1095114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger GLuint bumpedUnitNr = key->unit[unit].OptRGB[1].Source - SRC_TEXTURE0; 10967ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_rvalue *bump; 10977ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_rvalue *texcoord; 1098d6e6566206029ace72ba037a3ef7950876eeb88bEric Anholt ir_variable *rot_mat_0, *rot_mat_1; 10997ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 1100d6e6566206029ace72ba037a3ef7950876eeb88bEric Anholt rot_mat_0 = p->shader->symbols->get_variable("gl_BumpRotMatrix0MESA"); 1101d6e6566206029ace72ba037a3ef7950876eeb88bEric Anholt rot_mat_1 = p->shader->symbols->get_variable("gl_BumpRotMatrix1MESA"); 11027ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 11037ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_variable *tc_array = p->shader->symbols->get_variable("gl_TexCoord"); 11047ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt assert(tc_array); 11057ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt texcoord = new(p->mem_ctx) ir_dereference_variable(tc_array); 11067ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_rvalue *index = new(p->mem_ctx) ir_constant(bumpedUnitNr); 11077ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt texcoord = new(p->mem_ctx) ir_dereference_array(texcoord, index); 11087ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt tc_array->max_array_access = MAX2(tc_array->max_array_access, unit); 1109114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 1110114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger load_texenv_source( p, unit + SRC_TEXTURE0, unit ); 1111114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 1112457e427e32324884acb064b756e327dc131ff135Brian Paul /* Apply rot matrix and add coords to be available in next phase. 11137ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt * dest = Arg1 + (Arg0.xx * rotMat0) + (Arg0.yy * rotMat1) 1114457e427e32324884acb064b756e327dc131ff135Brian Paul * note only 2 coords are affected the rest are left unchanged (mul by 0) 1115457e427e32324884acb064b756e327dc131ff135Brian Paul */ 11167ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_rvalue *bump_x, *bump_y; 11177ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 11187ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt texcoord = smear(p, texcoord); 11197ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 11207ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt /* bump_texcoord = texcoord */ 11218bb0091e6838aeee2a5819850c334fde71b5a439Eric Anholt ir_variable *bumped = p->make_temp(texcoord->type, "bump_texcoord"); 11227e88f8ce8f9d72bbda248554e0630b4aca7e1154Eric Anholt p->emit(bumped); 1123d32780d5041a6d241834fe565739104f86300425Eric Anholt p->emit(assign(bumped, texcoord)); 11247ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 11257ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt /* bump_texcoord.xy += arg0.x * rotmat0 + arg0.y * rotmat1 */ 11267ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt bump = get_source(p, key->unit[unit].OptRGB[0].Source, unit); 1127b782352745d322596a9122969f5c0e57ea032c1bEric Anholt bump_x = mul(swizzle_x(bump), rot_mat_0); 1128b782352745d322596a9122969f5c0e57ea032c1bEric Anholt bump_y = mul(swizzle_y(bump->clone(p->mem_ctx, NULL)), rot_mat_1); 11297ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 1130d32780d5041a6d241834fe565739104f86300425Eric Anholt p->emit(assign(bumped, add(swizzle_xy(bumped), add(bump_x, bump_y)), 1131d32780d5041a6d241834fe565739104f86300425Eric Anholt WRITEMASK_XY)); 11327ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 11337ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt p->texcoord_tex[bumpedUnitNr] = bumped; 1134114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger} 113522db53577603afef8fdf62c324ff5977de76b9d8Brian Paul 113622db53577603afef8fdf62c324ff5977de76b9d8Brian Paul/** 11377ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt * Applies the fog calculations. 11387ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt * 11397ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt * This is basically like the ARB_fragment_prorgam fog options. Note 11407ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt * that ffvertex_prog.c produces fogcoord for us when 11417ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt * GL_FOG_COORDINATE_EXT is set to GL_FRAGMENT_DEPTH_EXT. 114222db53577603afef8fdf62c324ff5977de76b9d8Brian Paul */ 11437ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholtstatic ir_rvalue * 11447ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholtemit_fog_instructions(struct texenv_fragment_program *p, 11457ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_rvalue *fragcolor) 114615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell{ 11477ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt struct state_key *key = p->state; 11487ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_rvalue *f, *temp; 11497ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_variable *params, *oparams; 11507ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_variable *fogcoord; 11517ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 11527ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt /* Temporary storage for the whole fog result. Fog calculations 11537ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt * only affect rgb so we're hanging on to the .a value of fragcolor 11547ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt * this way. 1155098f9c5325de16bfb5bf8b0e93e0ec1871db4a76Eric Anholt */ 11568bb0091e6838aeee2a5819850c334fde71b5a439Eric Anholt ir_variable *fog_result = p->make_temp(glsl_type::vec4_type, "fog_result"); 1157d32780d5041a6d241834fe565739104f86300425Eric Anholt p->emit(assign(fog_result, fragcolor)); 11587ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 1159b782352745d322596a9122969f5c0e57ea032c1bEric Anholt fragcolor = swizzle_xyz(fog_result); 11607ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 11614fc9a98a0e01195202cd5f3f5a78cf28c5e8843cEric Anholt oparams = p->shader->symbols->get_variable("gl_FogParamsOptimizedMESA"); 11627ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt fogcoord = p->shader->symbols->get_variable("gl_FogFragCoord"); 11637ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt params = p->shader->symbols->get_variable("gl_Fog"); 11647ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt f = new(p->mem_ctx) ir_dereference_variable(fogcoord); 11657ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 11668bb0091e6838aeee2a5819850c334fde71b5a439Eric Anholt ir_variable *f_var = p->make_temp(glsl_type::float_type, "fog_factor"); 11677ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 11687ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt switch (key->fog_mode) { 11697ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt case FOG_LINEAR: 11707ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt /* f = (end - z) / (end - start) 11717ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt * 11727ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt * gl_MesaFogParamsOptimized gives us (-1 / (end - start)) and 11737ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt * (end / (end - start)) so we can generate a single MAD. 11747ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt */ 1175b782352745d322596a9122969f5c0e57ea032c1bEric Anholt f = add(mul(f, swizzle_x(oparams)), swizzle_y(oparams)); 11767ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt break; 11777ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt case FOG_EXP: 11787ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt /* f = e^(-(density * fogcoord)) 11797ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt * 11807ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt * gl_MesaFogParamsOptimized gives us density/ln(2) so we can 11817ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt * use EXP2 which is generally the native instruction without 11827ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt * having to do any further math on the fog density uniform. 11837ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt */ 1184b782352745d322596a9122969f5c0e57ea032c1bEric Anholt f = mul(f, swizzle_z(oparams)); 11857ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt f = new(p->mem_ctx) ir_expression(ir_unop_neg, f); 11867ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt f = new(p->mem_ctx) ir_expression(ir_unop_exp2, f); 11877ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt break; 11887ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt case FOG_EXP2: 11897ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt /* f = e^(-(density * fogcoord)^2) 11907ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt * 11917ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt * gl_MesaFogParamsOptimized gives us density/sqrt(ln(2)) so we 11927ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt * can do this like FOG_EXP but with a squaring after the 11937ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt * multiply by density. 11947ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt */ 11958bb0091e6838aeee2a5819850c334fde71b5a439Eric Anholt ir_variable *temp_var = p->make_temp(glsl_type::float_type, "fog_temp"); 1196d32780d5041a6d241834fe565739104f86300425Eric Anholt p->emit(assign(temp_var, mul(f, swizzle_w(oparams)))); 11977ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 1198d6e6566206029ace72ba037a3ef7950876eeb88bEric Anholt f = mul(temp_var, temp_var); 11997ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt f = new(p->mem_ctx) ir_expression(ir_unop_neg, f); 12007ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt f = new(p->mem_ctx) ir_expression(ir_unop_exp2, f); 12017ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt break; 1202098f9c5325de16bfb5bf8b0e93e0ec1871db4a76Eric Anholt } 120315e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1204d32780d5041a6d241834fe565739104f86300425Eric Anholt p->emit(assign(f_var, saturate(f))); 12057cb87dffce2c7a37f960f3a865cf92fd193dd8c5Eric Anholt 1206d6e6566206029ace72ba037a3ef7950876eeb88bEric Anholt f = sub(new(p->mem_ctx) ir_constant(1.0f), f_var); 12077ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt temp = new(p->mem_ctx) ir_dereference_variable(params); 12087ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt temp = new(p->mem_ctx) ir_dereference_record(temp, "color"); 1209b782352745d322596a9122969f5c0e57ea032c1bEric Anholt temp = mul(swizzle_xyz(temp), f); 12107cb87dffce2c7a37f960f3a865cf92fd193dd8c5Eric Anholt 1211d32780d5041a6d241834fe565739104f86300425Eric Anholt p->emit(assign(fog_result, add(temp, mul(fragcolor, f_var)), WRITEMASK_XYZ)); 12127ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 12137ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt return new(p->mem_ctx) ir_dereference_variable(fog_result); 12147ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt} 12157ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 12167ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholtstatic void 12177ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholtemit_instructions(struct texenv_fragment_program *p) 12187ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt{ 12197ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt struct state_key *key = p->state; 12207ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt GLuint unit; 12217ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 12227ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt if (key->enabled_units) { 1223114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger /* Zeroth pass - bump map textures first */ 12247ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt for (unit = 0; unit < key->nr_enabled_units; unit++) { 1225457e427e32324884acb064b756e327dc131ff135Brian Paul if (key->unit[unit].enabled && 1226457e427e32324884acb064b756e327dc131ff135Brian Paul key->unit[unit].ModeRGB == MODE_BUMP_ENVMAP_ATI) { 12277ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt load_texunit_bumpmap(p, unit); 1228114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger } 12297ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt } 1230114152e068ec919feb0a57a1259c2ada970b9f02Roland Scheidegger 12312dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell /* First pass - to support texture_env_crossbar, first identify 12322dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell * all referenced texture sources and emit texld instructions 12332dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell * for each: 12342dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell */ 12357a7d5879e28607c151132a8b6a07cf4be36b5b3eBrian Paul for (unit = 0; unit < key->nr_enabled_units; unit++) 1236ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell if (key->unit[unit].enabled) { 12377ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt load_texunit_sources(p, unit); 123815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 123915e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 12402dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell /* Second pass - emit combine instructions to build final color: 12412dea6df80b51ad8c5e2e88c2eb214b55889821c6Keith Whitwell */ 12427ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt for (unit = 0; unit < key->nr_enabled_units; unit++) { 124384d6bed4d6844110af23a995e2fad0280a92d46cBrian Paul if (key->unit[unit].enabled) { 12447ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt p->src_previous = emit_texenv(p, unit); 124515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 12467ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt } 124715e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell } 124815e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 12497ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_rvalue *cf = get_source(p, SRC_PREVIOUS, 0); 12507ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 12517ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt if (key->separate_specular) { 12528bb0091e6838aeee2a5819850c334fde71b5a439Eric Anholt ir_variable *spec_result = p->make_temp(glsl_type::vec4_type, 12538bb0091e6838aeee2a5819850c334fde71b5a439Eric Anholt "specular_add"); 1254d32780d5041a6d241834fe565739104f86300425Eric Anholt p->emit(assign(spec_result, cf)); 12557ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 12567ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_rvalue *secondary; 12577ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt if (p->state->inputs_available & FRAG_BIT_COL1) { 12587ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_variable *var = 12597ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt p->shader->symbols->get_variable("gl_SecondaryColor"); 12607ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt assert(var); 1261b782352745d322596a9122969f5c0e57ea032c1bEric Anholt secondary = swizzle_xyz(var); 12627ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt } else { 1263b782352745d322596a9122969f5c0e57ea032c1bEric Anholt secondary = swizzle_xyz(get_current_attrib(p, VERT_ATTRIB_COLOR1)); 12647ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt } 12657cb87dffce2c7a37f960f3a865cf92fd193dd8c5Eric Anholt 1266d32780d5041a6d241834fe565739104f86300425Eric Anholt p->emit(assign(spec_result, add(swizzle_xyz(spec_result), secondary), 1267d32780d5041a6d241834fe565739104f86300425Eric Anholt WRITEMASK_XYZ)); 12687ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 12697ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt cf = new(p->mem_ctx) ir_dereference_variable(spec_result); 12704b39a0da89f5b07d4a24bc9ce52693e6c2acfe99Dave Airlie } 127147b29f511a8e917c65536fde90397d54d2ad23d3Keith Whitwell 12727ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt if (key->fog_enabled) { 12737ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt cf = emit_fog_instructions(p, cf); 12743aa21f93dc1329c6f956277f2746c2a0bdae5446Ian Romanick } 12753aa21f93dc1329c6f956277f2746c2a0bdae5446Ian Romanick 12767ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_variable *frag_color = p->shader->symbols->get_variable("gl_FragColor"); 12777ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt assert(frag_color); 1278d32780d5041a6d241834fe565739104f86300425Eric Anholt p->emit(assign(frag_color, cf)); 12797ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt} 12807ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 12817ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt/** 12827ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt * Generate a new fragment program which implements the context's 12837ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt * current texture env/combine mode. 12847ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt */ 12857ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholtstatic struct gl_shader_program * 12867ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholtcreate_new_program(struct gl_context *ctx, struct state_key *key) 12877ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt{ 12887e88f8ce8f9d72bbda248554e0630b4aca7e1154Eric Anholt texenv_fragment_program p; 12897ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt unsigned int unit; 12907ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt _mesa_glsl_parse_state *state; 12917ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 12927ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt p.mem_ctx = ralloc_context(NULL); 12937ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt p.shader = ctx->Driver.NewShader(ctx, 0, GL_FRAGMENT_SHADER); 12947ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt p.shader->ir = new(p.shader) exec_list; 12957ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt state = new(p.shader) _mesa_glsl_parse_state(ctx, GL_FRAGMENT_SHADER, 12967ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt p.shader); 12977ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt p.shader->symbols = state->symbols; 12987ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt p.top_instructions = p.shader->ir; 12997ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt p.instructions = p.shader->ir; 13007ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt p.state = key; 13017ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt p.shader_program = ctx->Driver.NewShaderProgram(ctx, 0); 13027ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 13037ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt /* Tell the linker to ignore the fact that we're building a 13047ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt * separate shader, in case we're in a GLES2 context that would 13057ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt * normally reject that. The real problem is that we're building a 13067ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt * fixed function program in a GLES2 context at all, but that's a 13077ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt * big mess to clean up. 13083aa21f93dc1329c6f956277f2746c2a0bdae5446Ian Romanick */ 13097ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt p.shader_program->InternalSeparateShader = GL_TRUE; 13107ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 13117ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt state->language_version = 130; 13120c87f16817ff0bf1f05e0d634944fd47b097faeeChia-I Wu if (ctx->Extensions.OES_EGL_image_external) 13130c87f16817ff0bf1f05e0d634944fd47b097faeeChia-I Wu state->OES_EGL_image_external_enable = true; 13147ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt _mesa_glsl_initialize_types(state); 13157ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt _mesa_glsl_initialize_variables(p.instructions, state); 13167ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 13177ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { 13187ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt p.src_texture[unit] = NULL; 13197ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt p.texcoord_tex[unit] = NULL; 1320e998c346471142db91a1bcb6c61551b8247b87e7Brian Paul } 1321c81cce78313a62e0d36a5c80bd9d35b770d0814aBrian 13227ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt p.src_previous = NULL; 13237ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 13247ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_function *main_f = new(p.mem_ctx) ir_function("main"); 13257e88f8ce8f9d72bbda248554e0630b4aca7e1154Eric Anholt p.emit(main_f); 13267ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt state->symbols->add_function(main_f); 13277cb87dffce2c7a37f960f3a865cf92fd193dd8c5Eric Anholt 13287ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ir_function_signature *main_sig = 13297ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt new(p.mem_ctx) ir_function_signature(p.shader->symbols->get_type("void")); 13307ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt main_sig->is_defined = true; 13317ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt main_f->add_signature(main_sig); 13327cb87dffce2c7a37f960f3a865cf92fd193dd8c5Eric Anholt 13337ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt p.instructions = &main_sig->body; 13347ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt if (key->num_draw_buffers) 13357ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt emit_instructions(&p); 13367cb87dffce2c7a37f960f3a865cf92fd193dd8c5Eric Anholt 13377ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt validate_ir_tree(p.shader->ir); 13387cb87dffce2c7a37f960f3a865cf92fd193dd8c5Eric Anholt 13391d5d67f8adac9f94715de9804adb536d9a7ec5eeIan Romanick while (do_common_optimization(p.shader->ir, false, false, 32)) 13407ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ; 13417ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt reparent_ir(p.shader->ir, p.shader->ir); 13427ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 13437ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt p.shader->CompileStatus = true; 13447ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt p.shader->Version = state->language_version; 13457ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt p.shader->num_builtins_to_link = state->num_builtins_to_link; 13467ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt p.shader_program->Shaders = 13477ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt (gl_shader **)malloc(sizeof(*p.shader_program->Shaders)); 13487ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt p.shader_program->Shaders[0] = p.shader; 13497ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt p.shader_program->NumShaders = 1; 13507ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 13517ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt _mesa_glsl_link_shader(ctx, p.shader_program); 13527ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 13537ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt /* Set the sampler uniforms, and relink to get them into the linked 13547ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt * program. 13558b88f62fbd62153500fc3483003f438561366a00Keith Whitwell */ 1356f409a710e3562856a53a3b43ed526b877639a27cIan Romanick struct gl_shader *const fs = 1357f409a710e3562856a53a3b43ed526b877639a27cIan Romanick p.shader_program->_LinkedShaders[MESA_SHADER_FRAGMENT]; 1358f409a710e3562856a53a3b43ed526b877639a27cIan Romanick struct gl_program *const fp = fs->Program; 1359f409a710e3562856a53a3b43ed526b877639a27cIan Romanick 1360f409a710e3562856a53a3b43ed526b877639a27cIan Romanick _mesa_generate_parameters_list_for_uniforms(p.shader_program, fs, 1361f409a710e3562856a53a3b43ed526b877639a27cIan Romanick fp->Parameters); 1362f409a710e3562856a53a3b43ed526b877639a27cIan Romanick 1363f409a710e3562856a53a3b43ed526b877639a27cIan Romanick _mesa_associate_uniform_storage(ctx, p.shader_program, fp->Parameters); 13647ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 13656a992c3288b6f7a5d94172c9ad1908e71e58233eIan Romanick _mesa_update_shader_textures_used(p.shader_program, fp); 1366174d44a9c4d39a030fe3528acf07f9ac9aa617a1Kenneth Graunke if (ctx->Driver.SamplerUniformChange) 1367174d44a9c4d39a030fe3528acf07f9ac9aa617a1Kenneth Graunke ctx->Driver.SamplerUniformChange(ctx, fp->Target, fp); 13687ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 13697ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt if (!p.shader_program->LinkStatus) 13707ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt _mesa_problem(ctx, "Failed to link fixed function fragment shader: %s\n", 13717ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt p.shader_program->InfoLog); 13727ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 13737ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt ralloc_free(p.mem_ctx); 13747ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt return p.shader_program; 137515e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell} 137615e75e00c7dc79c28aeac84891bcf18ffc77cff9Keith Whitwell 1377cdacca4868bbfe2e39f72d524556e7b2c7200ba5Eric Anholtextern "C" { 13785d7b49f7e77f9e3303e0910834b6c014e7267289Brian Paul 137932ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell/** 138032ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell * Return a fragment program which implements the current 138132ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell * fixed-function texture, fog and color-sum operations. 138232ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell */ 13837ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholtstruct gl_shader_program * 1384f9995b30756140724f41daf963fa06167912be7fKristian Høgsberg_mesa_get_fixed_func_fragment_program(struct gl_context *ctx) 1385ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell{ 13867ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt struct gl_shader_program *shader_program; 138732ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell struct state_key key; 13887a7d5879e28607c151132a8b6a07cf4be36b5b3eBrian Paul GLuint keySize; 13897ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 13907a7d5879e28607c151132a8b6a07cf4be36b5b3eBrian Paul keySize = make_state_key(ctx, &key); 13917ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt 13927ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt shader_program = (struct gl_shader_program *) 139332ef6e75839d6be283e034436e5dd34eabb67958Keith Whitwell _mesa_search_program_cache(ctx->FragmentProgram.Cache, 13947a7d5879e28607c151132a8b6a07cf4be36b5b3eBrian Paul &key, keySize); 1395ce721143b4d44d239baefe965e499606149b15cbKeith Whitwell 13967ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt if (!shader_program) { 13977ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt shader_program = create_new_program(ctx, &key); 13985ddc53f899598396003ec6c723f8132c76aafe79Keith Whitwell 13997ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt _mesa_shader_cache_insert(ctx, ctx->FragmentProgram.Cache, 14007ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt &key, keySize, shader_program); 14018065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell } 14028065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell 14037ec2b0d0d6b6a0f760e55ffdee0bdb385a3e900aEric Anholt return shader_program; 14048065c120c45e89e49ca9f707408fd7bd14db6b23Keith Whitwell} 1405cdacca4868bbfe2e39f72d524556e7b2c7200ba5Eric Anholt 1406cdacca4868bbfe2e39f72d524556e7b2c7200ba5Eric Anholt} 1407