1 /************************************************************************** 2 * 3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28 29 #ifndef I915_FPC_H 30 #define I915_FPC_H 31 32 33 #include "i915_context.h" 34 #include "i915_reg.h" 35 36 #include "pipe/p_shader_tokens.h" 37 38 #include "tgsi/tgsi_parse.h" 39 40 #define I915_PROGRAM_SIZE 192 41 42 /* Use those indices for pos/face routing, must be >= num of inputs */ 43 #define I915_SEMANTIC_POS 100 44 #define I915_SEMANTIC_FACE 101 45 46 47 /** 48 * Program translation state 49 */ 50 struct i915_fp_compile { 51 struct i915_fragment_shader *shader; /* the shader we're compiling */ 52 53 boolean used_constants[I915_MAX_CONSTANT]; 54 55 /** maps TGSI immediate index to constant slot */ 56 uint num_immediates; 57 uint immediates_map[I915_MAX_CONSTANT]; 58 float immediates[I915_MAX_CONSTANT][4]; 59 60 boolean first_instruction; 61 62 uint declarations[I915_PROGRAM_SIZE]; 63 uint program[I915_PROGRAM_SIZE]; 64 65 uint *csr; /**< Cursor, points into program. */ 66 67 uint *decl; /**< Cursor, points into declarations. */ 68 69 uint decl_s; /**< flags for which s regs need to be decl'd */ 70 uint decl_t; /**< flags for which t regs need to be decl'd */ 71 72 uint temp_flag; /**< Tracks temporary regs which are in use */ 73 uint utemp_flag; /**< Tracks TYPE_U temporary regs which are in use */ 74 75 uint register_phases[16]; 76 uint nr_tex_indirect; 77 uint nr_tex_insn; 78 uint nr_alu_insn; 79 uint nr_decl_insn; 80 81 boolean error; /**< Set if i915_program_error() is called */ 82 uint NumNativeInstructions; 83 uint NumNativeAluInstructions; 84 uint NumNativeTexInstructions; 85 uint NumNativeTexIndirections; 86 }; 87 88 89 /* Having zero and one in here makes the definition of swizzle a lot 90 * easier. 91 */ 92 #define UREG_TYPE_SHIFT 29 93 #define UREG_NR_SHIFT 24 94 #define UREG_CHANNEL_X_NEGATE_SHIFT 23 95 #define UREG_CHANNEL_X_SHIFT 20 96 #define UREG_CHANNEL_Y_NEGATE_SHIFT 19 97 #define UREG_CHANNEL_Y_SHIFT 16 98 #define UREG_CHANNEL_Z_NEGATE_SHIFT 15 99 #define UREG_CHANNEL_Z_SHIFT 12 100 #define UREG_CHANNEL_W_NEGATE_SHIFT 11 101 #define UREG_CHANNEL_W_SHIFT 8 102 #define UREG_CHANNEL_ZERO_NEGATE_MBZ 5 103 #define UREG_CHANNEL_ZERO_SHIFT 4 104 #define UREG_CHANNEL_ONE_NEGATE_MBZ 1 105 #define UREG_CHANNEL_ONE_SHIFT 0 106 107 #define UREG_BAD 0xffffffff /* not a valid ureg */ 108 109 #define X SRC_X 110 #define Y SRC_Y 111 #define Z SRC_Z 112 #define W SRC_W 113 #define ZERO SRC_ZERO 114 #define ONE SRC_ONE 115 116 /* Construct a ureg: 117 */ 118 #define UREG( type, nr ) (((type)<< UREG_TYPE_SHIFT) | \ 119 ((nr) << UREG_NR_SHIFT) | \ 120 (X << UREG_CHANNEL_X_SHIFT) | \ 121 (Y << UREG_CHANNEL_Y_SHIFT) | \ 122 (Z << UREG_CHANNEL_Z_SHIFT) | \ 123 (W << UREG_CHANNEL_W_SHIFT) | \ 124 (ZERO << UREG_CHANNEL_ZERO_SHIFT) | \ 125 (ONE << UREG_CHANNEL_ONE_SHIFT)) 126 127 #define GET_CHANNEL_SRC( reg, channel ) ((reg<<(channel*4)) & (0xf<<20)) 128 #define CHANNEL_SRC( src, channel ) (src>>(channel*4)) 129 130 #define GET_UREG_TYPE(reg) (((reg)>>UREG_TYPE_SHIFT)®_TYPE_MASK) 131 #define GET_UREG_NR(reg) (((reg)>>UREG_NR_SHIFT)®_NR_MASK) 132 133 134 135 #define UREG_XYZW_CHANNEL_MASK 0x00ffff00 136 137 /* One neat thing about the UREG representation: 138 */ 139 static INLINE int 140 swizzle(int reg, uint x, uint y, uint z, uint w) 141 { 142 assert(x <= SRC_ONE); 143 assert(y <= SRC_ONE); 144 assert(z <= SRC_ONE); 145 assert(w <= SRC_ONE); 146 return ((reg & ~UREG_XYZW_CHANNEL_MASK) | 147 CHANNEL_SRC(GET_CHANNEL_SRC(reg, x), 0) | 148 CHANNEL_SRC(GET_CHANNEL_SRC(reg, y), 1) | 149 CHANNEL_SRC(GET_CHANNEL_SRC(reg, z), 2) | 150 CHANNEL_SRC(GET_CHANNEL_SRC(reg, w), 3)); 151 } 152 153 154 #define A0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT) 155 #define D0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT) 156 #define T0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT) 157 #define A0_SRC0( reg ) (((reg)&UREG_MASK)>>UREG_A0_SRC0_SHIFT_LEFT) 158 #define A1_SRC0( reg ) (((reg)&UREG_MASK)<<UREG_A1_SRC0_SHIFT_RIGHT) 159 #define A1_SRC1( reg ) (((reg)&UREG_MASK)>>UREG_A1_SRC1_SHIFT_LEFT) 160 #define A2_SRC1( reg ) (((reg)&UREG_MASK)<<UREG_A2_SRC1_SHIFT_RIGHT) 161 #define A2_SRC2( reg ) (((reg)&UREG_MASK)>>UREG_A2_SRC2_SHIFT_LEFT) 162 163 /* These are special, and don't have swizzle/negate bits. 164 */ 165 #define T0_SAMPLER( reg ) (GET_UREG_NR(reg)<<T0_SAMPLER_NR_SHIFT) 166 #define T1_ADDRESS_REG( reg ) ((GET_UREG_NR(reg)<<T1_ADDRESS_REG_NR_SHIFT) | \ 167 (GET_UREG_TYPE(reg)<<T1_ADDRESS_REG_TYPE_SHIFT)) 168 169 170 /* Macros for translating UREG's into the various register fields used 171 * by the I915 programmable unit. 172 */ 173 #define UREG_A0_DEST_SHIFT_LEFT (UREG_TYPE_SHIFT - A0_DEST_TYPE_SHIFT) 174 #define UREG_A0_SRC0_SHIFT_LEFT (UREG_TYPE_SHIFT - A0_SRC0_TYPE_SHIFT) 175 #define UREG_A1_SRC0_SHIFT_RIGHT (A1_SRC0_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT) 176 #define UREG_A1_SRC1_SHIFT_LEFT (UREG_TYPE_SHIFT - A1_SRC1_TYPE_SHIFT) 177 #define UREG_A2_SRC1_SHIFT_RIGHT (A2_SRC1_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT) 178 #define UREG_A2_SRC2_SHIFT_LEFT (UREG_TYPE_SHIFT - A2_SRC2_TYPE_SHIFT) 179 180 #define UREG_MASK 0xffffff00 181 #define UREG_TYPE_NR_MASK ((REG_TYPE_MASK << UREG_TYPE_SHIFT) | \ 182 (REG_NR_MASK << UREG_NR_SHIFT)) 183 184 185 186 187 /*********************************************************************** 188 * Public interface for the compiler 189 */ 190 extern void 191 i915_translate_fragment_program( struct i915_context *i915, 192 struct i915_fragment_shader *fs); 193 194 195 196 extern uint i915_get_temp(struct i915_fp_compile *p); 197 extern uint i915_get_utemp(struct i915_fp_compile *p); 198 extern void i915_release_utemps(struct i915_fp_compile *p); 199 200 201 extern uint i915_emit_texld(struct i915_fp_compile *p, 202 uint dest, 203 uint destmask, 204 uint sampler, 205 uint coord, 206 uint op, 207 uint num_coord); 208 209 extern uint i915_emit_arith(struct i915_fp_compile *p, 210 uint op, 211 uint dest, 212 uint mask, 213 uint saturate, 214 uint src0, uint src1, uint src2); 215 216 extern uint i915_emit_decl(struct i915_fp_compile *p, 217 uint type, uint nr, uint d0_flags); 218 219 220 extern uint i915_emit_const1f(struct i915_fp_compile *p, float c0); 221 222 extern uint i915_emit_const2f(struct i915_fp_compile *p, 223 float c0, float c1); 224 225 extern uint i915_emit_const4fv(struct i915_fp_compile *p, 226 const float * c); 227 228 extern uint i915_emit_const4f(struct i915_fp_compile *p, 229 float c0, float c1, 230 float c2, float c3); 231 232 233 /*====================================================================== 234 * i915_fpc_translate.c 235 */ 236 237 extern void 238 i915_program_error(struct i915_fp_compile *p, const char *msg, ...); 239 240 241 /*====================================================================== 242 * i915_fpc_optimize.c 243 */ 244 245 246 struct i915_src_register 247 { 248 unsigned File : 4; /* TGSI_FILE_ */ 249 unsigned Indirect : 1; /* BOOL */ 250 unsigned Dimension : 1; /* BOOL */ 251 int Index : 16; /* SINT */ 252 unsigned SwizzleX : 3; /* TGSI_SWIZZLE_ */ 253 unsigned SwizzleY : 3; /* TGSI_SWIZZLE_ */ 254 unsigned SwizzleZ : 3; /* TGSI_SWIZZLE_ */ 255 unsigned SwizzleW : 3; /* TGSI_SWIZZLE_ */ 256 unsigned Absolute : 1; /* BOOL */ 257 unsigned Negate : 1; /* BOOL */ 258 }; 259 260 /* Additional swizzle supported in i915 */ 261 #define TGSI_SWIZZLE_ZERO 4 262 #define TGSI_SWIZZLE_ONE 5 263 264 struct i915_dst_register 265 { 266 unsigned File : 4; /* TGSI_FILE_ */ 267 unsigned WriteMask : 4; /* TGSI_WRITEMASK_ */ 268 unsigned Indirect : 1; /* BOOL */ 269 unsigned Dimension : 1; /* BOOL */ 270 int Index : 16; /* SINT */ 271 unsigned Padding : 6; 272 }; 273 274 275 struct i915_full_dst_register 276 { 277 struct i915_dst_register Register; 278 /* 279 struct tgsi_src_register Indirect; 280 struct tgsi_dimension Dimension; 281 struct tgsi_src_register DimIndirect; 282 */ 283 }; 284 285 struct i915_full_src_register 286 { 287 struct i915_src_register Register; 288 /* 289 struct tgsi_src_register Indirect; 290 struct tgsi_dimension Dimension; 291 struct tgsi_src_register DimIndirect; 292 */ 293 }; 294 295 struct i915_full_instruction 296 { 297 struct tgsi_instruction Instruction; 298 /* 299 struct tgsi_instruction_predicate Predicate; 300 struct tgsi_instruction_label Label; 301 */ 302 struct tgsi_instruction_texture Texture; 303 struct i915_full_dst_register Dst[1]; 304 struct i915_full_src_register Src[3]; 305 }; 306 307 308 union i915_full_token 309 { 310 struct tgsi_token Token; 311 struct tgsi_full_declaration FullDeclaration; 312 struct tgsi_full_immediate FullImmediate; 313 struct i915_full_instruction FullInstruction; 314 struct tgsi_full_property FullProperty; 315 }; 316 317 struct i915_token_list 318 { 319 union i915_full_token* Tokens; 320 unsigned NumTokens; 321 }; 322 323 extern struct i915_token_list* i915_optimize(const struct tgsi_token *tokens); 324 325 extern void i915_optimize_free(struct i915_token_list* tokens); 326 327 #endif 328