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