1/************************************************************************** 2 * 3 * Copyright 2003 VMware, Inc. 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 VMWARE 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#ifndef I915_FPC_H 29#define I915_FPC_H 30 31#include "i915_context.h" 32#include "i915_reg.h" 33 34#include "pipe/p_shader_tokens.h" 35 36#include "tgsi/tgsi_parse.h" 37 38struct nir_shader; 39 40#define I915_PROGRAM_SIZE 192 41 42/** 43 * Program translation state 44 */ 45struct i915_fp_compile { 46 struct i915_fragment_shader *shader; /* the shader we're compiling */ 47 48 bool used_constants[I915_MAX_CONSTANT]; 49 50 /** maps TGSI immediate index to constant slot */ 51 uint32_t num_immediates; 52 uint32_t immediates_map[I915_MAX_CONSTANT]; 53 float immediates[I915_MAX_CONSTANT][4]; 54 55 bool first_instruction; 56 57 uint32_t declarations[I915_PROGRAM_SIZE]; 58 uint32_t program[I915_PROGRAM_SIZE]; 59 60 uint32_t *csr; /**< Cursor, points into program. */ 61 62 uint32_t *decl; /**< Cursor, points into declarations. */ 63 64 uint32_t decl_s; /**< flags for which s regs need to be decl'd */ 65 uint32_t decl_t; /**< flags for which t regs need to be decl'd */ 66 67 uint32_t temp_flag; /**< Tracks temporary regs which are in use */ 68 uint32_t utemp_flag; /**< Tracks TYPE_U temporary regs which are in use */ 69 70 uint32_t register_phases[I915_MAX_TEMPORARY]; 71 uint32_t nr_tex_indirect; 72 uint32_t nr_tex_insn; 73 uint32_t nr_alu_insn; 74 uint32_t nr_decl_insn; 75 76 bool log_program_errors; 77 bool error; /**< Set if i915_program_error() is called */ 78 uint32_t NumNativeInstructions; 79 uint32_t NumNativeAluInstructions; 80 uint32_t NumNativeTexInstructions; 81 uint32_t NumNativeTexIndirections; 82}; 83 84/* Having zero and one in here makes the definition of swizzle a lot 85 * easier. 86 */ 87#define UREG_TYPE_SHIFT 29 88#define UREG_NR_SHIFT 24 89#define UREG_CHANNEL_X_NEGATE_SHIFT 23 90#define UREG_CHANNEL_X_SHIFT 20 91#define UREG_CHANNEL_Y_NEGATE_SHIFT 19 92#define UREG_CHANNEL_Y_SHIFT 16 93#define UREG_CHANNEL_Z_NEGATE_SHIFT 15 94#define UREG_CHANNEL_Z_SHIFT 12 95#define UREG_CHANNEL_W_NEGATE_SHIFT 11 96#define UREG_CHANNEL_W_SHIFT 8 97#define UREG_CHANNEL_ZERO_NEGATE_MBZ 5 98#define UREG_CHANNEL_ZERO_SHIFT 4 99#define UREG_CHANNEL_ONE_NEGATE_MBZ 1 100#define UREG_CHANNEL_ONE_SHIFT 0 101 102#define UREG_BAD 0xffffffff /* not a valid ureg */ 103 104#define X SRC_X 105#define Y SRC_Y 106#define Z SRC_Z 107#define W SRC_W 108#define ZERO SRC_ZERO 109#define ONE SRC_ONE 110 111/* Construct a ureg: 112 */ 113#define UREG(type, nr) \ 114 (((type) << UREG_TYPE_SHIFT) | ((nr) << UREG_NR_SHIFT) | \ 115 (X << UREG_CHANNEL_X_SHIFT) | (Y << UREG_CHANNEL_Y_SHIFT) | \ 116 (Z << UREG_CHANNEL_Z_SHIFT) | (W << UREG_CHANNEL_W_SHIFT) | \ 117 (ZERO << UREG_CHANNEL_ZERO_SHIFT) | (ONE << UREG_CHANNEL_ONE_SHIFT)) 118 119#define GET_CHANNEL_SRC(reg, channel) ((reg << (channel * 4)) & (0xf << 20)) 120#define CHANNEL_SRC(src, channel) (src >> (channel * 4)) 121 122#define GET_UREG_TYPE(reg) (((reg) >> UREG_TYPE_SHIFT) & REG_TYPE_MASK) 123#define GET_UREG_NR(reg) (((reg) >> UREG_NR_SHIFT) & REG_NR_MASK) 124 125#define UREG_XYZW_CHANNEL_MASK 0x00ffff00 126 127/* One neat thing about the UREG representation: 128 */ 129static inline int 130swizzle(int reg, uint32_t x, uint32_t y, uint32_t z, uint32_t w) 131{ 132 assert(x <= SRC_ONE); 133 assert(y <= SRC_ONE); 134 assert(z <= SRC_ONE); 135 assert(w <= SRC_ONE); 136 return ((reg & ~UREG_XYZW_CHANNEL_MASK) | 137 CHANNEL_SRC(GET_CHANNEL_SRC(reg, x), 0) | 138 CHANNEL_SRC(GET_CHANNEL_SRC(reg, y), 1) | 139 CHANNEL_SRC(GET_CHANNEL_SRC(reg, z), 2) | 140 CHANNEL_SRC(GET_CHANNEL_SRC(reg, w), 3)); 141} 142 143#define A0_DEST(reg) (((reg)&UREG_TYPE_NR_MASK) >> UREG_A0_DEST_SHIFT_LEFT) 144#define D0_DEST(reg) (((reg)&UREG_TYPE_NR_MASK) >> UREG_A0_DEST_SHIFT_LEFT) 145#define T0_DEST(reg) (((reg)&UREG_TYPE_NR_MASK) >> UREG_A0_DEST_SHIFT_LEFT) 146#define A0_SRC0(reg) (((reg)&UREG_MASK) >> UREG_A0_SRC0_SHIFT_LEFT) 147#define A1_SRC0(reg) (((reg)&UREG_MASK) << UREG_A1_SRC0_SHIFT_RIGHT) 148#define A1_SRC1(reg) (((reg)&UREG_MASK) >> UREG_A1_SRC1_SHIFT_LEFT) 149#define A2_SRC1(reg) (((reg)&UREG_MASK) << UREG_A2_SRC1_SHIFT_RIGHT) 150#define A2_SRC2(reg) (((reg)&UREG_MASK) >> UREG_A2_SRC2_SHIFT_LEFT) 151 152/* These are special, and don't have swizzle/negate bits. 153 */ 154#define T0_SAMPLER(reg) (GET_UREG_NR(reg) << T0_SAMPLER_NR_SHIFT) 155#define T1_ADDRESS_REG(reg) \ 156 ((GET_UREG_NR(reg) << T1_ADDRESS_REG_NR_SHIFT) | \ 157 (GET_UREG_TYPE(reg) << T1_ADDRESS_REG_TYPE_SHIFT)) 158 159/* Macros for translating UREG's into the various register fields used 160 * by the I915 programmable unit. 161 */ 162#define UREG_A0_DEST_SHIFT_LEFT (UREG_TYPE_SHIFT - A0_DEST_TYPE_SHIFT) 163#define UREG_A0_SRC0_SHIFT_LEFT (UREG_TYPE_SHIFT - A0_SRC0_TYPE_SHIFT) 164#define UREG_A1_SRC0_SHIFT_RIGHT \ 165 (A1_SRC0_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT) 166#define UREG_A1_SRC1_SHIFT_LEFT (UREG_TYPE_SHIFT - A1_SRC1_TYPE_SHIFT) 167#define UREG_A2_SRC1_SHIFT_RIGHT \ 168 (A2_SRC1_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT) 169#define UREG_A2_SRC2_SHIFT_LEFT (UREG_TYPE_SHIFT - A2_SRC2_TYPE_SHIFT) 170 171#define UREG_MASK 0xffffff00 172#define UREG_TYPE_NR_MASK \ 173 ((REG_TYPE_MASK << UREG_TYPE_SHIFT) | (REG_NR_MASK << UREG_NR_SHIFT)) 174 175/*********************************************************************** 176 * Public interface for the compiler 177 */ 178extern void i915_translate_fragment_program(struct i915_context *i915, 179 struct i915_fragment_shader *fs); 180 181extern uint32_t i915_get_temp(struct i915_fp_compile *p); 182extern uint32_t i915_get_utemp(struct i915_fp_compile *p); 183extern void i915_release_utemps(struct i915_fp_compile *p); 184 185extern uint32_t i915_emit_texld(struct i915_fp_compile *p, uint32_t dest, 186 uint32_t destmask, uint32_t sampler, 187 uint32_t coord, uint32_t op, 188 uint32_t coord_mask); 189 190extern uint32_t i915_emit_arith(struct i915_fp_compile *p, uint32_t op, 191 uint32_t dest, uint32_t mask, uint32_t saturate, 192 uint32_t src0, uint32_t src1, uint32_t src2); 193 194extern uint32_t i915_emit_decl(struct i915_fp_compile *p, uint32_t type, 195 uint32_t nr, uint32_t d0_flags); 196 197extern uint32_t i915_emit_const1f(struct i915_fp_compile *p, float c0); 198 199extern uint32_t i915_emit_const2f(struct i915_fp_compile *p, float c0, 200 float c1); 201 202extern uint32_t i915_emit_const4fv(struct i915_fp_compile *p, const float *c); 203 204extern uint32_t i915_emit_const4f(struct i915_fp_compile *p, float c0, float c1, 205 float c2, float c3); 206 207/*====================================================================== 208 * i915_fpc_translate.c 209 */ 210 211extern void i915_program_error(struct i915_fp_compile *p, const char *msg, ...); 212 213/*====================================================================== 214 * i915_fpc_optimize.c 215 */ 216 217struct i915_src_register { 218 unsigned File : 4; /* TGSI_FILE_ */ 219 unsigned Indirect : 1; /* BOOL */ 220 unsigned Dimension : 1; /* BOOL */ 221 int Index : 16; /* SINT */ 222 unsigned SwizzleX : 3; /* TGSI_SWIZZLE_ */ 223 unsigned SwizzleY : 3; /* TGSI_SWIZZLE_ */ 224 unsigned SwizzleZ : 3; /* TGSI_SWIZZLE_ */ 225 unsigned SwizzleW : 3; /* TGSI_SWIZZLE_ */ 226 unsigned Absolute : 1; /* BOOL */ 227 unsigned Negate : 1; /* BOOL */ 228}; 229 230/* Additional swizzle supported in i915 */ 231#define TGSI_SWIZZLE_ZERO 4 232#define TGSI_SWIZZLE_ONE 5 233 234struct i915_dst_register { 235 unsigned File : 4; /* TGSI_FILE_ */ 236 unsigned WriteMask : 4; /* TGSI_WRITEMASK_ */ 237 unsigned Indirect : 1; /* BOOL */ 238 unsigned Dimension : 1; /* BOOL */ 239 int Index : 16; /* SINT */ 240 unsigned Padding : 6; 241}; 242 243struct i915_full_dst_register { 244 struct i915_dst_register Register; 245 /* 246 struct tgsi_ind_register Indirect; 247 struct tgsi_dimension Dimension; 248 struct tgsi_ind_register DimIndirect; 249 */ 250}; 251 252struct i915_full_src_register { 253 struct i915_src_register Register; 254 /* 255 struct tgsi_ind_register Indirect; 256 struct tgsi_dimension Dimension; 257 struct tgsi_ind_register DimIndirect; 258 */ 259}; 260 261struct i915_full_instruction { 262 struct tgsi_instruction Instruction; 263 /* 264 struct tgsi_instruction_label Label; 265 */ 266 struct tgsi_instruction_texture Texture; 267 struct i915_full_dst_register Dst[1]; 268 struct i915_full_src_register Src[3]; 269}; 270 271union i915_full_token { 272 struct tgsi_token Token; 273 struct tgsi_full_declaration FullDeclaration; 274 struct tgsi_full_immediate FullImmediate; 275 struct i915_full_instruction FullInstruction; 276 struct tgsi_full_property FullProperty; 277}; 278 279struct i915_token_list { 280 union i915_full_token *Tokens; 281 unsigned NumTokens; 282}; 283 284extern struct i915_token_list *i915_optimize(const struct tgsi_token *tokens); 285 286extern void i915_optimize_free(struct i915_token_list *tokens); 287 288extern uint32_t i915_coord_mask(enum tgsi_opcode opcode, enum tgsi_texture_type tex); 289 290#endif 291