1 /********************************************************** 2 * Copyright 2008-2009 VMware, Inc. All rights reserved. 3 * 4 * Permission is hereby granted, free of charge, to any person 5 * obtaining a copy of this software and associated documentation 6 * files (the "Software"), to deal in the Software without 7 * restriction, including without limitation the rights to use, copy, 8 * modify, merge, publish, distribute, sublicense, and/or sell copies 9 * of the Software, and to permit persons to whom the Software is 10 * furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be 13 * included in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 * 24 **********************************************************/ 25 26 #ifndef SVGA_TGSI_EMIT_H 27 #define SVGA_TGSI_EMIT_H 28 29 #include "tgsi/tgsi_scan.h" 30 #include "svga_hw_reg.h" 31 #include "svga_shader.h" 32 #include "svga_tgsi.h" 33 #include "svga3d_shaderdefs.h" 34 35 struct src_register 36 { 37 SVGA3dShaderSrcToken base; 38 SVGA3dShaderSrcToken indirect; 39 }; 40 41 42 struct svga_arl_consts 43 { 44 int number; 45 int idx; 46 int swizzle; 47 int arl_num; 48 }; 49 50 51 /** 52 * This is the context/state used during TGSI->SVGA shader translation. 53 */ 54 struct svga_shader_emitter 55 { 56 unsigned size; 57 char *buf; 58 char *ptr; 59 60 struct svga_compile_key key; 61 struct tgsi_shader_info info; 62 int unit; 63 64 int imm_start; 65 66 int nr_hw_float_const; 67 int nr_hw_int_const; 68 int nr_hw_temp; 69 70 int insn_offset; 71 72 int internal_temp_count; 73 int internal_imm_count; 74 75 int internal_color_idx[2]; /* diffuse, specular */ 76 int internal_color_count; 77 78 boolean emitted_vface; 79 boolean emit_frontface; 80 int internal_frontface_idx; 81 82 int ps30_input_count; 83 int vs30_output_count; 84 85 int dynamic_branching_level; 86 87 unsigned num_output_writes; 88 boolean constant_color_output; 89 90 boolean in_main_func; 91 92 boolean created_common_immediate; 93 int common_immediate_idx[2]; 94 95 boolean created_loop_const; 96 int loop_const_idx; 97 98 unsigned inverted_texcoords; /**< bitmask of which texcoords are flipped */ 99 struct src_register ps_true_texcoord[PIPE_MAX_ATTRIBS]; 100 struct src_register ps_inverted_texcoord[PIPE_MAX_ATTRIBS]; 101 unsigned ps_inverted_texcoord_input[PIPE_MAX_ATTRIBS]; 102 103 unsigned label[32]; 104 unsigned nr_labels; 105 106 /** input/output register mappings, indexed by register number */ 107 struct src_register input_map[PIPE_MAX_ATTRIBS]; 108 SVGA3dShaderDestToken output_map[PIPE_MAX_ATTRIBS]; 109 110 boolean ps_reads_pos; 111 boolean emitted_depth_fog; 112 struct src_register ps_true_pos; 113 struct src_register ps_depth_pos; 114 SVGA3dShaderDestToken ps_temp_pos; 115 116 /* shared input for depth and fog */ 117 struct src_register ps_depth_fog; 118 119 struct src_register imm_0055; 120 SVGA3dShaderDestToken temp_pos; 121 SVGA3dShaderDestToken true_pos; 122 SVGA3dShaderDestToken depth_pos; 123 124 /* shared output for depth and fog */ 125 SVGA3dShaderDestToken vs_depth_fog; 126 127 /* PS output colors (indexed by color semantic index) */ 128 SVGA3dShaderDestToken temp_color_output[PIPE_MAX_COLOR_BUFS]; 129 SVGA3dShaderDestToken true_color_output[PIPE_MAX_COLOR_BUFS]; 130 131 SVGA3dShaderDestToken temp_psiz; 132 SVGA3dShaderDestToken true_psiz; 133 134 struct svga_arl_consts arl_consts[12]; 135 int num_arl_consts; 136 int current_arl; 137 138 unsigned pstipple_sampler_unit; 139 140 int num_samplers; 141 uint8_t sampler_target[PIPE_MAX_SAMPLERS]; 142 }; 143 144 145 boolean 146 svga_shader_emit_dword(struct svga_shader_emitter *emit, unsigned dword); 147 148 boolean 149 svga_shader_emit_dwords(struct svga_shader_emitter *emit, 150 const unsigned *dwords, unsigned nr); 151 152 boolean 153 svga_shader_emit_opcode(struct svga_shader_emitter *emit, 154 unsigned opcode); 155 156 boolean 157 svga_shader_emit_instructions(struct svga_shader_emitter *emit, 158 const struct tgsi_token *tokens); 159 160 boolean 161 svga_shader_emit_samplers_decl(struct svga_shader_emitter *emit); 162 163 boolean 164 svga_translate_decl_sm30(struct svga_shader_emitter *emit, 165 const struct tgsi_full_declaration *decl); 166 167 168 #define TRANSLATE_SWIZZLE(x,y,z,w) ((x) | ((y) << 2) | ((z) << 4) | ((w) << 6)) 169 #define SWIZZLE_XYZW \ 170 TRANSLATE_SWIZZLE(TGSI_SWIZZLE_X,TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Z,TGSI_SWIZZLE_W) 171 #define SWIZZLE_XXXX \ 172 TRANSLATE_SWIZZLE(TGSI_SWIZZLE_X,TGSI_SWIZZLE_X,TGSI_SWIZZLE_X,TGSI_SWIZZLE_X) 173 #define SWIZZLE_YYYY \ 174 TRANSLATE_SWIZZLE(TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Y) 175 #define SWIZZLE_ZZZZ \ 176 TRANSLATE_SWIZZLE(TGSI_SWIZZLE_Z,TGSI_SWIZZLE_Z,TGSI_SWIZZLE_Z,TGSI_SWIZZLE_Z) 177 #define SWIZZLE_WWWW \ 178 TRANSLATE_SWIZZLE(TGSI_SWIZZLE_W,TGSI_SWIZZLE_W,TGSI_SWIZZLE_W,TGSI_SWIZZLE_W) 179 180 181 /** Emit the given SVGA3dShaderInstToken opcode */ 182 static inline boolean 183 emit_instruction(struct svga_shader_emitter *emit, 184 SVGA3dShaderInstToken opcode) 185 { 186 return svga_shader_emit_opcode(emit, opcode.value); 187 } 188 189 190 /** Generate a SVGA3dShaderInstToken for the given SVGA3D shader opcode */ 191 static inline SVGA3dShaderInstToken 192 inst_token(unsigned opcode) 193 { 194 SVGA3dShaderInstToken inst; 195 196 inst.value = 0; 197 inst.op = opcode; 198 199 return inst; 200 } 201 202 203 /** 204 * Generate a SVGA3dShaderInstToken for the given SVGA3D shader opcode 205 * with the predication flag set. 206 */ 207 static inline SVGA3dShaderInstToken 208 inst_token_predicated(unsigned opcode) 209 { 210 SVGA3dShaderInstToken inst; 211 212 inst.value = 0; 213 inst.op = opcode; 214 inst.predicated = 1; 215 216 return inst; 217 } 218 219 220 /** 221 * Generate a SVGA3dShaderInstToken for a SETP instruction (set predicate) 222 * using the given comparison operator (one of SVGA3DOPCOMP_xx). 223 */ 224 static inline SVGA3dShaderInstToken 225 inst_token_setp(unsigned operator) 226 { 227 SVGA3dShaderInstToken inst; 228 229 inst.value = 0; 230 inst.op = SVGA3DOP_SETP; 231 inst.control = operator; 232 233 return inst; 234 } 235 236 237 /** 238 * Create an instance of a SVGA3dShaderDestToken. 239 * Note that this function is used to create tokens for output registers, 240 * temp registers AND constants (see emit_def_const()). 241 */ 242 static inline SVGA3dShaderDestToken 243 dst_register(unsigned file, int number) 244 { 245 SVGA3dShaderDestToken dest; 246 247 /* check values against bitfield sizes */ 248 assert(number < (1 << 11)); 249 assert(file <= SVGA3DREG_PREDICATE); 250 251 dest.value = 0; 252 dest.num = number; 253 dest.type_upper = file >> 3; 254 dest.relAddr = 0; 255 dest.reserved1 = 0; 256 dest.mask = 0xf; 257 dest.dstMod = 0; 258 dest.shfScale = 0; 259 dest.type_lower = file & 0x7; 260 dest.reserved0 = 1; /* is_reg */ 261 262 return dest; 263 } 264 265 266 /** 267 * Apply a writemask to the given SVGA3dShaderDestToken, returning a 268 * new SVGA3dShaderDestToken. 269 */ 270 static inline SVGA3dShaderDestToken 271 writemask(SVGA3dShaderDestToken dest, unsigned mask) 272 { 273 assert(dest.mask & mask); 274 dest.mask &= mask; 275 return dest; 276 } 277 278 279 /** Create a SVGA3dShaderSrcToken given a register file and number */ 280 static inline SVGA3dShaderSrcToken 281 src_token(unsigned file, int number) 282 { 283 SVGA3dShaderSrcToken src; 284 285 /* check values against bitfield sizes */ 286 assert(number < (1 << 11)); 287 assert(file <= SVGA3DREG_PREDICATE); 288 289 src.value = 0; 290 src.num = number; 291 src.type_upper = file >> 3; 292 src.relAddr = 0; 293 src.reserved1 = 0; 294 src.swizzle = SWIZZLE_XYZW; 295 src.srcMod = 0; 296 src.type_lower = file & 0x7; 297 src.reserved0 = 1; /* is_reg */ 298 299 return src; 300 } 301 302 303 /** Create a src_register given a register file and register number */ 304 static inline struct src_register 305 src_register(unsigned file, int number) 306 { 307 struct src_register src; 308 309 src.base = src_token(file, number); 310 src.indirect.value = 0; 311 312 return src; 313 } 314 315 /** Translate src_register into SVGA3dShaderDestToken */ 316 static inline SVGA3dShaderDestToken 317 dst(struct src_register src) 318 { 319 return dst_register(SVGA3dShaderGetRegType(src.base.value), src.base.num); 320 } 321 322 323 /** Translate SVGA3dShaderDestToken to a src_register */ 324 static inline struct src_register 325 src(SVGA3dShaderDestToken dst) 326 { 327 return src_register(SVGA3dShaderGetRegType(dst.value), dst.num); 328 } 329 330 #endif 331