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 */ 50struct 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 */ 139static INLINE int 140swizzle(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 */ 190extern void 191i915_translate_fragment_program( struct i915_context *i915, 192 struct i915_fragment_shader *fs); 193 194 195 196extern uint i915_get_temp(struct i915_fp_compile *p); 197extern uint i915_get_utemp(struct i915_fp_compile *p); 198extern void i915_release_utemps(struct i915_fp_compile *p); 199 200 201extern 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 209extern 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 216extern uint i915_emit_decl(struct i915_fp_compile *p, 217 uint type, uint nr, uint d0_flags); 218 219 220extern uint i915_emit_const1f(struct i915_fp_compile *p, float c0); 221 222extern uint i915_emit_const2f(struct i915_fp_compile *p, 223 float c0, float c1); 224 225extern uint i915_emit_const4fv(struct i915_fp_compile *p, 226 const float * c); 227 228extern 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 237extern void 238i915_program_error(struct i915_fp_compile *p, const char *msg, ...); 239 240 241/*====================================================================== 242 * i915_fpc_optimize.c 243 */ 244 245 246struct 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 264struct 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 275struct 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 285struct 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 295struct 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 308union 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 317struct i915_token_list 318{ 319 union i915_full_token* Tokens; 320 unsigned NumTokens; 321}; 322 323extern struct i915_token_list* i915_optimize(const struct tgsi_token *tokens); 324 325extern void i915_optimize_free(struct i915_token_list* tokens); 326 327#endif 328