1 /************************************************************************** 2 * 3 * Copyright 2007-2008 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 * \author 30 * Michal Krol, 31 * Keith Whitwell 32 */ 33 34 #include "pipe/p_compiler.h" 35 #include "pipe/p_context.h" 36 #include "pipe/p_screen.h" 37 #include "pipe/p_shader_tokens.h" 38 #include "pipe/p_state.h" 39 #include "tgsi/tgsi_ureg.h" 40 #include "st_mesa_to_tgsi.h" 41 #include "st_context.h" 42 #include "program/prog_instruction.h" 43 #include "program/prog_parameter.h" 44 #include "util/u_debug.h" 45 #include "util/u_math.h" 46 #include "util/u_memory.h" 47 48 49 #define PROGRAM_ANY_CONST ((1 << PROGRAM_LOCAL_PARAM) | \ 50 (1 << PROGRAM_ENV_PARAM) | \ 51 (1 << PROGRAM_STATE_VAR) | \ 52 (1 << PROGRAM_NAMED_PARAM) | \ 53 (1 << PROGRAM_CONSTANT) | \ 54 (1 << PROGRAM_UNIFORM)) 55 56 57 struct label { 58 unsigned branch_target; 59 unsigned token; 60 }; 61 62 63 /** 64 * Intermediate state used during shader translation. 65 */ 66 struct st_translate { 67 struct ureg_program *ureg; 68 69 struct ureg_dst temps[MAX_PROGRAM_TEMPS]; 70 struct ureg_src *constants; 71 struct ureg_dst outputs[PIPE_MAX_SHADER_OUTPUTS]; 72 struct ureg_src inputs[PIPE_MAX_SHADER_INPUTS]; 73 struct ureg_dst address[1]; 74 struct ureg_src samplers[PIPE_MAX_SAMPLERS]; 75 struct ureg_src systemValues[SYSTEM_VALUE_MAX]; 76 77 const GLuint *inputMapping; 78 const GLuint *outputMapping; 79 80 /* For every instruction that contains a label (eg CALL), keep 81 * details so that we can go back afterwards and emit the correct 82 * tgsi instruction number for each label. 83 */ 84 struct label *labels; 85 unsigned labels_size; 86 unsigned labels_count; 87 88 /* Keep a record of the tgsi instruction number that each mesa 89 * instruction starts at, will be used to fix up labels after 90 * translation. 91 */ 92 unsigned *insn; 93 unsigned insn_size; 94 unsigned insn_count; 95 96 unsigned procType; /**< TGSI_PROCESSOR_VERTEX/FRAGMENT */ 97 98 boolean error; 99 }; 100 101 102 /** Map Mesa's SYSTEM_VALUE_x to TGSI_SEMANTIC_x */ 103 static unsigned mesa_sysval_to_semantic[SYSTEM_VALUE_MAX] = { 104 TGSI_SEMANTIC_FACE, 105 TGSI_SEMANTIC_VERTEXID, 106 TGSI_SEMANTIC_INSTANCEID 107 }; 108 109 110 /** 111 * Make note of a branch to a label in the TGSI code. 112 * After we've emitted all instructions, we'll go over the list 113 * of labels built here and patch the TGSI code with the actual 114 * location of each label. 115 */ 116 static unsigned *get_label( struct st_translate *t, 117 unsigned branch_target ) 118 { 119 unsigned i; 120 121 if (t->labels_count + 1 >= t->labels_size) { 122 t->labels_size = 1 << (util_logbase2(t->labels_size) + 1); 123 t->labels = realloc(t->labels, t->labels_size * sizeof t->labels[0]); 124 if (t->labels == NULL) { 125 static unsigned dummy; 126 t->error = TRUE; 127 return &dummy; 128 } 129 } 130 131 i = t->labels_count++; 132 t->labels[i].branch_target = branch_target; 133 return &t->labels[i].token; 134 } 135 136 137 /** 138 * Called prior to emitting the TGSI code for each Mesa instruction. 139 * Allocate additional space for instructions if needed. 140 * Update the insn[] array so the next Mesa instruction points to 141 * the next TGSI instruction. 142 */ 143 static void set_insn_start( struct st_translate *t, 144 unsigned start ) 145 { 146 if (t->insn_count + 1 >= t->insn_size) { 147 t->insn_size = 1 << (util_logbase2(t->insn_size) + 1); 148 t->insn = realloc(t->insn, t->insn_size * sizeof t->insn[0]); 149 if (t->insn == NULL) { 150 t->error = TRUE; 151 return; 152 } 153 } 154 155 t->insn[t->insn_count++] = start; 156 } 157 158 159 /** 160 * Map a Mesa dst register to a TGSI ureg_dst register. 161 */ 162 static struct ureg_dst 163 dst_register( struct st_translate *t, 164 gl_register_file file, 165 GLuint index ) 166 { 167 switch( file ) { 168 case PROGRAM_UNDEFINED: 169 return ureg_dst_undef(); 170 171 case PROGRAM_TEMPORARY: 172 if (ureg_dst_is_undef(t->temps[index])) 173 t->temps[index] = ureg_DECL_temporary( t->ureg ); 174 175 return t->temps[index]; 176 177 case PROGRAM_OUTPUT: 178 if (t->procType == TGSI_PROCESSOR_VERTEX) 179 assert(index < VERT_RESULT_MAX); 180 else if (t->procType == TGSI_PROCESSOR_FRAGMENT) 181 assert(index < FRAG_RESULT_MAX); 182 else 183 assert(index < GEOM_RESULT_MAX); 184 185 assert(t->outputMapping[index] < Elements(t->outputs)); 186 187 return t->outputs[t->outputMapping[index]]; 188 189 case PROGRAM_ADDRESS: 190 return t->address[index]; 191 192 default: 193 debug_assert( 0 ); 194 return ureg_dst_undef(); 195 } 196 } 197 198 199 /** 200 * Map a Mesa src register to a TGSI ureg_src register. 201 */ 202 static struct ureg_src 203 src_register( struct st_translate *t, 204 gl_register_file file, 205 GLint index ) 206 { 207 switch( file ) { 208 case PROGRAM_UNDEFINED: 209 return ureg_src_undef(); 210 211 case PROGRAM_TEMPORARY: 212 assert(index >= 0); 213 assert(index < Elements(t->temps)); 214 if (ureg_dst_is_undef(t->temps[index])) 215 t->temps[index] = ureg_DECL_temporary( t->ureg ); 216 return ureg_src(t->temps[index]); 217 218 case PROGRAM_NAMED_PARAM: 219 case PROGRAM_ENV_PARAM: 220 case PROGRAM_LOCAL_PARAM: 221 case PROGRAM_UNIFORM: 222 assert(index >= 0); 223 return t->constants[index]; 224 case PROGRAM_STATE_VAR: 225 case PROGRAM_CONSTANT: /* ie, immediate */ 226 if (index < 0) 227 return ureg_DECL_constant( t->ureg, 0 ); 228 else 229 return t->constants[index]; 230 231 case PROGRAM_INPUT: 232 assert(t->inputMapping[index] < Elements(t->inputs)); 233 return t->inputs[t->inputMapping[index]]; 234 235 case PROGRAM_OUTPUT: 236 assert(t->outputMapping[index] < Elements(t->outputs)); 237 return ureg_src(t->outputs[t->outputMapping[index]]); /* not needed? */ 238 239 case PROGRAM_ADDRESS: 240 return ureg_src(t->address[index]); 241 242 case PROGRAM_SYSTEM_VALUE: 243 assert(index < Elements(t->systemValues)); 244 return t->systemValues[index]; 245 246 default: 247 debug_assert( 0 ); 248 return ureg_src_undef(); 249 } 250 } 251 252 253 /** 254 * Map mesa texture target to TGSI texture target. 255 */ 256 unsigned 257 st_translate_texture_target( GLuint textarget, 258 GLboolean shadow ) 259 { 260 if (shadow) { 261 switch( textarget ) { 262 case TEXTURE_1D_INDEX: return TGSI_TEXTURE_SHADOW1D; 263 case TEXTURE_2D_INDEX: return TGSI_TEXTURE_SHADOW2D; 264 case TEXTURE_RECT_INDEX: return TGSI_TEXTURE_SHADOWRECT; 265 case TEXTURE_1D_ARRAY_INDEX: return TGSI_TEXTURE_SHADOW1D_ARRAY; 266 case TEXTURE_2D_ARRAY_INDEX: return TGSI_TEXTURE_SHADOW2D_ARRAY; 267 case TEXTURE_CUBE_INDEX: return TGSI_TEXTURE_SHADOWCUBE; 268 default: break; 269 } 270 } 271 272 switch( textarget ) { 273 case TEXTURE_1D_INDEX: return TGSI_TEXTURE_1D; 274 case TEXTURE_2D_INDEX: return TGSI_TEXTURE_2D; 275 case TEXTURE_3D_INDEX: return TGSI_TEXTURE_3D; 276 case TEXTURE_CUBE_INDEX: return TGSI_TEXTURE_CUBE; 277 case TEXTURE_RECT_INDEX: return TGSI_TEXTURE_RECT; 278 case TEXTURE_1D_ARRAY_INDEX: return TGSI_TEXTURE_1D_ARRAY; 279 case TEXTURE_2D_ARRAY_INDEX: return TGSI_TEXTURE_2D_ARRAY; 280 case TEXTURE_EXTERNAL_INDEX: return TGSI_TEXTURE_2D; 281 default: 282 debug_assert( 0 ); 283 return TGSI_TEXTURE_1D; 284 } 285 } 286 287 288 /** 289 * Create a TGSI ureg_dst register from a Mesa dest register. 290 */ 291 static struct ureg_dst 292 translate_dst( struct st_translate *t, 293 const struct prog_dst_register *DstReg, 294 boolean saturate, 295 boolean clamp_color) 296 { 297 struct ureg_dst dst = dst_register( t, 298 DstReg->File, 299 DstReg->Index ); 300 301 dst = ureg_writemask( dst, 302 DstReg->WriteMask ); 303 304 if (saturate) 305 dst = ureg_saturate( dst ); 306 else if (clamp_color && DstReg->File == PROGRAM_OUTPUT) { 307 /* Clamp colors for ARB_color_buffer_float. */ 308 switch (t->procType) { 309 case TGSI_PROCESSOR_VERTEX: 310 /* XXX if the geometry shader is present, this must be done there 311 * instead of here. */ 312 if (DstReg->Index == VERT_RESULT_COL0 || 313 DstReg->Index == VERT_RESULT_COL1 || 314 DstReg->Index == VERT_RESULT_BFC0 || 315 DstReg->Index == VERT_RESULT_BFC1) { 316 dst = ureg_saturate(dst); 317 } 318 break; 319 320 case TGSI_PROCESSOR_FRAGMENT: 321 if (DstReg->Index >= FRAG_RESULT_COLOR) { 322 dst = ureg_saturate(dst); 323 } 324 break; 325 } 326 } 327 328 if (DstReg->RelAddr) 329 dst = ureg_dst_indirect( dst, ureg_src(t->address[0]) ); 330 331 return dst; 332 } 333 334 335 /** 336 * Create a TGSI ureg_src register from a Mesa src register. 337 */ 338 static struct ureg_src 339 translate_src( struct st_translate *t, 340 const struct prog_src_register *SrcReg ) 341 { 342 struct ureg_src src = src_register( t, SrcReg->File, SrcReg->Index ); 343 344 if (t->procType == TGSI_PROCESSOR_GEOMETRY && SrcReg->HasIndex2) { 345 src = src_register( t, SrcReg->File, SrcReg->Index2 ); 346 if (SrcReg->RelAddr2) 347 src = ureg_src_dimension_indirect( src, ureg_src(t->address[0]), 348 SrcReg->Index); 349 else 350 src = ureg_src_dimension( src, SrcReg->Index); 351 } 352 353 src = ureg_swizzle( src, 354 GET_SWZ( SrcReg->Swizzle, 0 ) & 0x3, 355 GET_SWZ( SrcReg->Swizzle, 1 ) & 0x3, 356 GET_SWZ( SrcReg->Swizzle, 2 ) & 0x3, 357 GET_SWZ( SrcReg->Swizzle, 3 ) & 0x3); 358 359 if (SrcReg->Negate == NEGATE_XYZW) 360 src = ureg_negate(src); 361 362 if (SrcReg->Abs) 363 src = ureg_abs(src); 364 365 if (SrcReg->RelAddr) { 366 src = ureg_src_indirect( src, ureg_src(t->address[0])); 367 if (SrcReg->File != PROGRAM_INPUT && 368 SrcReg->File != PROGRAM_OUTPUT) { 369 /* If SrcReg->Index was negative, it was set to zero in 370 * src_register(). Reassign it now. But don't do this 371 * for input/output regs since they get remapped while 372 * const buffers don't. 373 */ 374 src.Index = SrcReg->Index; 375 } 376 } 377 378 return src; 379 } 380 381 382 static struct ureg_src swizzle_4v( struct ureg_src src, 383 const unsigned *swz ) 384 { 385 return ureg_swizzle( src, swz[0], swz[1], swz[2], swz[3] ); 386 } 387 388 389 /** 390 * Translate a SWZ instruction into a MOV, MUL or MAD instruction. EG: 391 * 392 * SWZ dst, src.x-y10 393 * 394 * becomes: 395 * 396 * MAD dst {1,-1,0,0}, src.xyxx, {0,0,1,0} 397 */ 398 static void emit_swz( struct st_translate *t, 399 struct ureg_dst dst, 400 const struct prog_src_register *SrcReg ) 401 { 402 struct ureg_program *ureg = t->ureg; 403 struct ureg_src src = src_register( t, SrcReg->File, SrcReg->Index ); 404 405 unsigned negate_mask = SrcReg->Negate; 406 407 unsigned one_mask = ((GET_SWZ(SrcReg->Swizzle, 0) == SWIZZLE_ONE) << 0 | 408 (GET_SWZ(SrcReg->Swizzle, 1) == SWIZZLE_ONE) << 1 | 409 (GET_SWZ(SrcReg->Swizzle, 2) == SWIZZLE_ONE) << 2 | 410 (GET_SWZ(SrcReg->Swizzle, 3) == SWIZZLE_ONE) << 3); 411 412 unsigned zero_mask = ((GET_SWZ(SrcReg->Swizzle, 0) == SWIZZLE_ZERO) << 0 | 413 (GET_SWZ(SrcReg->Swizzle, 1) == SWIZZLE_ZERO) << 1 | 414 (GET_SWZ(SrcReg->Swizzle, 2) == SWIZZLE_ZERO) << 2 | 415 (GET_SWZ(SrcReg->Swizzle, 3) == SWIZZLE_ZERO) << 3); 416 417 unsigned negative_one_mask = one_mask & negate_mask; 418 unsigned positive_one_mask = one_mask & ~negate_mask; 419 420 struct ureg_src imm; 421 unsigned i; 422 unsigned mul_swizzle[4] = {0,0,0,0}; 423 unsigned add_swizzle[4] = {0,0,0,0}; 424 unsigned src_swizzle[4] = {0,0,0,0}; 425 boolean need_add = FALSE; 426 boolean need_mul = FALSE; 427 428 if (dst.WriteMask == 0) 429 return; 430 431 /* Is this just a MOV? 432 */ 433 if (zero_mask == 0 && 434 one_mask == 0 && 435 (negate_mask == 0 || negate_mask == TGSI_WRITEMASK_XYZW)) 436 { 437 ureg_MOV( ureg, dst, translate_src( t, SrcReg )); 438 return; 439 } 440 441 #define IMM_ZERO 0 442 #define IMM_ONE 1 443 #define IMM_NEG_ONE 2 444 445 imm = ureg_imm3f( ureg, 0, 1, -1 ); 446 447 for (i = 0; i < 4; i++) { 448 unsigned bit = 1 << i; 449 450 if (dst.WriteMask & bit) { 451 if (positive_one_mask & bit) { 452 mul_swizzle[i] = IMM_ZERO; 453 add_swizzle[i] = IMM_ONE; 454 need_add = TRUE; 455 } 456 else if (negative_one_mask & bit) { 457 mul_swizzle[i] = IMM_ZERO; 458 add_swizzle[i] = IMM_NEG_ONE; 459 need_add = TRUE; 460 } 461 else if (zero_mask & bit) { 462 mul_swizzle[i] = IMM_ZERO; 463 add_swizzle[i] = IMM_ZERO; 464 need_add = TRUE; 465 } 466 else { 467 add_swizzle[i] = IMM_ZERO; 468 src_swizzle[i] = GET_SWZ(SrcReg->Swizzle, i); 469 need_mul = TRUE; 470 if (negate_mask & bit) { 471 mul_swizzle[i] = IMM_NEG_ONE; 472 } 473 else { 474 mul_swizzle[i] = IMM_ONE; 475 } 476 } 477 } 478 } 479 480 if (need_mul && need_add) { 481 ureg_MAD( ureg, 482 dst, 483 swizzle_4v( src, src_swizzle ), 484 swizzle_4v( imm, mul_swizzle ), 485 swizzle_4v( imm, add_swizzle ) ); 486 } 487 else if (need_mul) { 488 ureg_MUL( ureg, 489 dst, 490 swizzle_4v( src, src_swizzle ), 491 swizzle_4v( imm, mul_swizzle ) ); 492 } 493 else if (need_add) { 494 ureg_MOV( ureg, 495 dst, 496 swizzle_4v( imm, add_swizzle ) ); 497 } 498 else { 499 debug_assert(0); 500 } 501 502 #undef IMM_ZERO 503 #undef IMM_ONE 504 #undef IMM_NEG_ONE 505 } 506 507 508 /** 509 * Negate the value of DDY to match GL semantics where (0,0) is the 510 * lower-left corner of the window. 511 * Note that the GL_ARB_fragment_coord_conventions extension will 512 * effect this someday. 513 */ 514 static void emit_ddy( struct st_translate *t, 515 struct ureg_dst dst, 516 const struct prog_src_register *SrcReg ) 517 { 518 struct ureg_program *ureg = t->ureg; 519 struct ureg_src src = translate_src( t, SrcReg ); 520 src = ureg_negate( src ); 521 ureg_DDY( ureg, dst, src ); 522 } 523 524 525 526 static unsigned 527 translate_opcode( unsigned op ) 528 { 529 switch( op ) { 530 case OPCODE_ARL: 531 return TGSI_OPCODE_ARL; 532 case OPCODE_ABS: 533 return TGSI_OPCODE_ABS; 534 case OPCODE_ADD: 535 return TGSI_OPCODE_ADD; 536 case OPCODE_BGNLOOP: 537 return TGSI_OPCODE_BGNLOOP; 538 case OPCODE_BGNSUB: 539 return TGSI_OPCODE_BGNSUB; 540 case OPCODE_BRA: 541 return TGSI_OPCODE_BRA; 542 case OPCODE_BRK: 543 return TGSI_OPCODE_BRK; 544 case OPCODE_CAL: 545 return TGSI_OPCODE_CAL; 546 case OPCODE_CMP: 547 return TGSI_OPCODE_CMP; 548 case OPCODE_CONT: 549 return TGSI_OPCODE_CONT; 550 case OPCODE_COS: 551 return TGSI_OPCODE_COS; 552 case OPCODE_DDX: 553 return TGSI_OPCODE_DDX; 554 case OPCODE_DDY: 555 return TGSI_OPCODE_DDY; 556 case OPCODE_DP2: 557 return TGSI_OPCODE_DP2; 558 case OPCODE_DP2A: 559 return TGSI_OPCODE_DP2A; 560 case OPCODE_DP3: 561 return TGSI_OPCODE_DP3; 562 case OPCODE_DP4: 563 return TGSI_OPCODE_DP4; 564 case OPCODE_DPH: 565 return TGSI_OPCODE_DPH; 566 case OPCODE_DST: 567 return TGSI_OPCODE_DST; 568 case OPCODE_ELSE: 569 return TGSI_OPCODE_ELSE; 570 case OPCODE_EMIT_VERTEX: 571 return TGSI_OPCODE_EMIT; 572 case OPCODE_END_PRIMITIVE: 573 return TGSI_OPCODE_ENDPRIM; 574 case OPCODE_ENDIF: 575 return TGSI_OPCODE_ENDIF; 576 case OPCODE_ENDLOOP: 577 return TGSI_OPCODE_ENDLOOP; 578 case OPCODE_ENDSUB: 579 return TGSI_OPCODE_ENDSUB; 580 case OPCODE_EX2: 581 return TGSI_OPCODE_EX2; 582 case OPCODE_EXP: 583 return TGSI_OPCODE_EXP; 584 case OPCODE_FLR: 585 return TGSI_OPCODE_FLR; 586 case OPCODE_FRC: 587 return TGSI_OPCODE_FRC; 588 case OPCODE_IF: 589 return TGSI_OPCODE_IF; 590 case OPCODE_TRUNC: 591 return TGSI_OPCODE_TRUNC; 592 case OPCODE_KIL: 593 return TGSI_OPCODE_KIL; 594 case OPCODE_KIL_NV: 595 return TGSI_OPCODE_KILP; 596 case OPCODE_LG2: 597 return TGSI_OPCODE_LG2; 598 case OPCODE_LOG: 599 return TGSI_OPCODE_LOG; 600 case OPCODE_LIT: 601 return TGSI_OPCODE_LIT; 602 case OPCODE_LRP: 603 return TGSI_OPCODE_LRP; 604 case OPCODE_MAD: 605 return TGSI_OPCODE_MAD; 606 case OPCODE_MAX: 607 return TGSI_OPCODE_MAX; 608 case OPCODE_MIN: 609 return TGSI_OPCODE_MIN; 610 case OPCODE_MOV: 611 return TGSI_OPCODE_MOV; 612 case OPCODE_MUL: 613 return TGSI_OPCODE_MUL; 614 case OPCODE_NOP: 615 return TGSI_OPCODE_NOP; 616 case OPCODE_NRM3: 617 return TGSI_OPCODE_NRM; 618 case OPCODE_NRM4: 619 return TGSI_OPCODE_NRM4; 620 case OPCODE_POW: 621 return TGSI_OPCODE_POW; 622 case OPCODE_RCP: 623 return TGSI_OPCODE_RCP; 624 case OPCODE_RET: 625 return TGSI_OPCODE_RET; 626 case OPCODE_RSQ: 627 return TGSI_OPCODE_RSQ; 628 case OPCODE_SCS: 629 return TGSI_OPCODE_SCS; 630 case OPCODE_SEQ: 631 return TGSI_OPCODE_SEQ; 632 case OPCODE_SGE: 633 return TGSI_OPCODE_SGE; 634 case OPCODE_SGT: 635 return TGSI_OPCODE_SGT; 636 case OPCODE_SIN: 637 return TGSI_OPCODE_SIN; 638 case OPCODE_SLE: 639 return TGSI_OPCODE_SLE; 640 case OPCODE_SLT: 641 return TGSI_OPCODE_SLT; 642 case OPCODE_SNE: 643 return TGSI_OPCODE_SNE; 644 case OPCODE_SSG: 645 return TGSI_OPCODE_SSG; 646 case OPCODE_SUB: 647 return TGSI_OPCODE_SUB; 648 case OPCODE_TEX: 649 return TGSI_OPCODE_TEX; 650 case OPCODE_TXB: 651 return TGSI_OPCODE_TXB; 652 case OPCODE_TXD: 653 return TGSI_OPCODE_TXD; 654 case OPCODE_TXL: 655 return TGSI_OPCODE_TXL; 656 case OPCODE_TXP: 657 return TGSI_OPCODE_TXP; 658 case OPCODE_XPD: 659 return TGSI_OPCODE_XPD; 660 case OPCODE_END: 661 return TGSI_OPCODE_END; 662 default: 663 debug_assert( 0 ); 664 return TGSI_OPCODE_NOP; 665 } 666 } 667 668 669 static void 670 compile_instruction( 671 struct st_translate *t, 672 const struct prog_instruction *inst, 673 boolean clamp_dst_color_output) 674 { 675 struct ureg_program *ureg = t->ureg; 676 GLuint i; 677 struct ureg_dst dst[1] = { { 0 } }; 678 struct ureg_src src[4]; 679 unsigned num_dst; 680 unsigned num_src; 681 682 num_dst = _mesa_num_inst_dst_regs( inst->Opcode ); 683 num_src = _mesa_num_inst_src_regs( inst->Opcode ); 684 685 if (num_dst) 686 dst[0] = translate_dst( t, 687 &inst->DstReg, 688 inst->SaturateMode, 689 clamp_dst_color_output); 690 691 for (i = 0; i < num_src; i++) 692 src[i] = translate_src( t, &inst->SrcReg[i] ); 693 694 switch( inst->Opcode ) { 695 case OPCODE_SWZ: 696 emit_swz( t, dst[0], &inst->SrcReg[0] ); 697 return; 698 699 case OPCODE_BGNLOOP: 700 case OPCODE_CAL: 701 case OPCODE_ELSE: 702 case OPCODE_ENDLOOP: 703 case OPCODE_IF: 704 debug_assert(num_dst == 0); 705 ureg_label_insn( ureg, 706 translate_opcode( inst->Opcode ), 707 src, num_src, 708 get_label( t, inst->BranchTarget )); 709 return; 710 711 case OPCODE_TEX: 712 case OPCODE_TXB: 713 case OPCODE_TXD: 714 case OPCODE_TXL: 715 case OPCODE_TXP: 716 src[num_src++] = t->samplers[inst->TexSrcUnit]; 717 ureg_tex_insn( ureg, 718 translate_opcode( inst->Opcode ), 719 dst, num_dst, 720 st_translate_texture_target( inst->TexSrcTarget, 721 inst->TexShadow ), 722 NULL, 0, 723 src, num_src ); 724 return; 725 726 case OPCODE_SCS: 727 dst[0] = ureg_writemask(dst[0], TGSI_WRITEMASK_XY ); 728 ureg_insn( ureg, 729 translate_opcode( inst->Opcode ), 730 dst, num_dst, 731 src, num_src ); 732 break; 733 734 case OPCODE_XPD: 735 dst[0] = ureg_writemask(dst[0], TGSI_WRITEMASK_XYZ ); 736 ureg_insn( ureg, 737 translate_opcode( inst->Opcode ), 738 dst, num_dst, 739 src, num_src ); 740 break; 741 742 case OPCODE_NOISE1: 743 case OPCODE_NOISE2: 744 case OPCODE_NOISE3: 745 case OPCODE_NOISE4: 746 /* At some point, a motivated person could add a better 747 * implementation of noise. Currently not even the nvidia 748 * binary drivers do anything more than this. In any case, the 749 * place to do this is in the GL state tracker, not the poor 750 * driver. 751 */ 752 ureg_MOV( ureg, dst[0], ureg_imm1f(ureg, 0.5) ); 753 break; 754 755 case OPCODE_DDY: 756 emit_ddy( t, dst[0], &inst->SrcReg[0] ); 757 break; 758 759 default: 760 ureg_insn( ureg, 761 translate_opcode( inst->Opcode ), 762 dst, num_dst, 763 src, num_src ); 764 break; 765 } 766 } 767 768 769 /** 770 * Emit the TGSI instructions for inverting and adjusting WPOS. 771 * This code is unavoidable because it also depends on whether 772 * a FBO is bound (STATE_FB_WPOS_Y_TRANSFORM). 773 */ 774 static void 775 emit_wpos_adjustment( struct st_translate *t, 776 const struct gl_program *program, 777 boolean invert, 778 GLfloat adjX, GLfloat adjY[2]) 779 { 780 struct ureg_program *ureg = t->ureg; 781 782 /* Fragment program uses fragment position input. 783 * Need to replace instances of INPUT[WPOS] with temp T 784 * where T = INPUT[WPOS] by y is inverted. 785 */ 786 static const gl_state_index wposTransformState[STATE_LENGTH] 787 = { STATE_INTERNAL, STATE_FB_WPOS_Y_TRANSFORM, 0, 0, 0 }; 788 789 /* XXX: note we are modifying the incoming shader here! Need to 790 * do this before emitting the constant decls below, or this 791 * will be missed: 792 */ 793 unsigned wposTransConst = _mesa_add_state_reference(program->Parameters, 794 wposTransformState); 795 796 struct ureg_src wpostrans = ureg_DECL_constant( ureg, wposTransConst ); 797 struct ureg_dst wpos_temp = ureg_DECL_temporary( ureg ); 798 struct ureg_src wpos_input = t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]]; 799 800 /* First, apply the coordinate shift: */ 801 if (adjX || adjY[0] || adjY[1]) { 802 if (adjY[0] != adjY[1]) { 803 /* Adjust the y coordinate by adjY[1] or adjY[0] respectively 804 * depending on whether inversion is actually going to be applied 805 * or not, which is determined by testing against the inversion 806 * state variable used below, which will be either +1 or -1. 807 */ 808 struct ureg_dst adj_temp = ureg_DECL_temporary(ureg); 809 810 ureg_CMP(ureg, adj_temp, 811 ureg_scalar(wpostrans, invert ? 2 : 0), 812 ureg_imm4f(ureg, adjX, adjY[0], 0.0f, 0.0f), 813 ureg_imm4f(ureg, adjX, adjY[1], 0.0f, 0.0f)); 814 ureg_ADD(ureg, wpos_temp, wpos_input, ureg_src(adj_temp)); 815 } else { 816 ureg_ADD(ureg, wpos_temp, wpos_input, 817 ureg_imm4f(ureg, adjX, adjY[0], 0.0f, 0.0f)); 818 } 819 wpos_input = ureg_src(wpos_temp); 820 } else { 821 /* MOV wpos_temp, input[wpos] 822 */ 823 ureg_MOV( ureg, wpos_temp, wpos_input ); 824 } 825 826 /* Now the conditional y flip: STATE_FB_WPOS_Y_TRANSFORM.xy/zw will be 827 * inversion/identity, or the other way around if we're drawing to an FBO. 828 */ 829 if (invert) { 830 /* MAD wpos_temp.y, wpos_input, wpostrans.xxxx, wpostrans.yyyy 831 */ 832 ureg_MAD( ureg, 833 ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y ), 834 wpos_input, 835 ureg_scalar(wpostrans, 0), 836 ureg_scalar(wpostrans, 1)); 837 } else { 838 /* MAD wpos_temp.y, wpos_input, wpostrans.zzzz, wpostrans.wwww 839 */ 840 ureg_MAD( ureg, 841 ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y ), 842 wpos_input, 843 ureg_scalar(wpostrans, 2), 844 ureg_scalar(wpostrans, 3)); 845 } 846 847 /* Use wpos_temp as position input from here on: 848 */ 849 t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]] = ureg_src(wpos_temp); 850 } 851 852 853 /** 854 * Emit fragment position/ooordinate code. 855 */ 856 static void 857 emit_wpos(struct st_context *st, 858 struct st_translate *t, 859 const struct gl_program *program, 860 struct ureg_program *ureg) 861 { 862 const struct gl_fragment_program *fp = 863 (const struct gl_fragment_program *) program; 864 struct pipe_screen *pscreen = st->pipe->screen; 865 GLfloat adjX = 0.0f; 866 GLfloat adjY[2] = { 0.0f, 0.0f }; 867 boolean invert = FALSE; 868 869 /* Query the pixel center conventions supported by the pipe driver and set 870 * adjX, adjY to help out if it cannot handle the requested one internally. 871 * 872 * The bias of the y-coordinate depends on whether y-inversion takes place 873 * (adjY[1]) or not (adjY[0]), which is in turn dependent on whether we are 874 * drawing to an FBO (causes additional inversion), and whether the the pipe 875 * driver origin and the requested origin differ (the latter condition is 876 * stored in the 'invert' variable). 877 * 878 * For height = 100 (i = integer, h = half-integer, l = lower, u = upper): 879 * 880 * center shift only: 881 * i -> h: +0.5 882 * h -> i: -0.5 883 * 884 * inversion only: 885 * l,i -> u,i: ( 0.0 + 1.0) * -1 + 100 = 99 886 * l,h -> u,h: ( 0.5 + 0.0) * -1 + 100 = 99.5 887 * u,i -> l,i: (99.0 + 1.0) * -1 + 100 = 0 888 * u,h -> l,h: (99.5 + 0.0) * -1 + 100 = 0.5 889 * 890 * inversion and center shift: 891 * l,i -> u,h: ( 0.0 + 0.5) * -1 + 100 = 99.5 892 * l,h -> u,i: ( 0.5 + 0.5) * -1 + 100 = 99 893 * u,i -> l,h: (99.0 + 0.5) * -1 + 100 = 0.5 894 * u,h -> l,i: (99.5 + 0.5) * -1 + 100 = 0 895 */ 896 if (fp->OriginUpperLeft) { 897 /* Fragment shader wants origin in upper-left */ 898 if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT)) { 899 /* the driver supports upper-left origin */ 900 } 901 else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT)) { 902 /* the driver supports lower-left origin, need to invert Y */ 903 ureg_property_fs_coord_origin(ureg, TGSI_FS_COORD_ORIGIN_LOWER_LEFT); 904 invert = TRUE; 905 } 906 else 907 assert(0); 908 } 909 else { 910 /* Fragment shader wants origin in lower-left */ 911 if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT)) 912 /* the driver supports lower-left origin */ 913 ureg_property_fs_coord_origin(ureg, TGSI_FS_COORD_ORIGIN_LOWER_LEFT); 914 else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT)) 915 /* the driver supports upper-left origin, need to invert Y */ 916 invert = TRUE; 917 else 918 assert(0); 919 } 920 921 if (fp->PixelCenterInteger) { 922 /* Fragment shader wants pixel center integer */ 923 if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) { 924 /* the driver supports pixel center integer */ 925 adjY[1] = 1.0f; 926 ureg_property_fs_coord_pixel_center(ureg, TGSI_FS_COORD_PIXEL_CENTER_INTEGER); 927 } 928 else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER)) { 929 /* the driver supports pixel center half integer, need to bias X,Y */ 930 adjX = -0.5f; 931 adjY[0] = -0.5f; 932 adjY[1] = 0.5f; 933 } 934 else 935 assert(0); 936 } 937 else { 938 /* Fragment shader wants pixel center half integer */ 939 if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER)) { 940 /* the driver supports pixel center half integer */ 941 } 942 else if (pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER)) { 943 /* the driver supports pixel center integer, need to bias X,Y */ 944 adjX = adjY[0] = adjY[1] = 0.5f; 945 ureg_property_fs_coord_pixel_center(ureg, TGSI_FS_COORD_PIXEL_CENTER_INTEGER); 946 } 947 else 948 assert(0); 949 } 950 951 /* we invert after adjustment so that we avoid the MOV to temporary, 952 * and reuse the adjustment ADD instead */ 953 emit_wpos_adjustment(t, program, invert, adjX, adjY); 954 } 955 956 957 /** 958 * OpenGL's fragment gl_FrontFace input is 1 for front-facing, 0 for back. 959 * TGSI uses +1 for front, -1 for back. 960 * This function converts the TGSI value to the GL value. Simply clamping/ 961 * saturating the value to [0,1] does the job. 962 */ 963 static void 964 emit_face_var( struct st_translate *t, 965 const struct gl_program *program ) 966 { 967 struct ureg_program *ureg = t->ureg; 968 struct ureg_dst face_temp = ureg_DECL_temporary( ureg ); 969 struct ureg_src face_input = t->inputs[t->inputMapping[FRAG_ATTRIB_FACE]]; 970 971 /* MOV_SAT face_temp, input[face] 972 */ 973 face_temp = ureg_saturate( face_temp ); 974 ureg_MOV( ureg, face_temp, face_input ); 975 976 /* Use face_temp as face input from here on: 977 */ 978 t->inputs[t->inputMapping[FRAG_ATTRIB_FACE]] = ureg_src(face_temp); 979 } 980 981 982 static void 983 emit_edgeflags( struct st_translate *t, 984 const struct gl_program *program ) 985 { 986 struct ureg_program *ureg = t->ureg; 987 struct ureg_dst edge_dst = t->outputs[t->outputMapping[VERT_RESULT_EDGE]]; 988 struct ureg_src edge_src = t->inputs[t->inputMapping[VERT_ATTRIB_EDGEFLAG]]; 989 990 ureg_MOV( ureg, edge_dst, edge_src ); 991 } 992 993 994 /** 995 * Translate Mesa program to TGSI format. 996 * \param program the program to translate 997 * \param numInputs number of input registers used 998 * \param inputMapping maps Mesa fragment program inputs to TGSI generic 999 * input indexes 1000 * \param inputSemanticName the TGSI_SEMANTIC flag for each input 1001 * \param inputSemanticIndex the semantic index (ex: which texcoord) for 1002 * each input 1003 * \param interpMode the TGSI_INTERPOLATE_LINEAR/PERSP mode for each input 1004 * \param numOutputs number of output registers used 1005 * \param outputMapping maps Mesa fragment program outputs to TGSI 1006 * generic outputs 1007 * \param outputSemanticName the TGSI_SEMANTIC flag for each output 1008 * \param outputSemanticIndex the semantic index (ex: which texcoord) for 1009 * each output 1010 * 1011 * \return PIPE_OK or PIPE_ERROR_OUT_OF_MEMORY 1012 */ 1013 enum pipe_error 1014 st_translate_mesa_program( 1015 struct gl_context *ctx, 1016 uint procType, 1017 struct ureg_program *ureg, 1018 const struct gl_program *program, 1019 GLuint numInputs, 1020 const GLuint inputMapping[], 1021 const ubyte inputSemanticName[], 1022 const ubyte inputSemanticIndex[], 1023 const GLuint interpMode[], 1024 GLuint numOutputs, 1025 const GLuint outputMapping[], 1026 const ubyte outputSemanticName[], 1027 const ubyte outputSemanticIndex[], 1028 boolean passthrough_edgeflags, 1029 boolean clamp_color) 1030 { 1031 struct st_translate translate, *t; 1032 unsigned i; 1033 enum pipe_error ret = PIPE_OK; 1034 1035 assert(numInputs <= Elements(t->inputs)); 1036 assert(numOutputs <= Elements(t->outputs)); 1037 1038 t = &translate; 1039 memset(t, 0, sizeof *t); 1040 1041 t->procType = procType; 1042 t->inputMapping = inputMapping; 1043 t->outputMapping = outputMapping; 1044 t->ureg = ureg; 1045 1046 /*_mesa_print_program(program);*/ 1047 1048 /* 1049 * Declare input attributes. 1050 */ 1051 if (procType == TGSI_PROCESSOR_FRAGMENT) { 1052 for (i = 0; i < numInputs; i++) { 1053 if (program->InputFlags[0] & PROG_PARAM_BIT_CYL_WRAP) { 1054 t->inputs[i] = ureg_DECL_fs_input_cyl(ureg, 1055 inputSemanticName[i], 1056 inputSemanticIndex[i], 1057 interpMode[i], 1058 TGSI_CYLINDRICAL_WRAP_X); 1059 } 1060 else { 1061 t->inputs[i] = ureg_DECL_fs_input(ureg, 1062 inputSemanticName[i], 1063 inputSemanticIndex[i], 1064 interpMode[i]); 1065 } 1066 } 1067 1068 if (program->InputsRead & FRAG_BIT_WPOS) { 1069 /* Must do this after setting up t->inputs, and before 1070 * emitting constant references, below: 1071 */ 1072 emit_wpos(st_context(ctx), t, program, ureg); 1073 } 1074 1075 if (program->InputsRead & FRAG_BIT_FACE) { 1076 emit_face_var( t, program ); 1077 } 1078 1079 /* 1080 * Declare output attributes. 1081 */ 1082 for (i = 0; i < numOutputs; i++) { 1083 switch (outputSemanticName[i]) { 1084 case TGSI_SEMANTIC_POSITION: 1085 t->outputs[i] = ureg_DECL_output( ureg, 1086 TGSI_SEMANTIC_POSITION, /* Z / Depth */ 1087 outputSemanticIndex[i] ); 1088 1089 t->outputs[i] = ureg_writemask( t->outputs[i], 1090 TGSI_WRITEMASK_Z ); 1091 break; 1092 case TGSI_SEMANTIC_STENCIL: 1093 t->outputs[i] = ureg_DECL_output( ureg, 1094 TGSI_SEMANTIC_STENCIL, /* Stencil */ 1095 outputSemanticIndex[i] ); 1096 t->outputs[i] = ureg_writemask( t->outputs[i], 1097 TGSI_WRITEMASK_Y ); 1098 break; 1099 case TGSI_SEMANTIC_COLOR: 1100 t->outputs[i] = ureg_DECL_output( ureg, 1101 TGSI_SEMANTIC_COLOR, 1102 outputSemanticIndex[i] ); 1103 break; 1104 default: 1105 debug_assert(0); 1106 return 0; 1107 } 1108 } 1109 } 1110 else if (procType == TGSI_PROCESSOR_GEOMETRY) { 1111 for (i = 0; i < numInputs; i++) { 1112 t->inputs[i] = ureg_DECL_gs_input(ureg, 1113 i, 1114 inputSemanticName[i], 1115 inputSemanticIndex[i]); 1116 } 1117 1118 for (i = 0; i < numOutputs; i++) { 1119 t->outputs[i] = ureg_DECL_output( ureg, 1120 outputSemanticName[i], 1121 outputSemanticIndex[i] ); 1122 } 1123 } 1124 else { 1125 assert(procType == TGSI_PROCESSOR_VERTEX); 1126 1127 for (i = 0; i < numInputs; i++) { 1128 t->inputs[i] = ureg_DECL_vs_input(ureg, i); 1129 } 1130 1131 for (i = 0; i < numOutputs; i++) { 1132 t->outputs[i] = ureg_DECL_output( ureg, 1133 outputSemanticName[i], 1134 outputSemanticIndex[i] ); 1135 } 1136 if (passthrough_edgeflags) 1137 emit_edgeflags( t, program ); 1138 } 1139 1140 /* Declare address register. 1141 */ 1142 if (program->NumAddressRegs > 0) { 1143 debug_assert( program->NumAddressRegs == 1 ); 1144 t->address[0] = ureg_DECL_address( ureg ); 1145 } 1146 1147 /* Declare misc input registers 1148 */ 1149 { 1150 GLbitfield sysInputs = program->SystemValuesRead; 1151 unsigned numSys = 0; 1152 for (i = 0; sysInputs; i++) { 1153 if (sysInputs & (1 << i)) { 1154 unsigned semName = mesa_sysval_to_semantic[i]; 1155 t->systemValues[i] = ureg_DECL_system_value(ureg, numSys, semName, 0); 1156 if (semName == TGSI_SEMANTIC_INSTANCEID || 1157 semName == TGSI_SEMANTIC_VERTEXID) { 1158 /* From Gallium perspective, these system values are always 1159 * integer, and require native integer support. However, if 1160 * native integer is supported on the vertex stage but not the 1161 * pixel stage (e.g, i915g + draw), Mesa will generate IR that 1162 * assumes these system values are floats. To resolve the 1163 * inconsistency, we insert a U2F. 1164 */ 1165 struct st_context *st = st_context(ctx); 1166 struct pipe_screen *pscreen = st->pipe->screen; 1167 assert(procType == TGSI_PROCESSOR_VERTEX); 1168 assert(pscreen->get_shader_param(pscreen, PIPE_SHADER_VERTEX, PIPE_SHADER_CAP_INTEGERS)); 1169 if (!ctx->Const.NativeIntegers) { 1170 struct ureg_dst temp = ureg_DECL_local_temporary(t->ureg); 1171 ureg_U2F( t->ureg, ureg_writemask(temp, TGSI_WRITEMASK_X), t->systemValues[i]); 1172 t->systemValues[i] = ureg_scalar(ureg_src(temp), 0); 1173 } 1174 } 1175 numSys++; 1176 sysInputs &= ~(1 << i); 1177 } 1178 } 1179 } 1180 1181 if (program->IndirectRegisterFiles & (1 << PROGRAM_TEMPORARY)) { 1182 /* If temps are accessed with indirect addressing, declare temporaries 1183 * in sequential order. Else, we declare them on demand elsewhere. 1184 */ 1185 for (i = 0; i < program->NumTemporaries; i++) { 1186 /* XXX use TGSI_FILE_TEMPORARY_ARRAY when it's supported by ureg */ 1187 t->temps[i] = ureg_DECL_temporary( t->ureg ); 1188 } 1189 } 1190 1191 /* Emit constants and immediates. Mesa uses a single index space 1192 * for these, so we put all the translated regs in t->constants. 1193 */ 1194 if (program->Parameters) { 1195 t->constants = calloc( program->Parameters->NumParameters, 1196 sizeof t->constants[0] ); 1197 if (t->constants == NULL) { 1198 ret = PIPE_ERROR_OUT_OF_MEMORY; 1199 goto out; 1200 } 1201 1202 for (i = 0; i < program->Parameters->NumParameters; i++) { 1203 switch (program->Parameters->Parameters[i].Type) { 1204 case PROGRAM_ENV_PARAM: 1205 case PROGRAM_LOCAL_PARAM: 1206 case PROGRAM_STATE_VAR: 1207 case PROGRAM_NAMED_PARAM: 1208 case PROGRAM_UNIFORM: 1209 t->constants[i] = ureg_DECL_constant( ureg, i ); 1210 break; 1211 1212 /* Emit immediates only when there's no indirect addressing of 1213 * the const buffer. 1214 * FIXME: Be smarter and recognize param arrays: 1215 * indirect addressing is only valid within the referenced 1216 * array. 1217 */ 1218 case PROGRAM_CONSTANT: 1219 if (program->IndirectRegisterFiles & PROGRAM_ANY_CONST) 1220 t->constants[i] = ureg_DECL_constant( ureg, i ); 1221 else 1222 t->constants[i] = 1223 ureg_DECL_immediate( ureg, 1224 (const float*) program->Parameters->ParameterValues[i], 1225 4 ); 1226 break; 1227 default: 1228 break; 1229 } 1230 } 1231 } 1232 1233 /* texture samplers */ 1234 for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) { 1235 if (program->SamplersUsed & (1 << i)) { 1236 t->samplers[i] = ureg_DECL_sampler( ureg, i ); 1237 } 1238 } 1239 1240 /* Emit each instruction in turn: 1241 */ 1242 for (i = 0; i < program->NumInstructions; i++) { 1243 set_insn_start( t, ureg_get_instruction_number( ureg )); 1244 compile_instruction( t, &program->Instructions[i], clamp_color ); 1245 } 1246 1247 /* Fix up all emitted labels: 1248 */ 1249 for (i = 0; i < t->labels_count; i++) { 1250 ureg_fixup_label( ureg, 1251 t->labels[i].token, 1252 t->insn[t->labels[i].branch_target] ); 1253 } 1254 1255 out: 1256 FREE(t->insn); 1257 FREE(t->labels); 1258 FREE(t->constants); 1259 1260 if (t->error) { 1261 debug_printf("%s: translate error flag set\n", __FUNCTION__); 1262 } 1263 1264 return ret; 1265 } 1266 1267 1268 /** 1269 * Tokens cannot be free with free otherwise the builtin gallium 1270 * malloc debugging will get confused. 1271 */ 1272 void 1273 st_free_tokens(const struct tgsi_token *tokens) 1274 { 1275 ureg_free_tokens(tokens); 1276 } 1277