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 27#include "pipe/p_shader_tokens.h" 28#include "tgsi/tgsi_parse.h" 29#include "util/u_memory.h" 30 31#include "svga_tgsi_emit.h" 32 33 34/** 35 * Translate TGSI semantic info into SVGA3d semantic info. 36 * This is called for VS outputs and PS inputs only. 37 */ 38static boolean 39translate_vs_ps_semantic(struct svga_shader_emitter *emit, 40 struct tgsi_declaration_semantic semantic, 41 unsigned *usage, 42 unsigned *idx) 43{ 44 switch (semantic.Name) { 45 case TGSI_SEMANTIC_POSITION: 46 *idx = semantic.Index; 47 *usage = SVGA3D_DECLUSAGE_POSITION; 48 break; 49 case TGSI_SEMANTIC_COLOR: 50 *idx = semantic.Index; 51 *usage = SVGA3D_DECLUSAGE_COLOR; 52 break; 53 case TGSI_SEMANTIC_BCOLOR: 54 *idx = semantic.Index + 2; /* sharing with COLOR */ 55 *usage = SVGA3D_DECLUSAGE_COLOR; 56 break; 57 case TGSI_SEMANTIC_FOG: 58 *idx = 0; 59 assert(semantic.Index == 0); 60 *usage = SVGA3D_DECLUSAGE_TEXCOORD; 61 break; 62 case TGSI_SEMANTIC_PSIZE: 63 *idx = semantic.Index; 64 *usage = SVGA3D_DECLUSAGE_PSIZE; 65 break; 66 case TGSI_SEMANTIC_GENERIC: 67 *idx = svga_remap_generic_index(emit->key.generic_remap_table, 68 semantic.Index); 69 *usage = SVGA3D_DECLUSAGE_TEXCOORD; 70 break; 71 case TGSI_SEMANTIC_NORMAL: 72 *idx = semantic.Index; 73 *usage = SVGA3D_DECLUSAGE_NORMAL; 74 break; 75 case TGSI_SEMANTIC_CLIPDIST: 76 case TGSI_SEMANTIC_CLIPVERTEX: 77 /* XXX at this time we don't support clip distance or clip vertices */ 78 debug_warn_once("unsupported clip distance/vertex attribute\n"); 79 *usage = SVGA3D_DECLUSAGE_TEXCOORD; 80 *idx = 0; 81 return TRUE; 82 default: 83 assert(0); 84 *usage = SVGA3D_DECLUSAGE_TEXCOORD; 85 *idx = 0; 86 return FALSE; 87 } 88 89 return TRUE; 90} 91 92 93/** 94 * Emit a PS input (or VS depth/fog output) register declaration. 95 * For example, if usage = SVGA3D_DECLUSAGE_TEXCOORD, reg.num = 1, and 96 * index = 3, we'll emit "dcl_texcoord3 v1". 97 */ 98static boolean 99emit_decl(struct svga_shader_emitter *emit, 100 SVGA3dShaderDestToken reg, 101 unsigned usage, 102 unsigned index) 103{ 104 SVGA3DOpDclArgs dcl; 105 SVGA3dShaderInstToken opcode; 106 107 /* check values against bitfield sizes */ 108 assert(index < 16); 109 assert(usage <= SVGA3D_DECLUSAGE_MAX); 110 111 opcode = inst_token( SVGA3DOP_DCL ); 112 dcl.values[0] = 0; 113 dcl.values[1] = 0; 114 115 dcl.dst = reg; 116 dcl.usage = usage; 117 dcl.index = index; 118 dcl.values[0] |= 1<<31; 119 120 return (emit_instruction(emit, opcode) && 121 svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values))); 122} 123 124 125/** 126 * Emit declaration for PS front/back-face input register. 127 */ 128static boolean 129emit_vface_decl(struct svga_shader_emitter *emit) 130{ 131 if (!emit->emitted_vface) { 132 SVGA3dShaderDestToken reg = 133 dst_register(SVGA3DREG_MISCTYPE, SVGA3DMISCREG_FACE); 134 135 if (!emit_decl( emit, reg, 0, 0 )) 136 return FALSE; 137 138 emit->emitted_vface = TRUE; 139 } 140 return TRUE; 141} 142 143 144/** 145 * Emit PS input register to pass depth/fog coordinates. 146 * Note that this always goes into texcoord[0]. 147 */ 148static boolean 149ps30_input_emit_depth_fog( struct svga_shader_emitter *emit, 150 struct src_register *out ) 151{ 152 struct src_register reg; 153 154 if (emit->emitted_depth_fog) { 155 *out = emit->ps_depth_fog; 156 return TRUE; 157 } 158 159 if (emit->ps30_input_count >= SVGA3D_INPUTREG_MAX) 160 return FALSE; 161 162 reg = src_register( SVGA3DREG_INPUT, 163 emit->ps30_input_count++ ); 164 165 *out = emit->ps_depth_fog = reg; 166 167 emit->emitted_depth_fog = TRUE; 168 169 return emit_decl( emit, dst( reg ), SVGA3D_DECLUSAGE_TEXCOORD, 0 ); 170} 171 172 173/** 174 * Process a PS input declaration. 175 * We'll emit a declaration like "dcl_texcoord1 v2" 176 */ 177static boolean 178ps30_input(struct svga_shader_emitter *emit, 179 struct tgsi_declaration_semantic semantic, 180 unsigned idx) 181{ 182 unsigned usage, index; 183 SVGA3dShaderDestToken reg; 184 185 if (semantic.Name == TGSI_SEMANTIC_POSITION) { 186 187 emit->ps_true_pos = src_register( SVGA3DREG_MISCTYPE, 188 SVGA3DMISCREG_POSITION ); 189 emit->ps_true_pos.base.swizzle = TRANSLATE_SWIZZLE( TGSI_SWIZZLE_X, 190 TGSI_SWIZZLE_Y, 191 TGSI_SWIZZLE_Y, 192 TGSI_SWIZZLE_Y ); 193 reg = writemask( dst(emit->ps_true_pos), 194 TGSI_WRITEMASK_XY ); 195 emit->ps_reads_pos = TRUE; 196 197 if (emit->info.reads_z) { 198 emit->ps_temp_pos = dst_register( SVGA3DREG_TEMP, 199 emit->nr_hw_temp ); 200 201 emit->input_map[idx] = src_register( SVGA3DREG_TEMP, 202 emit->nr_hw_temp ); 203 emit->nr_hw_temp++; 204 205 if (!ps30_input_emit_depth_fog( emit, &emit->ps_depth_pos )) 206 return FALSE; 207 208 emit->ps_depth_pos.base.swizzle = TRANSLATE_SWIZZLE( TGSI_SWIZZLE_Z, 209 TGSI_SWIZZLE_Z, 210 TGSI_SWIZZLE_Z, 211 TGSI_SWIZZLE_W ); 212 } 213 else { 214 emit->input_map[idx] = emit->ps_true_pos; 215 } 216 217 return emit_decl( emit, reg, 0, 0 ); 218 } 219 else if (emit->key.fkey.light_twoside && 220 (semantic.Name == TGSI_SEMANTIC_COLOR)) { 221 222 if (!translate_vs_ps_semantic( emit, semantic, &usage, &index )) 223 return FALSE; 224 225 emit->internal_color_idx[emit->internal_color_count] = idx; 226 emit->input_map[idx] = src_register( SVGA3DREG_INPUT, emit->ps30_input_count ); 227 emit->ps30_input_count++; 228 emit->internal_color_count++; 229 230 reg = dst( emit->input_map[idx] ); 231 232 if (!emit_decl( emit, reg, usage, index )) 233 return FALSE; 234 235 semantic.Name = TGSI_SEMANTIC_BCOLOR; 236 if (!translate_vs_ps_semantic( emit, semantic, &usage, &index )) 237 return FALSE; 238 239 if (emit->ps30_input_count >= SVGA3D_INPUTREG_MAX) 240 return FALSE; 241 242 reg = dst_register( SVGA3DREG_INPUT, emit->ps30_input_count++ ); 243 244 if (!emit_decl( emit, reg, usage, index )) 245 return FALSE; 246 247 if (!emit_vface_decl( emit )) 248 return FALSE; 249 250 return TRUE; 251 } 252 else if (semantic.Name == TGSI_SEMANTIC_FACE) { 253 if (!emit_vface_decl( emit )) 254 return FALSE; 255 emit->emit_frontface = TRUE; 256 emit->internal_frontface_idx = idx; 257 return TRUE; 258 } 259 else if (semantic.Name == TGSI_SEMANTIC_FOG) { 260 261 assert(semantic.Index == 0); 262 263 if (!ps30_input_emit_depth_fog( emit, &emit->input_map[idx] )) 264 return FALSE; 265 266 emit->input_map[idx].base.swizzle = TRANSLATE_SWIZZLE( TGSI_SWIZZLE_X, 267 TGSI_SWIZZLE_X, 268 TGSI_SWIZZLE_X, 269 TGSI_SWIZZLE_X ); 270 271 return TRUE; 272 } 273 else { 274 275 if (!translate_vs_ps_semantic( emit, semantic, &usage, &index )) 276 return FALSE; 277 278 if (emit->ps30_input_count >= SVGA3D_INPUTREG_MAX) 279 return FALSE; 280 281 emit->input_map[idx] = src_register( SVGA3DREG_INPUT, emit->ps30_input_count++ ); 282 reg = dst( emit->input_map[idx] ); 283 284 if (!emit_decl( emit, reg, usage, index )) 285 return FALSE; 286 287 if (semantic.Name == TGSI_SEMANTIC_GENERIC && 288 emit->key.fkey.sprite_origin_lower_left && 289 index >= 1 && 290 emit->key.fkey.tex[index - 1].sprite_texgen) { 291 /* This is a sprite texture coord with lower-left origin. 292 * We need to invert the texture T coordinate since the SVGA3D 293 * device only supports an upper-left origin. 294 */ 295 unsigned unit = index - 1; 296 297 emit->inverted_texcoords |= (1 << unit); 298 299 /* save original texcoord reg */ 300 emit->ps_true_texcoord[unit] = emit->input_map[idx]; 301 302 /* this temp register will be the results of the MAD instruction */ 303 emit->ps_inverted_texcoord[unit] = 304 src_register(SVGA3DREG_TEMP, emit->nr_hw_temp); 305 emit->nr_hw_temp++; 306 307 emit->ps_inverted_texcoord_input[unit] = idx; 308 309 /* replace input_map entry with the temp register */ 310 emit->input_map[idx] = emit->ps_inverted_texcoord[unit]; 311 } 312 313 return TRUE; 314 } 315 316} 317 318 319/** 320 * Process a PS output declaration. 321 * Note that we don't actually emit a SVGA3DOpDcl for PS outputs. 322 */ 323static boolean 324ps30_output(struct svga_shader_emitter *emit, 325 struct tgsi_declaration_semantic semantic, 326 unsigned idx) 327{ 328 switch (semantic.Name) { 329 case TGSI_SEMANTIC_COLOR: 330 if (emit->unit == PIPE_SHADER_FRAGMENT && 331 emit->key.fkey.white_fragments) { 332 333 emit->output_map[idx] = dst_register( SVGA3DREG_TEMP, 334 emit->nr_hw_temp++ ); 335 emit->temp_col[idx] = emit->output_map[idx]; 336 emit->true_col[idx] = dst_register( SVGA3DREG_COLOROUT, 337 semantic.Index ); 338 } 339 else { 340 emit->output_map[idx] = dst_register( SVGA3DREG_COLOROUT, 341 semantic.Index ); 342 } 343 break; 344 case TGSI_SEMANTIC_POSITION: 345 emit->output_map[idx] = dst_register( SVGA3DREG_TEMP, 346 emit->nr_hw_temp++ ); 347 emit->temp_pos = emit->output_map[idx]; 348 emit->true_pos = dst_register( SVGA3DREG_DEPTHOUT, 349 semantic.Index ); 350 break; 351 default: 352 assert(0); 353 /* A wild stab in the dark. */ 354 emit->output_map[idx] = dst_register( SVGA3DREG_COLOROUT, 0 ); 355 break; 356 } 357 358 return TRUE; 359} 360 361 362/** 363 * Declare a VS input register. 364 * We still make up the input semantics the same as in 2.0 365 */ 366static boolean 367vs30_input(struct svga_shader_emitter *emit, 368 struct tgsi_declaration_semantic semantic, 369 unsigned idx) 370{ 371 SVGA3DOpDclArgs dcl; 372 SVGA3dShaderInstToken opcode; 373 unsigned usage, index; 374 375 opcode = inst_token( SVGA3DOP_DCL ); 376 dcl.values[0] = 0; 377 dcl.values[1] = 0; 378 379 emit->input_map[idx] = src_register( SVGA3DREG_INPUT, idx ); 380 dcl.dst = dst_register( SVGA3DREG_INPUT, idx ); 381 382 assert(dcl.dst.reserved0); 383 384 svga_generate_vdecl_semantics( idx, &usage, &index ); 385 386 dcl.usage = usage; 387 dcl.index = index; 388 dcl.values[0] |= 1<<31; 389 390 return (emit_instruction(emit, opcode) && 391 svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values))); 392} 393 394 395/** 396 * Declare VS output for holding depth/fog. 397 */ 398static boolean 399vs30_output_emit_depth_fog(struct svga_shader_emitter *emit, 400 SVGA3dShaderDestToken *out) 401{ 402 SVGA3dShaderDestToken reg; 403 404 if (emit->emitted_depth_fog) { 405 *out = emit->vs_depth_fog; 406 return TRUE; 407 } 408 409 reg = dst_register( SVGA3DREG_OUTPUT, emit->vs30_output_count++ ); 410 411 *out = emit->vs_depth_fog = reg; 412 413 emit->emitted_depth_fog = TRUE; 414 415 return emit_decl( emit, reg, SVGA3D_DECLUSAGE_TEXCOORD, 0 ); 416} 417 418 419/** 420 * Declare a VS output. 421 * VS3.0 outputs have proper declarations and semantic info for 422 * matching against PS inputs. 423 */ 424static boolean 425vs30_output(struct svga_shader_emitter *emit, 426 struct tgsi_declaration_semantic semantic, 427 unsigned idx) 428{ 429 SVGA3DOpDclArgs dcl; 430 SVGA3dShaderInstToken opcode; 431 unsigned usage, index; 432 433 opcode = inst_token( SVGA3DOP_DCL ); 434 dcl.values[0] = 0; 435 dcl.values[1] = 0; 436 437 if (!translate_vs_ps_semantic( emit, semantic, &usage, &index )) 438 return FALSE; 439 440 if (emit->vs30_output_count >= SVGA3D_OUTPUTREG_MAX) 441 return FALSE; 442 443 dcl.dst = dst_register( SVGA3DREG_OUTPUT, emit->vs30_output_count++ ); 444 dcl.usage = usage; 445 dcl.index = index; 446 dcl.values[0] |= 1<<31; 447 448 if (semantic.Name == TGSI_SEMANTIC_POSITION) { 449 assert(idx == 0); 450 emit->output_map[idx] = dst_register( SVGA3DREG_TEMP, 451 emit->nr_hw_temp++ ); 452 emit->temp_pos = emit->output_map[idx]; 453 emit->true_pos = dcl.dst; 454 455 /* Grab an extra output for the depth output */ 456 if (!vs30_output_emit_depth_fog( emit, &emit->depth_pos )) 457 return FALSE; 458 459 } 460 else if (semantic.Name == TGSI_SEMANTIC_PSIZE) { 461 emit->output_map[idx] = dst_register( SVGA3DREG_TEMP, 462 emit->nr_hw_temp++ ); 463 emit->temp_psiz = emit->output_map[idx]; 464 465 /* This has the effect of not declaring psiz (below) and not 466 * emitting the final MOV to true_psiz in the postamble. 467 */ 468 if (!emit->key.vkey.allow_psiz) 469 return TRUE; 470 471 emit->true_psiz = dcl.dst; 472 } 473 else if (semantic.Name == TGSI_SEMANTIC_FOG) { 474 /* 475 * Fog is shared with depth. 476 * So we need to decrement out_count since emit_depth_fog will increment it. 477 */ 478 emit->vs30_output_count--; 479 480 if (!vs30_output_emit_depth_fog( emit, &emit->output_map[idx] )) 481 return FALSE; 482 483 return TRUE; 484 } 485 else { 486 emit->output_map[idx] = dcl.dst; 487 } 488 489 return (emit_instruction(emit, opcode) && 490 svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values))); 491} 492 493 494static boolean 495ps30_sampler( struct svga_shader_emitter *emit, 496 struct tgsi_declaration_semantic semantic, 497 unsigned idx ) 498{ 499 SVGA3DOpDclArgs dcl; 500 SVGA3dShaderInstToken opcode; 501 502 opcode = inst_token( SVGA3DOP_DCL ); 503 dcl.values[0] = 0; 504 dcl.values[1] = 0; 505 506 dcl.dst = dst_register( SVGA3DREG_SAMPLER, idx ); 507 dcl.type = svga_tgsi_sampler_type( emit, idx ); 508 dcl.values[0] |= 1<<31; 509 510 return (emit_instruction(emit, opcode) && 511 svga_shader_emit_dwords( emit, dcl.values, Elements(dcl.values))); 512} 513 514 515boolean 516svga_translate_decl_sm30( struct svga_shader_emitter *emit, 517 const struct tgsi_full_declaration *decl ) 518{ 519 unsigned first = decl->Range.First; 520 unsigned last = decl->Range.Last; 521 unsigned idx; 522 523 for( idx = first; idx <= last; idx++ ) { 524 boolean ok; 525 526 switch (decl->Declaration.File) { 527 case TGSI_FILE_SAMPLER: 528 assert (emit->unit == PIPE_SHADER_FRAGMENT); 529 ok = ps30_sampler( emit, decl->Semantic, idx ); 530 break; 531 532 case TGSI_FILE_INPUT: 533 if (emit->unit == PIPE_SHADER_VERTEX) 534 ok = vs30_input( emit, decl->Semantic, idx ); 535 else 536 ok = ps30_input( emit, decl->Semantic, idx ); 537 break; 538 539 case TGSI_FILE_OUTPUT: 540 if (emit->unit == PIPE_SHADER_VERTEX) 541 ok = vs30_output( emit, decl->Semantic, idx ); 542 else 543 ok = ps30_output( emit, decl->Semantic, idx ); 544 break; 545 546 default: 547 /* don't need to declare other vars */ 548 ok = TRUE; 549 } 550 551 if (!ok) 552 return FALSE; 553 } 554 555 return TRUE; 556} 557