1 /************************************************************************** 2 * 3 * Copyright 2009-2010 VMware, Inc. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL VMWARE, INC 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 #include "pipe/p_screen.h" 30 #include "pipe/p_context.h" 31 #include "pipe/p_state.h" 32 #include "tgsi/tgsi_ureg.h" 33 #include "tgsi/tgsi_build.h" 34 #include "tgsi/tgsi_info.h" 35 #include "tgsi/tgsi_dump.h" 36 #include "tgsi/tgsi_sanity.h" 37 #include "util/u_debug.h" 38 #include "util/u_inlines.h" 39 #include "util/u_memory.h" 40 #include "util/u_math.h" 41 #include "util/u_bitmask.h" 42 43 union tgsi_any_token { 44 struct tgsi_header header; 45 struct tgsi_processor processor; 46 struct tgsi_token token; 47 struct tgsi_property prop; 48 struct tgsi_property_data prop_data; 49 struct tgsi_declaration decl; 50 struct tgsi_declaration_range decl_range; 51 struct tgsi_declaration_dimension decl_dim; 52 struct tgsi_declaration_interp decl_interp; 53 struct tgsi_declaration_image decl_image; 54 struct tgsi_declaration_semantic decl_semantic; 55 struct tgsi_declaration_sampler_view decl_sampler_view; 56 struct tgsi_declaration_array array; 57 struct tgsi_immediate imm; 58 union tgsi_immediate_data imm_data; 59 struct tgsi_instruction insn; 60 struct tgsi_instruction_predicate insn_predicate; 61 struct tgsi_instruction_label insn_label; 62 struct tgsi_instruction_texture insn_texture; 63 struct tgsi_instruction_memory insn_memory; 64 struct tgsi_texture_offset insn_texture_offset; 65 struct tgsi_src_register src; 66 struct tgsi_ind_register ind; 67 struct tgsi_dimension dim; 68 struct tgsi_dst_register dst; 69 unsigned value; 70 }; 71 72 73 struct ureg_tokens { 74 union tgsi_any_token *tokens; 75 unsigned size; 76 unsigned order; 77 unsigned count; 78 }; 79 80 #define UREG_MAX_INPUT (4 * PIPE_MAX_SHADER_INPUTS) 81 #define UREG_MAX_SYSTEM_VALUE PIPE_MAX_ATTRIBS 82 #define UREG_MAX_OUTPUT (4 * PIPE_MAX_SHADER_OUTPUTS) 83 #define UREG_MAX_CONSTANT_RANGE 32 84 #define UREG_MAX_IMMEDIATE 4096 85 #define UREG_MAX_ADDR 3 86 #define UREG_MAX_PRED 1 87 #define UREG_MAX_ARRAY_TEMPS 256 88 89 struct const_decl { 90 struct { 91 unsigned first; 92 unsigned last; 93 } constant_range[UREG_MAX_CONSTANT_RANGE]; 94 unsigned nr_constant_ranges; 95 }; 96 97 #define DOMAIN_DECL 0 98 #define DOMAIN_INSN 1 99 100 struct ureg_program 101 { 102 unsigned processor; 103 bool supports_any_inout_decl_range; 104 int next_shader_processor; 105 106 struct { 107 unsigned semantic_name; 108 unsigned semantic_index; 109 unsigned interp; 110 unsigned char cylindrical_wrap; 111 unsigned char usage_mask; 112 unsigned interp_location; 113 unsigned first; 114 unsigned last; 115 unsigned array_id; 116 } input[UREG_MAX_INPUT]; 117 unsigned nr_inputs, nr_input_regs; 118 119 unsigned vs_inputs[PIPE_MAX_ATTRIBS/32]; 120 121 struct { 122 unsigned semantic_name; 123 unsigned semantic_index; 124 } system_value[UREG_MAX_SYSTEM_VALUE]; 125 unsigned nr_system_values; 126 127 struct { 128 unsigned semantic_name; 129 unsigned semantic_index; 130 unsigned streams; 131 unsigned usage_mask; /* = TGSI_WRITEMASK_* */ 132 unsigned first; 133 unsigned last; 134 unsigned array_id; 135 } output[UREG_MAX_OUTPUT]; 136 unsigned nr_outputs, nr_output_regs; 137 138 struct { 139 union { 140 float f[4]; 141 unsigned u[4]; 142 int i[4]; 143 } value; 144 unsigned nr; 145 unsigned type; 146 } immediate[UREG_MAX_IMMEDIATE]; 147 unsigned nr_immediates; 148 149 struct ureg_src sampler[PIPE_MAX_SAMPLERS]; 150 unsigned nr_samplers; 151 152 struct { 153 unsigned index; 154 unsigned target; 155 unsigned return_type_x; 156 unsigned return_type_y; 157 unsigned return_type_z; 158 unsigned return_type_w; 159 } sampler_view[PIPE_MAX_SHADER_SAMPLER_VIEWS]; 160 unsigned nr_sampler_views; 161 162 struct { 163 unsigned index; 164 unsigned target; 165 unsigned format; 166 boolean wr; 167 boolean raw; 168 } image[PIPE_MAX_SHADER_IMAGES]; 169 unsigned nr_images; 170 171 struct { 172 unsigned index; 173 bool atomic; 174 } buffer[PIPE_MAX_SHADER_BUFFERS]; 175 unsigned nr_buffers; 176 177 struct util_bitmask *free_temps; 178 struct util_bitmask *local_temps; 179 struct util_bitmask *decl_temps; 180 unsigned nr_temps; 181 182 unsigned array_temps[UREG_MAX_ARRAY_TEMPS]; 183 unsigned nr_array_temps; 184 185 struct const_decl const_decls; 186 struct const_decl const_decls2D[PIPE_MAX_CONSTANT_BUFFERS]; 187 188 unsigned properties[TGSI_PROPERTY_COUNT]; 189 190 unsigned nr_addrs; 191 unsigned nr_preds; 192 unsigned nr_instructions; 193 194 struct ureg_tokens domain[2]; 195 196 bool use_memory[TGSI_MEMORY_TYPE_COUNT]; 197 }; 198 199 static union tgsi_any_token error_tokens[32]; 200 201 static void tokens_error( struct ureg_tokens *tokens ) 202 { 203 if (tokens->tokens && tokens->tokens != error_tokens) 204 FREE(tokens->tokens); 205 206 tokens->tokens = error_tokens; 207 tokens->size = ARRAY_SIZE(error_tokens); 208 tokens->count = 0; 209 } 210 211 212 static void tokens_expand( struct ureg_tokens *tokens, 213 unsigned count ) 214 { 215 unsigned old_size = tokens->size * sizeof(unsigned); 216 217 if (tokens->tokens == error_tokens) { 218 return; 219 } 220 221 while (tokens->count + count > tokens->size) { 222 tokens->size = (1 << ++tokens->order); 223 } 224 225 tokens->tokens = REALLOC(tokens->tokens, 226 old_size, 227 tokens->size * sizeof(unsigned)); 228 if (tokens->tokens == NULL) { 229 tokens_error(tokens); 230 } 231 } 232 233 static void set_bad( struct ureg_program *ureg ) 234 { 235 tokens_error(&ureg->domain[0]); 236 } 237 238 239 240 static union tgsi_any_token *get_tokens( struct ureg_program *ureg, 241 unsigned domain, 242 unsigned count ) 243 { 244 struct ureg_tokens *tokens = &ureg->domain[domain]; 245 union tgsi_any_token *result; 246 247 if (tokens->count + count > tokens->size) 248 tokens_expand(tokens, count); 249 250 result = &tokens->tokens[tokens->count]; 251 tokens->count += count; 252 return result; 253 } 254 255 256 static union tgsi_any_token *retrieve_token( struct ureg_program *ureg, 257 unsigned domain, 258 unsigned nr ) 259 { 260 if (ureg->domain[domain].tokens == error_tokens) 261 return &error_tokens[0]; 262 263 return &ureg->domain[domain].tokens[nr]; 264 } 265 266 void 267 ureg_property(struct ureg_program *ureg, unsigned name, unsigned value) 268 { 269 assert(name < ARRAY_SIZE(ureg->properties)); 270 ureg->properties[name] = value; 271 } 272 273 struct ureg_src 274 ureg_DECL_fs_input_cyl_centroid_layout(struct ureg_program *ureg, 275 unsigned semantic_name, 276 unsigned semantic_index, 277 unsigned interp_mode, 278 unsigned cylindrical_wrap, 279 unsigned interp_location, 280 unsigned index, 281 unsigned usage_mask, 282 unsigned array_id, 283 unsigned array_size) 284 { 285 unsigned i; 286 287 assert(usage_mask != 0); 288 assert(usage_mask <= TGSI_WRITEMASK_XYZW); 289 290 for (i = 0; i < ureg->nr_inputs; i++) { 291 if (ureg->input[i].semantic_name == semantic_name && 292 ureg->input[i].semantic_index == semantic_index) { 293 assert(ureg->input[i].interp == interp_mode); 294 assert(ureg->input[i].cylindrical_wrap == cylindrical_wrap); 295 assert(ureg->input[i].interp_location == interp_location); 296 if (ureg->input[i].array_id == array_id) { 297 ureg->input[i].usage_mask |= usage_mask; 298 goto out; 299 } 300 assert((ureg->input[i].usage_mask & usage_mask) == 0); 301 } 302 } 303 304 if (ureg->nr_inputs < UREG_MAX_INPUT) { 305 assert(array_size >= 1); 306 ureg->input[i].semantic_name = semantic_name; 307 ureg->input[i].semantic_index = semantic_index; 308 ureg->input[i].interp = interp_mode; 309 ureg->input[i].cylindrical_wrap = cylindrical_wrap; 310 ureg->input[i].interp_location = interp_location; 311 ureg->input[i].first = index; 312 ureg->input[i].last = index + array_size - 1; 313 ureg->input[i].array_id = array_id; 314 ureg->input[i].usage_mask = usage_mask; 315 ureg->nr_input_regs = MAX2(ureg->nr_input_regs, index + array_size); 316 ureg->nr_inputs++; 317 } else { 318 set_bad(ureg); 319 } 320 321 out: 322 return ureg_src_array_register(TGSI_FILE_INPUT, ureg->input[i].first, 323 array_id); 324 } 325 326 struct ureg_src 327 ureg_DECL_fs_input_cyl_centroid(struct ureg_program *ureg, 328 unsigned semantic_name, 329 unsigned semantic_index, 330 unsigned interp_mode, 331 unsigned cylindrical_wrap, 332 unsigned interp_location, 333 unsigned array_id, 334 unsigned array_size) 335 { 336 return ureg_DECL_fs_input_cyl_centroid_layout(ureg, 337 semantic_name, semantic_index, interp_mode, cylindrical_wrap, interp_location, 338 ureg->nr_input_regs, TGSI_WRITEMASK_XYZW, array_id, array_size); 339 } 340 341 342 struct ureg_src 343 ureg_DECL_vs_input( struct ureg_program *ureg, 344 unsigned index ) 345 { 346 assert(ureg->processor == PIPE_SHADER_VERTEX); 347 assert(index / 32 < ARRAY_SIZE(ureg->vs_inputs)); 348 349 ureg->vs_inputs[index/32] |= 1 << (index % 32); 350 return ureg_src_register( TGSI_FILE_INPUT, index ); 351 } 352 353 354 struct ureg_src 355 ureg_DECL_input_layout(struct ureg_program *ureg, 356 unsigned semantic_name, 357 unsigned semantic_index, 358 unsigned index, 359 unsigned usage_mask, 360 unsigned array_id, 361 unsigned array_size) 362 { 363 return ureg_DECL_fs_input_cyl_centroid_layout(ureg, 364 semantic_name, semantic_index, 0, 0, 0, 365 index, usage_mask, array_id, array_size); 366 } 367 368 369 struct ureg_src 370 ureg_DECL_input(struct ureg_program *ureg, 371 unsigned semantic_name, 372 unsigned semantic_index, 373 unsigned array_id, 374 unsigned array_size) 375 { 376 return ureg_DECL_fs_input_cyl_centroid(ureg, semantic_name, semantic_index, 377 0, 0, 0, array_id, array_size); 378 } 379 380 381 struct ureg_src 382 ureg_DECL_system_value(struct ureg_program *ureg, 383 unsigned semantic_name, 384 unsigned semantic_index) 385 { 386 unsigned i; 387 388 for (i = 0; i < ureg->nr_system_values; i++) { 389 if (ureg->system_value[i].semantic_name == semantic_name && 390 ureg->system_value[i].semantic_index == semantic_index) { 391 goto out; 392 } 393 } 394 395 if (ureg->nr_system_values < UREG_MAX_SYSTEM_VALUE) { 396 ureg->system_value[ureg->nr_system_values].semantic_name = semantic_name; 397 ureg->system_value[ureg->nr_system_values].semantic_index = semantic_index; 398 i = ureg->nr_system_values; 399 ureg->nr_system_values++; 400 } else { 401 set_bad(ureg); 402 } 403 404 out: 405 return ureg_src_register(TGSI_FILE_SYSTEM_VALUE, i); 406 } 407 408 409 struct ureg_dst 410 ureg_DECL_output_layout(struct ureg_program *ureg, 411 unsigned semantic_name, 412 unsigned semantic_index, 413 unsigned streams, 414 unsigned index, 415 unsigned usage_mask, 416 unsigned array_id, 417 unsigned array_size) 418 { 419 unsigned i; 420 421 assert(usage_mask != 0); 422 assert(!(streams & 0x03) || (usage_mask & 1)); 423 assert(!(streams & 0x0c) || (usage_mask & 2)); 424 assert(!(streams & 0x30) || (usage_mask & 4)); 425 assert(!(streams & 0xc0) || (usage_mask & 8)); 426 427 for (i = 0; i < ureg->nr_outputs; i++) { 428 if (ureg->output[i].semantic_name == semantic_name && 429 ureg->output[i].semantic_index == semantic_index) { 430 if (ureg->output[i].array_id == array_id) { 431 ureg->output[i].usage_mask |= usage_mask; 432 goto out; 433 } 434 assert((ureg->output[i].usage_mask & usage_mask) == 0); 435 } 436 } 437 438 if (ureg->nr_outputs < UREG_MAX_OUTPUT) { 439 ureg->output[i].semantic_name = semantic_name; 440 ureg->output[i].semantic_index = semantic_index; 441 ureg->output[i].usage_mask = usage_mask; 442 ureg->output[i].first = index; 443 ureg->output[i].last = index + array_size - 1; 444 ureg->output[i].array_id = array_id; 445 ureg->nr_output_regs = MAX2(ureg->nr_output_regs, index + array_size); 446 ureg->nr_outputs++; 447 } 448 else { 449 set_bad( ureg ); 450 i = 0; 451 } 452 453 out: 454 ureg->output[i].streams |= streams; 455 456 return ureg_dst_array_register(TGSI_FILE_OUTPUT, ureg->output[i].first, 457 array_id); 458 } 459 460 461 struct ureg_dst 462 ureg_DECL_output_masked(struct ureg_program *ureg, 463 unsigned name, 464 unsigned index, 465 unsigned usage_mask, 466 unsigned array_id, 467 unsigned array_size) 468 { 469 return ureg_DECL_output_layout(ureg, name, index, 0, 470 ureg->nr_output_regs, usage_mask, array_id, array_size); 471 } 472 473 474 struct ureg_dst 475 ureg_DECL_output(struct ureg_program *ureg, 476 unsigned name, 477 unsigned index) 478 { 479 return ureg_DECL_output_masked(ureg, name, index, TGSI_WRITEMASK_XYZW, 480 0, 1); 481 } 482 483 struct ureg_dst 484 ureg_DECL_output_array(struct ureg_program *ureg, 485 unsigned semantic_name, 486 unsigned semantic_index, 487 unsigned array_id, 488 unsigned array_size) 489 { 490 return ureg_DECL_output_masked(ureg, semantic_name, semantic_index, 491 TGSI_WRITEMASK_XYZW, 492 array_id, array_size); 493 } 494 495 496 /* Returns a new constant register. Keep track of which have been 497 * referred to so that we can emit decls later. 498 * 499 * Constant operands declared with this function must be addressed 500 * with a two-dimensional index. 501 * 502 * There is nothing in this code to bind this constant to any tracked 503 * value or manage any constant_buffer contents -- that's the 504 * resposibility of the calling code. 505 */ 506 void 507 ureg_DECL_constant2D(struct ureg_program *ureg, 508 unsigned first, 509 unsigned last, 510 unsigned index2D) 511 { 512 struct const_decl *decl = &ureg->const_decls2D[index2D]; 513 514 assert(index2D < PIPE_MAX_CONSTANT_BUFFERS); 515 516 if (decl->nr_constant_ranges < UREG_MAX_CONSTANT_RANGE) { 517 uint i = decl->nr_constant_ranges++; 518 519 decl->constant_range[i].first = first; 520 decl->constant_range[i].last = last; 521 } 522 } 523 524 525 /* A one-dimensional, deprecated version of ureg_DECL_constant2D(). 526 * 527 * Constant operands declared with this function must be addressed 528 * with a one-dimensional index. 529 */ 530 struct ureg_src 531 ureg_DECL_constant(struct ureg_program *ureg, 532 unsigned index) 533 { 534 struct const_decl *decl = &ureg->const_decls; 535 unsigned minconst = index, maxconst = index; 536 unsigned i; 537 538 /* Inside existing range? 539 */ 540 for (i = 0; i < decl->nr_constant_ranges; i++) { 541 if (decl->constant_range[i].first <= index && 542 decl->constant_range[i].last >= index) { 543 goto out; 544 } 545 } 546 547 /* Extend existing range? 548 */ 549 for (i = 0; i < decl->nr_constant_ranges; i++) { 550 if (decl->constant_range[i].last == index - 1) { 551 decl->constant_range[i].last = index; 552 goto out; 553 } 554 555 if (decl->constant_range[i].first == index + 1) { 556 decl->constant_range[i].first = index; 557 goto out; 558 } 559 560 minconst = MIN2(minconst, decl->constant_range[i].first); 561 maxconst = MAX2(maxconst, decl->constant_range[i].last); 562 } 563 564 /* Create new range? 565 */ 566 if (decl->nr_constant_ranges < UREG_MAX_CONSTANT_RANGE) { 567 i = decl->nr_constant_ranges++; 568 decl->constant_range[i].first = index; 569 decl->constant_range[i].last = index; 570 goto out; 571 } 572 573 /* Collapse all ranges down to one: 574 */ 575 i = 0; 576 decl->constant_range[0].first = minconst; 577 decl->constant_range[0].last = maxconst; 578 decl->nr_constant_ranges = 1; 579 580 out: 581 assert(i < decl->nr_constant_ranges); 582 assert(decl->constant_range[i].first <= index); 583 assert(decl->constant_range[i].last >= index); 584 return ureg_src_register(TGSI_FILE_CONSTANT, index); 585 } 586 587 static struct ureg_dst alloc_temporary( struct ureg_program *ureg, 588 boolean local ) 589 { 590 unsigned i; 591 592 /* Look for a released temporary. 593 */ 594 for (i = util_bitmask_get_first_index(ureg->free_temps); 595 i != UTIL_BITMASK_INVALID_INDEX; 596 i = util_bitmask_get_next_index(ureg->free_temps, i + 1)) { 597 if (util_bitmask_get(ureg->local_temps, i) == local) 598 break; 599 } 600 601 /* Or allocate a new one. 602 */ 603 if (i == UTIL_BITMASK_INVALID_INDEX) { 604 i = ureg->nr_temps++; 605 606 if (local) 607 util_bitmask_set(ureg->local_temps, i); 608 609 /* Start a new declaration when the local flag changes */ 610 if (!i || util_bitmask_get(ureg->local_temps, i - 1) != local) 611 util_bitmask_set(ureg->decl_temps, i); 612 } 613 614 util_bitmask_clear(ureg->free_temps, i); 615 616 return ureg_dst_register( TGSI_FILE_TEMPORARY, i ); 617 } 618 619 struct ureg_dst ureg_DECL_temporary( struct ureg_program *ureg ) 620 { 621 return alloc_temporary(ureg, FALSE); 622 } 623 624 struct ureg_dst ureg_DECL_local_temporary( struct ureg_program *ureg ) 625 { 626 return alloc_temporary(ureg, TRUE); 627 } 628 629 struct ureg_dst ureg_DECL_array_temporary( struct ureg_program *ureg, 630 unsigned size, 631 boolean local ) 632 { 633 unsigned i = ureg->nr_temps; 634 struct ureg_dst dst = ureg_dst_register( TGSI_FILE_TEMPORARY, i ); 635 636 if (local) 637 util_bitmask_set(ureg->local_temps, i); 638 639 /* Always start a new declaration at the start */ 640 util_bitmask_set(ureg->decl_temps, i); 641 642 ureg->nr_temps += size; 643 644 /* and also at the end of the array */ 645 util_bitmask_set(ureg->decl_temps, ureg->nr_temps); 646 647 if (ureg->nr_array_temps < UREG_MAX_ARRAY_TEMPS) { 648 ureg->array_temps[ureg->nr_array_temps++] = i; 649 dst.ArrayID = ureg->nr_array_temps; 650 } 651 652 return dst; 653 } 654 655 void ureg_release_temporary( struct ureg_program *ureg, 656 struct ureg_dst tmp ) 657 { 658 if(tmp.File == TGSI_FILE_TEMPORARY) 659 util_bitmask_set(ureg->free_temps, tmp.Index); 660 } 661 662 663 /* Allocate a new address register. 664 */ 665 struct ureg_dst ureg_DECL_address( struct ureg_program *ureg ) 666 { 667 if (ureg->nr_addrs < UREG_MAX_ADDR) 668 return ureg_dst_register( TGSI_FILE_ADDRESS, ureg->nr_addrs++ ); 669 670 assert( 0 ); 671 return ureg_dst_register( TGSI_FILE_ADDRESS, 0 ); 672 } 673 674 /* Allocate a new predicate register. 675 */ 676 struct ureg_dst 677 ureg_DECL_predicate(struct ureg_program *ureg) 678 { 679 if (ureg->nr_preds < UREG_MAX_PRED) { 680 return ureg_dst_register(TGSI_FILE_PREDICATE, ureg->nr_preds++); 681 } 682 683 assert(0); 684 return ureg_dst_register(TGSI_FILE_PREDICATE, 0); 685 } 686 687 /* Allocate a new sampler. 688 */ 689 struct ureg_src ureg_DECL_sampler( struct ureg_program *ureg, 690 unsigned nr ) 691 { 692 unsigned i; 693 694 for (i = 0; i < ureg->nr_samplers; i++) 695 if (ureg->sampler[i].Index == nr) 696 return ureg->sampler[i]; 697 698 if (i < PIPE_MAX_SAMPLERS) { 699 ureg->sampler[i] = ureg_src_register( TGSI_FILE_SAMPLER, nr ); 700 ureg->nr_samplers++; 701 return ureg->sampler[i]; 702 } 703 704 assert( 0 ); 705 return ureg->sampler[0]; 706 } 707 708 /* 709 * Allocate a new shader sampler view. 710 */ 711 struct ureg_src 712 ureg_DECL_sampler_view(struct ureg_program *ureg, 713 unsigned index, 714 unsigned target, 715 unsigned return_type_x, 716 unsigned return_type_y, 717 unsigned return_type_z, 718 unsigned return_type_w) 719 { 720 struct ureg_src reg = ureg_src_register(TGSI_FILE_SAMPLER_VIEW, index); 721 uint i; 722 723 for (i = 0; i < ureg->nr_sampler_views; i++) { 724 if (ureg->sampler_view[i].index == index) { 725 return reg; 726 } 727 } 728 729 if (i < PIPE_MAX_SHADER_SAMPLER_VIEWS) { 730 ureg->sampler_view[i].index = index; 731 ureg->sampler_view[i].target = target; 732 ureg->sampler_view[i].return_type_x = return_type_x; 733 ureg->sampler_view[i].return_type_y = return_type_y; 734 ureg->sampler_view[i].return_type_z = return_type_z; 735 ureg->sampler_view[i].return_type_w = return_type_w; 736 ureg->nr_sampler_views++; 737 return reg; 738 } 739 740 assert(0); 741 return reg; 742 } 743 744 /* Allocate a new image. 745 */ 746 struct ureg_src 747 ureg_DECL_image(struct ureg_program *ureg, 748 unsigned index, 749 unsigned target, 750 unsigned format, 751 boolean wr, 752 boolean raw) 753 { 754 struct ureg_src reg = ureg_src_register(TGSI_FILE_IMAGE, index); 755 unsigned i; 756 757 for (i = 0; i < ureg->nr_images; i++) 758 if (ureg->image[i].index == index) 759 return reg; 760 761 if (i < PIPE_MAX_SHADER_IMAGES) { 762 ureg->image[i].index = index; 763 ureg->image[i].target = target; 764 ureg->image[i].wr = wr; 765 ureg->image[i].raw = raw; 766 ureg->image[i].format = format; 767 ureg->nr_images++; 768 return reg; 769 } 770 771 assert(0); 772 return reg; 773 } 774 775 /* Allocate a new buffer. 776 */ 777 struct ureg_src ureg_DECL_buffer(struct ureg_program *ureg, unsigned nr, 778 bool atomic) 779 { 780 struct ureg_src reg = ureg_src_register(TGSI_FILE_BUFFER, nr); 781 unsigned i; 782 783 for (i = 0; i < ureg->nr_buffers; i++) 784 if (ureg->buffer[i].index == nr) 785 return reg; 786 787 if (i < PIPE_MAX_SHADER_BUFFERS) { 788 ureg->buffer[i].index = nr; 789 ureg->buffer[i].atomic = atomic; 790 ureg->nr_buffers++; 791 return reg; 792 } 793 794 assert(0); 795 return reg; 796 } 797 798 /* Allocate a memory area. 799 */ 800 struct ureg_src ureg_DECL_memory(struct ureg_program *ureg, 801 unsigned memory_type) 802 { 803 struct ureg_src reg = ureg_src_register(TGSI_FILE_MEMORY, memory_type); 804 805 ureg->use_memory[memory_type] = true; 806 return reg; 807 } 808 809 static int 810 match_or_expand_immediate64( const unsigned *v, 811 int type, 812 unsigned nr, 813 unsigned *v2, 814 unsigned *pnr2, 815 unsigned *swizzle ) 816 { 817 unsigned nr2 = *pnr2; 818 unsigned i, j; 819 *swizzle = 0; 820 821 for (i = 0; i < nr; i += 2) { 822 boolean found = FALSE; 823 824 for (j = 0; j < nr2 && !found; j += 2) { 825 if (v[i] == v2[j] && v[i + 1] == v2[j + 1]) { 826 *swizzle |= (j << (i * 2)) | ((j + 1) << ((i + 1) * 2)); 827 found = TRUE; 828 } 829 } 830 if (!found) { 831 if ((nr2) >= 4) { 832 return FALSE; 833 } 834 835 v2[nr2] = v[i]; 836 v2[nr2 + 1] = v[i + 1]; 837 838 *swizzle |= (nr2 << (i * 2)) | ((nr2 + 1) << ((i + 1) * 2)); 839 nr2 += 2; 840 } 841 } 842 843 /* Actually expand immediate only when fully succeeded. 844 */ 845 *pnr2 = nr2; 846 return TRUE; 847 } 848 849 static int 850 match_or_expand_immediate( const unsigned *v, 851 int type, 852 unsigned nr, 853 unsigned *v2, 854 unsigned *pnr2, 855 unsigned *swizzle ) 856 { 857 unsigned nr2 = *pnr2; 858 unsigned i, j; 859 860 if (type == TGSI_IMM_FLOAT64 || 861 type == TGSI_IMM_UINT64 || 862 type == TGSI_IMM_INT64) 863 return match_or_expand_immediate64(v, type, nr, v2, pnr2, swizzle); 864 865 *swizzle = 0; 866 867 for (i = 0; i < nr; i++) { 868 boolean found = FALSE; 869 870 for (j = 0; j < nr2 && !found; j++) { 871 if (v[i] == v2[j]) { 872 *swizzle |= j << (i * 2); 873 found = TRUE; 874 } 875 } 876 877 if (!found) { 878 if (nr2 >= 4) { 879 return FALSE; 880 } 881 882 v2[nr2] = v[i]; 883 *swizzle |= nr2 << (i * 2); 884 nr2++; 885 } 886 } 887 888 /* Actually expand immediate only when fully succeeded. 889 */ 890 *pnr2 = nr2; 891 return TRUE; 892 } 893 894 895 static struct ureg_src 896 decl_immediate( struct ureg_program *ureg, 897 const unsigned *v, 898 unsigned nr, 899 unsigned type ) 900 { 901 unsigned i, j; 902 unsigned swizzle = 0; 903 904 /* Could do a first pass where we examine all existing immediates 905 * without expanding. 906 */ 907 908 for (i = 0; i < ureg->nr_immediates; i++) { 909 if (ureg->immediate[i].type != type) { 910 continue; 911 } 912 if (match_or_expand_immediate(v, 913 type, 914 nr, 915 ureg->immediate[i].value.u, 916 &ureg->immediate[i].nr, 917 &swizzle)) { 918 goto out; 919 } 920 } 921 922 if (ureg->nr_immediates < UREG_MAX_IMMEDIATE) { 923 i = ureg->nr_immediates++; 924 ureg->immediate[i].type = type; 925 if (match_or_expand_immediate(v, 926 type, 927 nr, 928 ureg->immediate[i].value.u, 929 &ureg->immediate[i].nr, 930 &swizzle)) { 931 goto out; 932 } 933 } 934 935 set_bad(ureg); 936 937 out: 938 /* Make sure that all referenced elements are from this immediate. 939 * Has the effect of making size-one immediates into scalars. 940 */ 941 if (type == TGSI_IMM_FLOAT64 || 942 type == TGSI_IMM_UINT64 || 943 type == TGSI_IMM_INT64) { 944 for (j = nr; j < 4; j+=2) { 945 swizzle |= (swizzle & 0xf) << (j * 2); 946 } 947 } else { 948 for (j = nr; j < 4; j++) { 949 swizzle |= (swizzle & 0x3) << (j * 2); 950 } 951 } 952 return ureg_swizzle(ureg_src_register(TGSI_FILE_IMMEDIATE, i), 953 (swizzle >> 0) & 0x3, 954 (swizzle >> 2) & 0x3, 955 (swizzle >> 4) & 0x3, 956 (swizzle >> 6) & 0x3); 957 } 958 959 960 struct ureg_src 961 ureg_DECL_immediate( struct ureg_program *ureg, 962 const float *v, 963 unsigned nr ) 964 { 965 union { 966 float f[4]; 967 unsigned u[4]; 968 } fu; 969 unsigned int i; 970 971 for (i = 0; i < nr; i++) { 972 fu.f[i] = v[i]; 973 } 974 975 return decl_immediate(ureg, fu.u, nr, TGSI_IMM_FLOAT32); 976 } 977 978 struct ureg_src 979 ureg_DECL_immediate_f64( struct ureg_program *ureg, 980 const double *v, 981 unsigned nr ) 982 { 983 union { 984 unsigned u[4]; 985 double d[2]; 986 } fu; 987 unsigned int i; 988 989 assert((nr / 2) < 3); 990 for (i = 0; i < nr / 2; i++) { 991 fu.d[i] = v[i]; 992 } 993 994 return decl_immediate(ureg, fu.u, nr, TGSI_IMM_FLOAT64); 995 } 996 997 struct ureg_src 998 ureg_DECL_immediate_uint( struct ureg_program *ureg, 999 const unsigned *v, 1000 unsigned nr ) 1001 { 1002 return decl_immediate(ureg, v, nr, TGSI_IMM_UINT32); 1003 } 1004 1005 1006 struct ureg_src 1007 ureg_DECL_immediate_block_uint( struct ureg_program *ureg, 1008 const unsigned *v, 1009 unsigned nr ) 1010 { 1011 uint index; 1012 uint i; 1013 1014 if (ureg->nr_immediates + (nr + 3) / 4 > UREG_MAX_IMMEDIATE) { 1015 set_bad(ureg); 1016 return ureg_src_register(TGSI_FILE_IMMEDIATE, 0); 1017 } 1018 1019 index = ureg->nr_immediates; 1020 ureg->nr_immediates += (nr + 3) / 4; 1021 1022 for (i = index; i < ureg->nr_immediates; i++) { 1023 ureg->immediate[i].type = TGSI_IMM_UINT32; 1024 ureg->immediate[i].nr = nr > 4 ? 4 : nr; 1025 memcpy(ureg->immediate[i].value.u, 1026 &v[(i - index) * 4], 1027 ureg->immediate[i].nr * sizeof(uint)); 1028 nr -= 4; 1029 } 1030 1031 return ureg_src_register(TGSI_FILE_IMMEDIATE, index); 1032 } 1033 1034 1035 struct ureg_src 1036 ureg_DECL_immediate_int( struct ureg_program *ureg, 1037 const int *v, 1038 unsigned nr ) 1039 { 1040 return decl_immediate(ureg, (const unsigned *)v, nr, TGSI_IMM_INT32); 1041 } 1042 1043 struct ureg_src 1044 ureg_DECL_immediate_uint64( struct ureg_program *ureg, 1045 const uint64_t *v, 1046 unsigned nr ) 1047 { 1048 union { 1049 unsigned u[4]; 1050 uint64_t u64[2]; 1051 } fu; 1052 unsigned int i; 1053 1054 assert((nr / 2) < 3); 1055 for (i = 0; i < nr / 2; i++) { 1056 fu.u64[i] = v[i]; 1057 } 1058 1059 return decl_immediate(ureg, fu.u, nr, TGSI_IMM_UINT64); 1060 } 1061 1062 struct ureg_src 1063 ureg_DECL_immediate_int64( struct ureg_program *ureg, 1064 const int64_t *v, 1065 unsigned nr ) 1066 { 1067 union { 1068 unsigned u[4]; 1069 int64_t i64[2]; 1070 } fu; 1071 unsigned int i; 1072 1073 assert((nr / 2) < 3); 1074 for (i = 0; i < nr / 2; i++) { 1075 fu.i64[i] = v[i]; 1076 } 1077 1078 return decl_immediate(ureg, fu.u, nr, TGSI_IMM_INT64); 1079 } 1080 1081 void 1082 ureg_emit_src( struct ureg_program *ureg, 1083 struct ureg_src src ) 1084 { 1085 unsigned size = 1 + (src.Indirect ? 1 : 0) + 1086 (src.Dimension ? (src.DimIndirect ? 2 : 1) : 0); 1087 1088 union tgsi_any_token *out = get_tokens( ureg, DOMAIN_INSN, size ); 1089 unsigned n = 0; 1090 1091 assert(src.File != TGSI_FILE_NULL); 1092 assert(src.File < TGSI_FILE_COUNT); 1093 1094 out[n].value = 0; 1095 out[n].src.File = src.File; 1096 out[n].src.SwizzleX = src.SwizzleX; 1097 out[n].src.SwizzleY = src.SwizzleY; 1098 out[n].src.SwizzleZ = src.SwizzleZ; 1099 out[n].src.SwizzleW = src.SwizzleW; 1100 out[n].src.Index = src.Index; 1101 out[n].src.Negate = src.Negate; 1102 out[0].src.Absolute = src.Absolute; 1103 n++; 1104 1105 if (src.Indirect) { 1106 out[0].src.Indirect = 1; 1107 out[n].value = 0; 1108 out[n].ind.File = src.IndirectFile; 1109 out[n].ind.Swizzle = src.IndirectSwizzle; 1110 out[n].ind.Index = src.IndirectIndex; 1111 if (!ureg->supports_any_inout_decl_range && 1112 (src.File == TGSI_FILE_INPUT || src.File == TGSI_FILE_OUTPUT)) 1113 out[n].ind.ArrayID = 0; 1114 else 1115 out[n].ind.ArrayID = src.ArrayID; 1116 n++; 1117 } 1118 1119 if (src.Dimension) { 1120 out[0].src.Dimension = 1; 1121 out[n].dim.Dimension = 0; 1122 out[n].dim.Padding = 0; 1123 if (src.DimIndirect) { 1124 out[n].dim.Indirect = 1; 1125 out[n].dim.Index = src.DimensionIndex; 1126 n++; 1127 out[n].value = 0; 1128 out[n].ind.File = src.DimIndFile; 1129 out[n].ind.Swizzle = src.DimIndSwizzle; 1130 out[n].ind.Index = src.DimIndIndex; 1131 if (!ureg->supports_any_inout_decl_range && 1132 (src.File == TGSI_FILE_INPUT || src.File == TGSI_FILE_OUTPUT)) 1133 out[n].ind.ArrayID = 0; 1134 else 1135 out[n].ind.ArrayID = src.ArrayID; 1136 } else { 1137 out[n].dim.Indirect = 0; 1138 out[n].dim.Index = src.DimensionIndex; 1139 } 1140 n++; 1141 } 1142 1143 assert(n == size); 1144 } 1145 1146 1147 void 1148 ureg_emit_dst( struct ureg_program *ureg, 1149 struct ureg_dst dst ) 1150 { 1151 unsigned size = 1 + (dst.Indirect ? 1 : 0) + 1152 (dst.Dimension ? (dst.DimIndirect ? 2 : 1) : 0); 1153 1154 union tgsi_any_token *out = get_tokens( ureg, DOMAIN_INSN, size ); 1155 unsigned n = 0; 1156 1157 assert(dst.File != TGSI_FILE_NULL); 1158 assert(dst.File != TGSI_FILE_CONSTANT); 1159 assert(dst.File != TGSI_FILE_INPUT); 1160 assert(dst.File != TGSI_FILE_SAMPLER); 1161 assert(dst.File != TGSI_FILE_SAMPLER_VIEW); 1162 assert(dst.File != TGSI_FILE_IMMEDIATE); 1163 assert(dst.File < TGSI_FILE_COUNT); 1164 1165 out[n].value = 0; 1166 out[n].dst.File = dst.File; 1167 out[n].dst.WriteMask = dst.WriteMask; 1168 out[n].dst.Indirect = dst.Indirect; 1169 out[n].dst.Index = dst.Index; 1170 n++; 1171 1172 if (dst.Indirect) { 1173 out[n].value = 0; 1174 out[n].ind.File = dst.IndirectFile; 1175 out[n].ind.Swizzle = dst.IndirectSwizzle; 1176 out[n].ind.Index = dst.IndirectIndex; 1177 if (!ureg->supports_any_inout_decl_range && 1178 (dst.File == TGSI_FILE_INPUT || dst.File == TGSI_FILE_OUTPUT)) 1179 out[n].ind.ArrayID = 0; 1180 else 1181 out[n].ind.ArrayID = dst.ArrayID; 1182 n++; 1183 } 1184 1185 if (dst.Dimension) { 1186 out[0].dst.Dimension = 1; 1187 out[n].dim.Dimension = 0; 1188 out[n].dim.Padding = 0; 1189 if (dst.DimIndirect) { 1190 out[n].dim.Indirect = 1; 1191 out[n].dim.Index = dst.DimensionIndex; 1192 n++; 1193 out[n].value = 0; 1194 out[n].ind.File = dst.DimIndFile; 1195 out[n].ind.Swizzle = dst.DimIndSwizzle; 1196 out[n].ind.Index = dst.DimIndIndex; 1197 if (!ureg->supports_any_inout_decl_range && 1198 (dst.File == TGSI_FILE_INPUT || dst.File == TGSI_FILE_OUTPUT)) 1199 out[n].ind.ArrayID = 0; 1200 else 1201 out[n].ind.ArrayID = dst.ArrayID; 1202 } else { 1203 out[n].dim.Indirect = 0; 1204 out[n].dim.Index = dst.DimensionIndex; 1205 } 1206 n++; 1207 } 1208 1209 assert(n == size); 1210 } 1211 1212 1213 static void validate( unsigned opcode, 1214 unsigned nr_dst, 1215 unsigned nr_src ) 1216 { 1217 #ifdef DEBUG 1218 const struct tgsi_opcode_info *info = tgsi_get_opcode_info( opcode ); 1219 assert(info); 1220 if (info) { 1221 assert(nr_dst == info->num_dst); 1222 assert(nr_src == info->num_src); 1223 } 1224 #endif 1225 } 1226 1227 struct ureg_emit_insn_result 1228 ureg_emit_insn(struct ureg_program *ureg, 1229 unsigned opcode, 1230 boolean saturate, 1231 boolean predicate, 1232 boolean pred_negate, 1233 unsigned pred_swizzle_x, 1234 unsigned pred_swizzle_y, 1235 unsigned pred_swizzle_z, 1236 unsigned pred_swizzle_w, 1237 unsigned num_dst, 1238 unsigned num_src ) 1239 { 1240 union tgsi_any_token *out; 1241 uint count = predicate ? 2 : 1; 1242 struct ureg_emit_insn_result result; 1243 1244 validate( opcode, num_dst, num_src ); 1245 1246 out = get_tokens( ureg, DOMAIN_INSN, count ); 1247 out[0].insn = tgsi_default_instruction(); 1248 out[0].insn.Opcode = opcode; 1249 out[0].insn.Saturate = saturate; 1250 out[0].insn.NumDstRegs = num_dst; 1251 out[0].insn.NumSrcRegs = num_src; 1252 1253 result.insn_token = ureg->domain[DOMAIN_INSN].count - count; 1254 result.extended_token = result.insn_token; 1255 1256 if (predicate) { 1257 out[0].insn.Predicate = 1; 1258 out[1].insn_predicate = tgsi_default_instruction_predicate(); 1259 out[1].insn_predicate.Negate = pred_negate; 1260 out[1].insn_predicate.SwizzleX = pred_swizzle_x; 1261 out[1].insn_predicate.SwizzleY = pred_swizzle_y; 1262 out[1].insn_predicate.SwizzleZ = pred_swizzle_z; 1263 out[1].insn_predicate.SwizzleW = pred_swizzle_w; 1264 } 1265 1266 ureg->nr_instructions++; 1267 1268 return result; 1269 } 1270 1271 1272 /** 1273 * Emit a label token. 1274 * \param label_token returns a token number indicating where the label 1275 * needs to be patched later. Later, this value should be passed to the 1276 * ureg_fixup_label() function. 1277 */ 1278 void 1279 ureg_emit_label(struct ureg_program *ureg, 1280 unsigned extended_token, 1281 unsigned *label_token ) 1282 { 1283 union tgsi_any_token *out, *insn; 1284 1285 if (!label_token) 1286 return; 1287 1288 out = get_tokens( ureg, DOMAIN_INSN, 1 ); 1289 out[0].value = 0; 1290 1291 insn = retrieve_token( ureg, DOMAIN_INSN, extended_token ); 1292 insn->insn.Label = 1; 1293 1294 *label_token = ureg->domain[DOMAIN_INSN].count - 1; 1295 } 1296 1297 /* Will return a number which can be used in a label to point to the 1298 * next instruction to be emitted. 1299 */ 1300 unsigned 1301 ureg_get_instruction_number( struct ureg_program *ureg ) 1302 { 1303 return ureg->nr_instructions; 1304 } 1305 1306 /* Patch a given label (expressed as a token number) to point to a 1307 * given instruction (expressed as an instruction number). 1308 */ 1309 void 1310 ureg_fixup_label(struct ureg_program *ureg, 1311 unsigned label_token, 1312 unsigned instruction_number ) 1313 { 1314 union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_INSN, label_token ); 1315 1316 out->insn_label.Label = instruction_number; 1317 } 1318 1319 1320 void 1321 ureg_emit_texture(struct ureg_program *ureg, 1322 unsigned extended_token, 1323 unsigned target, unsigned num_offsets) 1324 { 1325 union tgsi_any_token *out, *insn; 1326 1327 out = get_tokens( ureg, DOMAIN_INSN, 1 ); 1328 insn = retrieve_token( ureg, DOMAIN_INSN, extended_token ); 1329 1330 insn->insn.Texture = 1; 1331 1332 out[0].value = 0; 1333 out[0].insn_texture.Texture = target; 1334 out[0].insn_texture.NumOffsets = num_offsets; 1335 } 1336 1337 void 1338 ureg_emit_texture_offset(struct ureg_program *ureg, 1339 const struct tgsi_texture_offset *offset) 1340 { 1341 union tgsi_any_token *out; 1342 1343 out = get_tokens( ureg, DOMAIN_INSN, 1); 1344 1345 out[0].value = 0; 1346 out[0].insn_texture_offset = *offset; 1347 1348 } 1349 1350 void 1351 ureg_emit_memory(struct ureg_program *ureg, 1352 unsigned extended_token, 1353 unsigned qualifier, 1354 unsigned texture, 1355 unsigned format) 1356 { 1357 union tgsi_any_token *out, *insn; 1358 1359 out = get_tokens( ureg, DOMAIN_INSN, 1 ); 1360 insn = retrieve_token( ureg, DOMAIN_INSN, extended_token ); 1361 1362 insn->insn.Memory = 1; 1363 1364 out[0].value = 0; 1365 out[0].insn_memory.Qualifier = qualifier; 1366 out[0].insn_memory.Texture = texture; 1367 out[0].insn_memory.Format = format; 1368 } 1369 1370 void 1371 ureg_fixup_insn_size(struct ureg_program *ureg, 1372 unsigned insn ) 1373 { 1374 union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_INSN, insn ); 1375 1376 assert(out->insn.Type == TGSI_TOKEN_TYPE_INSTRUCTION); 1377 out->insn.NrTokens = ureg->domain[DOMAIN_INSN].count - insn - 1; 1378 } 1379 1380 1381 void 1382 ureg_insn(struct ureg_program *ureg, 1383 unsigned opcode, 1384 const struct ureg_dst *dst, 1385 unsigned nr_dst, 1386 const struct ureg_src *src, 1387 unsigned nr_src ) 1388 { 1389 struct ureg_emit_insn_result insn; 1390 unsigned i; 1391 boolean saturate; 1392 boolean predicate; 1393 boolean negate = FALSE; 1394 unsigned swizzle[4] = { 0 }; 1395 1396 if (nr_dst && ureg_dst_is_empty(dst[0])) { 1397 return; 1398 } 1399 1400 saturate = nr_dst ? dst[0].Saturate : FALSE; 1401 predicate = nr_dst ? dst[0].Predicate : FALSE; 1402 if (predicate) { 1403 negate = dst[0].PredNegate; 1404 swizzle[0] = dst[0].PredSwizzleX; 1405 swizzle[1] = dst[0].PredSwizzleY; 1406 swizzle[2] = dst[0].PredSwizzleZ; 1407 swizzle[3] = dst[0].PredSwizzleW; 1408 } 1409 1410 insn = ureg_emit_insn(ureg, 1411 opcode, 1412 saturate, 1413 predicate, 1414 negate, 1415 swizzle[0], 1416 swizzle[1], 1417 swizzle[2], 1418 swizzle[3], 1419 nr_dst, 1420 nr_src); 1421 1422 for (i = 0; i < nr_dst; i++) 1423 ureg_emit_dst( ureg, dst[i] ); 1424 1425 for (i = 0; i < nr_src; i++) 1426 ureg_emit_src( ureg, src[i] ); 1427 1428 ureg_fixup_insn_size( ureg, insn.insn_token ); 1429 } 1430 1431 void 1432 ureg_tex_insn(struct ureg_program *ureg, 1433 unsigned opcode, 1434 const struct ureg_dst *dst, 1435 unsigned nr_dst, 1436 unsigned target, 1437 const struct tgsi_texture_offset *texoffsets, 1438 unsigned nr_offset, 1439 const struct ureg_src *src, 1440 unsigned nr_src ) 1441 { 1442 struct ureg_emit_insn_result insn; 1443 unsigned i; 1444 boolean saturate; 1445 boolean predicate; 1446 boolean negate = FALSE; 1447 unsigned swizzle[4] = { 0 }; 1448 1449 if (nr_dst && ureg_dst_is_empty(dst[0])) { 1450 return; 1451 } 1452 1453 saturate = nr_dst ? dst[0].Saturate : FALSE; 1454 predicate = nr_dst ? dst[0].Predicate : FALSE; 1455 if (predicate) { 1456 negate = dst[0].PredNegate; 1457 swizzle[0] = dst[0].PredSwizzleX; 1458 swizzle[1] = dst[0].PredSwizzleY; 1459 swizzle[2] = dst[0].PredSwizzleZ; 1460 swizzle[3] = dst[0].PredSwizzleW; 1461 } 1462 1463 insn = ureg_emit_insn(ureg, 1464 opcode, 1465 saturate, 1466 predicate, 1467 negate, 1468 swizzle[0], 1469 swizzle[1], 1470 swizzle[2], 1471 swizzle[3], 1472 nr_dst, 1473 nr_src); 1474 1475 ureg_emit_texture( ureg, insn.extended_token, target, nr_offset ); 1476 1477 for (i = 0; i < nr_offset; i++) 1478 ureg_emit_texture_offset( ureg, &texoffsets[i]); 1479 1480 for (i = 0; i < nr_dst; i++) 1481 ureg_emit_dst( ureg, dst[i] ); 1482 1483 for (i = 0; i < nr_src; i++) 1484 ureg_emit_src( ureg, src[i] ); 1485 1486 ureg_fixup_insn_size( ureg, insn.insn_token ); 1487 } 1488 1489 1490 void 1491 ureg_label_insn(struct ureg_program *ureg, 1492 unsigned opcode, 1493 const struct ureg_src *src, 1494 unsigned nr_src, 1495 unsigned *label_token ) 1496 { 1497 struct ureg_emit_insn_result insn; 1498 unsigned i; 1499 1500 insn = ureg_emit_insn(ureg, 1501 opcode, 1502 FALSE, 1503 FALSE, 1504 FALSE, 1505 TGSI_SWIZZLE_X, 1506 TGSI_SWIZZLE_Y, 1507 TGSI_SWIZZLE_Z, 1508 TGSI_SWIZZLE_W, 1509 0, 1510 nr_src); 1511 1512 ureg_emit_label( ureg, insn.extended_token, label_token ); 1513 1514 for (i = 0; i < nr_src; i++) 1515 ureg_emit_src( ureg, src[i] ); 1516 1517 ureg_fixup_insn_size( ureg, insn.insn_token ); 1518 } 1519 1520 1521 void 1522 ureg_memory_insn(struct ureg_program *ureg, 1523 unsigned opcode, 1524 const struct ureg_dst *dst, 1525 unsigned nr_dst, 1526 const struct ureg_src *src, 1527 unsigned nr_src, 1528 unsigned qualifier, 1529 unsigned texture, 1530 unsigned format) 1531 { 1532 struct ureg_emit_insn_result insn; 1533 unsigned i; 1534 1535 insn = ureg_emit_insn(ureg, 1536 opcode, 1537 FALSE, 1538 FALSE, 1539 FALSE, 1540 TGSI_SWIZZLE_X, 1541 TGSI_SWIZZLE_Y, 1542 TGSI_SWIZZLE_Z, 1543 TGSI_SWIZZLE_W, 1544 nr_dst, 1545 nr_src); 1546 1547 ureg_emit_memory(ureg, insn.extended_token, qualifier, texture, format); 1548 1549 for (i = 0; i < nr_dst; i++) 1550 ureg_emit_dst(ureg, dst[i]); 1551 1552 for (i = 0; i < nr_src; i++) 1553 ureg_emit_src(ureg, src[i]); 1554 1555 ureg_fixup_insn_size(ureg, insn.insn_token); 1556 } 1557 1558 1559 static void 1560 emit_decl_semantic(struct ureg_program *ureg, 1561 unsigned file, 1562 unsigned first, 1563 unsigned last, 1564 unsigned semantic_name, 1565 unsigned semantic_index, 1566 unsigned streams, 1567 unsigned usage_mask, 1568 unsigned array_id) 1569 { 1570 union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, array_id ? 4 : 3); 1571 1572 out[0].value = 0; 1573 out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION; 1574 out[0].decl.NrTokens = 3; 1575 out[0].decl.File = file; 1576 out[0].decl.UsageMask = usage_mask; 1577 out[0].decl.Semantic = 1; 1578 out[0].decl.Array = array_id != 0; 1579 1580 out[1].value = 0; 1581 out[1].decl_range.First = first; 1582 out[1].decl_range.Last = last; 1583 1584 out[2].value = 0; 1585 out[2].decl_semantic.Name = semantic_name; 1586 out[2].decl_semantic.Index = semantic_index; 1587 out[2].decl_semantic.StreamX = streams & 3; 1588 out[2].decl_semantic.StreamY = (streams >> 2) & 3; 1589 out[2].decl_semantic.StreamZ = (streams >> 4) & 3; 1590 out[2].decl_semantic.StreamW = (streams >> 6) & 3; 1591 1592 if (array_id) { 1593 out[3].value = 0; 1594 out[3].array.ArrayID = array_id; 1595 } 1596 } 1597 1598 1599 static void 1600 emit_decl_fs(struct ureg_program *ureg, 1601 unsigned file, 1602 unsigned first, 1603 unsigned last, 1604 unsigned semantic_name, 1605 unsigned semantic_index, 1606 unsigned interpolate, 1607 unsigned cylindrical_wrap, 1608 unsigned interpolate_location, 1609 unsigned array_id, 1610 unsigned usage_mask) 1611 { 1612 union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 1613 array_id ? 5 : 4); 1614 1615 out[0].value = 0; 1616 out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION; 1617 out[0].decl.NrTokens = 4; 1618 out[0].decl.File = file; 1619 out[0].decl.UsageMask = usage_mask; 1620 out[0].decl.Interpolate = 1; 1621 out[0].decl.Semantic = 1; 1622 out[0].decl.Array = array_id != 0; 1623 1624 out[1].value = 0; 1625 out[1].decl_range.First = first; 1626 out[1].decl_range.Last = last; 1627 1628 out[2].value = 0; 1629 out[2].decl_interp.Interpolate = interpolate; 1630 out[2].decl_interp.CylindricalWrap = cylindrical_wrap; 1631 out[2].decl_interp.Location = interpolate_location; 1632 1633 out[3].value = 0; 1634 out[3].decl_semantic.Name = semantic_name; 1635 out[3].decl_semantic.Index = semantic_index; 1636 1637 if (array_id) { 1638 out[4].value = 0; 1639 out[4].array.ArrayID = array_id; 1640 } 1641 } 1642 1643 static void 1644 emit_decl_temps( struct ureg_program *ureg, 1645 unsigned first, unsigned last, 1646 boolean local, 1647 unsigned arrayid ) 1648 { 1649 union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 1650 arrayid ? 3 : 2 ); 1651 1652 out[0].value = 0; 1653 out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION; 1654 out[0].decl.NrTokens = 2; 1655 out[0].decl.File = TGSI_FILE_TEMPORARY; 1656 out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW; 1657 out[0].decl.Local = local; 1658 1659 out[1].value = 0; 1660 out[1].decl_range.First = first; 1661 out[1].decl_range.Last = last; 1662 1663 if (arrayid) { 1664 out[0].decl.Array = 1; 1665 out[2].value = 0; 1666 out[2].array.ArrayID = arrayid; 1667 } 1668 } 1669 1670 static void emit_decl_range( struct ureg_program *ureg, 1671 unsigned file, 1672 unsigned first, 1673 unsigned count ) 1674 { 1675 union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 2 ); 1676 1677 out[0].value = 0; 1678 out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION; 1679 out[0].decl.NrTokens = 2; 1680 out[0].decl.File = file; 1681 out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW; 1682 out[0].decl.Semantic = 0; 1683 1684 out[1].value = 0; 1685 out[1].decl_range.First = first; 1686 out[1].decl_range.Last = first + count - 1; 1687 } 1688 1689 static void 1690 emit_decl_range2D(struct ureg_program *ureg, 1691 unsigned file, 1692 unsigned first, 1693 unsigned last, 1694 unsigned index2D) 1695 { 1696 union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 3); 1697 1698 out[0].value = 0; 1699 out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION; 1700 out[0].decl.NrTokens = 3; 1701 out[0].decl.File = file; 1702 out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW; 1703 out[0].decl.Dimension = 1; 1704 1705 out[1].value = 0; 1706 out[1].decl_range.First = first; 1707 out[1].decl_range.Last = last; 1708 1709 out[2].value = 0; 1710 out[2].decl_dim.Index2D = index2D; 1711 } 1712 1713 static void 1714 emit_decl_sampler_view(struct ureg_program *ureg, 1715 unsigned index, 1716 unsigned target, 1717 unsigned return_type_x, 1718 unsigned return_type_y, 1719 unsigned return_type_z, 1720 unsigned return_type_w ) 1721 { 1722 union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 3); 1723 1724 out[0].value = 0; 1725 out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION; 1726 out[0].decl.NrTokens = 3; 1727 out[0].decl.File = TGSI_FILE_SAMPLER_VIEW; 1728 out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW; 1729 1730 out[1].value = 0; 1731 out[1].decl_range.First = index; 1732 out[1].decl_range.Last = index; 1733 1734 out[2].value = 0; 1735 out[2].decl_sampler_view.Resource = target; 1736 out[2].decl_sampler_view.ReturnTypeX = return_type_x; 1737 out[2].decl_sampler_view.ReturnTypeY = return_type_y; 1738 out[2].decl_sampler_view.ReturnTypeZ = return_type_z; 1739 out[2].decl_sampler_view.ReturnTypeW = return_type_w; 1740 } 1741 1742 static void 1743 emit_decl_image(struct ureg_program *ureg, 1744 unsigned index, 1745 unsigned target, 1746 unsigned format, 1747 boolean wr, 1748 boolean raw) 1749 { 1750 union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 3); 1751 1752 out[0].value = 0; 1753 out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION; 1754 out[0].decl.NrTokens = 3; 1755 out[0].decl.File = TGSI_FILE_IMAGE; 1756 out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW; 1757 1758 out[1].value = 0; 1759 out[1].decl_range.First = index; 1760 out[1].decl_range.Last = index; 1761 1762 out[2].value = 0; 1763 out[2].decl_image.Resource = target; 1764 out[2].decl_image.Writable = wr; 1765 out[2].decl_image.Raw = raw; 1766 out[2].decl_image.Format = format; 1767 } 1768 1769 static void 1770 emit_decl_buffer(struct ureg_program *ureg, 1771 unsigned index, 1772 bool atomic) 1773 { 1774 union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 2); 1775 1776 out[0].value = 0; 1777 out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION; 1778 out[0].decl.NrTokens = 2; 1779 out[0].decl.File = TGSI_FILE_BUFFER; 1780 out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW; 1781 out[0].decl.Atomic = atomic; 1782 1783 out[1].value = 0; 1784 out[1].decl_range.First = index; 1785 out[1].decl_range.Last = index; 1786 } 1787 1788 static void 1789 emit_decl_memory(struct ureg_program *ureg, unsigned memory_type) 1790 { 1791 union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 2); 1792 1793 out[0].value = 0; 1794 out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION; 1795 out[0].decl.NrTokens = 2; 1796 out[0].decl.File = TGSI_FILE_MEMORY; 1797 out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW; 1798 out[0].decl.MemType = memory_type; 1799 1800 out[1].value = 0; 1801 out[1].decl_range.First = memory_type; 1802 out[1].decl_range.Last = memory_type; 1803 } 1804 1805 static void 1806 emit_immediate( struct ureg_program *ureg, 1807 const unsigned *v, 1808 unsigned type ) 1809 { 1810 union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 5 ); 1811 1812 out[0].value = 0; 1813 out[0].imm.Type = TGSI_TOKEN_TYPE_IMMEDIATE; 1814 out[0].imm.NrTokens = 5; 1815 out[0].imm.DataType = type; 1816 out[0].imm.Padding = 0; 1817 1818 out[1].imm_data.Uint = v[0]; 1819 out[2].imm_data.Uint = v[1]; 1820 out[3].imm_data.Uint = v[2]; 1821 out[4].imm_data.Uint = v[3]; 1822 } 1823 1824 static void 1825 emit_property(struct ureg_program *ureg, 1826 unsigned name, 1827 unsigned data) 1828 { 1829 union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 2); 1830 1831 out[0].value = 0; 1832 out[0].prop.Type = TGSI_TOKEN_TYPE_PROPERTY; 1833 out[0].prop.NrTokens = 2; 1834 out[0].prop.PropertyName = name; 1835 1836 out[1].prop_data.Data = data; 1837 } 1838 1839 1840 static void emit_decls( struct ureg_program *ureg ) 1841 { 1842 unsigned i,j; 1843 1844 for (i = 0; i < ARRAY_SIZE(ureg->properties); i++) 1845 if (ureg->properties[i] != ~0) 1846 emit_property(ureg, i, ureg->properties[i]); 1847 1848 if (ureg->processor == PIPE_SHADER_VERTEX) { 1849 for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { 1850 if (ureg->vs_inputs[i/32] & (1u << (i%32))) { 1851 emit_decl_range( ureg, TGSI_FILE_INPUT, i, 1 ); 1852 } 1853 } 1854 } else if (ureg->processor == PIPE_SHADER_FRAGMENT) { 1855 if (ureg->supports_any_inout_decl_range) { 1856 for (i = 0; i < ureg->nr_inputs; i++) { 1857 emit_decl_fs(ureg, 1858 TGSI_FILE_INPUT, 1859 ureg->input[i].first, 1860 ureg->input[i].last, 1861 ureg->input[i].semantic_name, 1862 ureg->input[i].semantic_index, 1863 ureg->input[i].interp, 1864 ureg->input[i].cylindrical_wrap, 1865 ureg->input[i].interp_location, 1866 ureg->input[i].array_id, 1867 ureg->input[i].usage_mask); 1868 } 1869 } 1870 else { 1871 for (i = 0; i < ureg->nr_inputs; i++) { 1872 for (j = ureg->input[i].first; j <= ureg->input[i].last; j++) { 1873 emit_decl_fs(ureg, 1874 TGSI_FILE_INPUT, 1875 j, j, 1876 ureg->input[i].semantic_name, 1877 ureg->input[i].semantic_index + 1878 (j - ureg->input[i].first), 1879 ureg->input[i].interp, 1880 ureg->input[i].cylindrical_wrap, 1881 ureg->input[i].interp_location, 0, 1882 ureg->input[i].usage_mask); 1883 } 1884 } 1885 } 1886 } else { 1887 if (ureg->supports_any_inout_decl_range) { 1888 for (i = 0; i < ureg->nr_inputs; i++) { 1889 emit_decl_semantic(ureg, 1890 TGSI_FILE_INPUT, 1891 ureg->input[i].first, 1892 ureg->input[i].last, 1893 ureg->input[i].semantic_name, 1894 ureg->input[i].semantic_index, 1895 0, 1896 TGSI_WRITEMASK_XYZW, 1897 ureg->input[i].array_id); 1898 } 1899 } 1900 else { 1901 for (i = 0; i < ureg->nr_inputs; i++) { 1902 for (j = ureg->input[i].first; j <= ureg->input[i].last; j++) { 1903 emit_decl_semantic(ureg, 1904 TGSI_FILE_INPUT, 1905 j, j, 1906 ureg->input[i].semantic_name, 1907 ureg->input[i].semantic_index + 1908 (j - ureg->input[i].first), 1909 0, 1910 TGSI_WRITEMASK_XYZW, 0); 1911 } 1912 } 1913 } 1914 } 1915 1916 for (i = 0; i < ureg->nr_system_values; i++) { 1917 emit_decl_semantic(ureg, 1918 TGSI_FILE_SYSTEM_VALUE, 1919 i, 1920 i, 1921 ureg->system_value[i].semantic_name, 1922 ureg->system_value[i].semantic_index, 1923 0, 1924 TGSI_WRITEMASK_XYZW, 0); 1925 } 1926 1927 if (ureg->supports_any_inout_decl_range) { 1928 for (i = 0; i < ureg->nr_outputs; i++) { 1929 emit_decl_semantic(ureg, 1930 TGSI_FILE_OUTPUT, 1931 ureg->output[i].first, 1932 ureg->output[i].last, 1933 ureg->output[i].semantic_name, 1934 ureg->output[i].semantic_index, 1935 ureg->output[i].streams, 1936 ureg->output[i].usage_mask, 1937 ureg->output[i].array_id); 1938 } 1939 } 1940 else { 1941 for (i = 0; i < ureg->nr_outputs; i++) { 1942 for (j = ureg->output[i].first; j <= ureg->output[i].last; j++) { 1943 emit_decl_semantic(ureg, 1944 TGSI_FILE_OUTPUT, 1945 j, j, 1946 ureg->output[i].semantic_name, 1947 ureg->output[i].semantic_index + 1948 (j - ureg->output[i].first), 1949 ureg->output[i].streams, 1950 ureg->output[i].usage_mask, 0); 1951 } 1952 } 1953 } 1954 1955 for (i = 0; i < ureg->nr_samplers; i++) { 1956 emit_decl_range( ureg, 1957 TGSI_FILE_SAMPLER, 1958 ureg->sampler[i].Index, 1 ); 1959 } 1960 1961 for (i = 0; i < ureg->nr_sampler_views; i++) { 1962 emit_decl_sampler_view(ureg, 1963 ureg->sampler_view[i].index, 1964 ureg->sampler_view[i].target, 1965 ureg->sampler_view[i].return_type_x, 1966 ureg->sampler_view[i].return_type_y, 1967 ureg->sampler_view[i].return_type_z, 1968 ureg->sampler_view[i].return_type_w); 1969 } 1970 1971 for (i = 0; i < ureg->nr_images; i++) { 1972 emit_decl_image(ureg, 1973 ureg->image[i].index, 1974 ureg->image[i].target, 1975 ureg->image[i].format, 1976 ureg->image[i].wr, 1977 ureg->image[i].raw); 1978 } 1979 1980 for (i = 0; i < ureg->nr_buffers; i++) { 1981 emit_decl_buffer(ureg, ureg->buffer[i].index, ureg->buffer[i].atomic); 1982 } 1983 1984 for (i = 0; i < TGSI_MEMORY_TYPE_COUNT; i++) { 1985 if (ureg->use_memory[i]) 1986 emit_decl_memory(ureg, i); 1987 } 1988 1989 if (ureg->const_decls.nr_constant_ranges) { 1990 for (i = 0; i < ureg->const_decls.nr_constant_ranges; i++) { 1991 emit_decl_range(ureg, 1992 TGSI_FILE_CONSTANT, 1993 ureg->const_decls.constant_range[i].first, 1994 ureg->const_decls.constant_range[i].last - ureg->const_decls.constant_range[i].first + 1); 1995 } 1996 } 1997 1998 for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) { 1999 struct const_decl *decl = &ureg->const_decls2D[i]; 2000 2001 if (decl->nr_constant_ranges) { 2002 uint j; 2003 2004 for (j = 0; j < decl->nr_constant_ranges; j++) { 2005 emit_decl_range2D(ureg, 2006 TGSI_FILE_CONSTANT, 2007 decl->constant_range[j].first, 2008 decl->constant_range[j].last, 2009 i); 2010 } 2011 } 2012 } 2013 2014 if (ureg->nr_temps) { 2015 unsigned array = 0; 2016 for (i = 0; i < ureg->nr_temps;) { 2017 boolean local = util_bitmask_get(ureg->local_temps, i); 2018 unsigned first = i; 2019 i = util_bitmask_get_next_index(ureg->decl_temps, i + 1); 2020 if (i == UTIL_BITMASK_INVALID_INDEX) 2021 i = ureg->nr_temps; 2022 2023 if (array < ureg->nr_array_temps && ureg->array_temps[array] == first) 2024 emit_decl_temps( ureg, first, i - 1, local, ++array ); 2025 else 2026 emit_decl_temps( ureg, first, i - 1, local, 0 ); 2027 } 2028 } 2029 2030 if (ureg->nr_addrs) { 2031 emit_decl_range( ureg, 2032 TGSI_FILE_ADDRESS, 2033 0, ureg->nr_addrs ); 2034 } 2035 2036 if (ureg->nr_preds) { 2037 emit_decl_range(ureg, 2038 TGSI_FILE_PREDICATE, 2039 0, 2040 ureg->nr_preds); 2041 } 2042 2043 for (i = 0; i < ureg->nr_immediates; i++) { 2044 emit_immediate( ureg, 2045 ureg->immediate[i].value.u, 2046 ureg->immediate[i].type ); 2047 } 2048 } 2049 2050 /* Append the instruction tokens onto the declarations to build a 2051 * contiguous stream suitable to send to the driver. 2052 */ 2053 static void copy_instructions( struct ureg_program *ureg ) 2054 { 2055 unsigned nr_tokens = ureg->domain[DOMAIN_INSN].count; 2056 union tgsi_any_token *out = get_tokens( ureg, 2057 DOMAIN_DECL, 2058 nr_tokens ); 2059 2060 memcpy(out, 2061 ureg->domain[DOMAIN_INSN].tokens, 2062 nr_tokens * sizeof out[0] ); 2063 } 2064 2065 2066 static void 2067 fixup_header_size(struct ureg_program *ureg) 2068 { 2069 union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_DECL, 0 ); 2070 2071 out->header.BodySize = ureg->domain[DOMAIN_DECL].count - 2; 2072 } 2073 2074 2075 static void 2076 emit_header( struct ureg_program *ureg ) 2077 { 2078 union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 2 ); 2079 2080 out[0].header.HeaderSize = 2; 2081 out[0].header.BodySize = 0; 2082 2083 out[1].processor.Processor = ureg->processor; 2084 out[1].processor.Padding = 0; 2085 } 2086 2087 2088 const struct tgsi_token *ureg_finalize( struct ureg_program *ureg ) 2089 { 2090 const struct tgsi_token *tokens; 2091 2092 switch (ureg->processor) { 2093 case PIPE_SHADER_VERTEX: 2094 case PIPE_SHADER_TESS_EVAL: 2095 ureg_property(ureg, TGSI_PROPERTY_NEXT_SHADER, 2096 ureg->next_shader_processor == -1 ? 2097 PIPE_SHADER_FRAGMENT : 2098 ureg->next_shader_processor); 2099 break; 2100 } 2101 2102 emit_header( ureg ); 2103 emit_decls( ureg ); 2104 copy_instructions( ureg ); 2105 fixup_header_size( ureg ); 2106 2107 if (ureg->domain[0].tokens == error_tokens || 2108 ureg->domain[1].tokens == error_tokens) { 2109 debug_printf("%s: error in generated shader\n", __FUNCTION__); 2110 assert(0); 2111 return NULL; 2112 } 2113 2114 tokens = &ureg->domain[DOMAIN_DECL].tokens[0].token; 2115 2116 if (0) { 2117 debug_printf("%s: emitted shader %d tokens:\n", __FUNCTION__, 2118 ureg->domain[DOMAIN_DECL].count); 2119 tgsi_dump( tokens, 0 ); 2120 } 2121 2122 #if DEBUG 2123 if (tokens && !tgsi_sanity_check(tokens)) { 2124 debug_printf("tgsi_ureg.c, sanity check failed on generated tokens:\n"); 2125 tgsi_dump(tokens, 0); 2126 assert(0); 2127 } 2128 #endif 2129 2130 2131 return tokens; 2132 } 2133 2134 2135 void *ureg_create_shader( struct ureg_program *ureg, 2136 struct pipe_context *pipe, 2137 const struct pipe_stream_output_info *so ) 2138 { 2139 struct pipe_shader_state state; 2140 2141 pipe_shader_state_from_tgsi(&state, ureg_finalize(ureg)); 2142 if(!state.tokens) 2143 return NULL; 2144 2145 if (so) 2146 state.stream_output = *so; 2147 2148 switch (ureg->processor) { 2149 case PIPE_SHADER_VERTEX: 2150 return pipe->create_vs_state(pipe, &state); 2151 case PIPE_SHADER_TESS_CTRL: 2152 return pipe->create_tcs_state(pipe, &state); 2153 case PIPE_SHADER_TESS_EVAL: 2154 return pipe->create_tes_state(pipe, &state); 2155 case PIPE_SHADER_GEOMETRY: 2156 return pipe->create_gs_state(pipe, &state); 2157 case PIPE_SHADER_FRAGMENT: 2158 return pipe->create_fs_state(pipe, &state); 2159 default: 2160 return NULL; 2161 } 2162 } 2163 2164 2165 const struct tgsi_token *ureg_get_tokens( struct ureg_program *ureg, 2166 unsigned *nr_tokens ) 2167 { 2168 const struct tgsi_token *tokens; 2169 2170 ureg_finalize(ureg); 2171 2172 tokens = &ureg->domain[DOMAIN_DECL].tokens[0].token; 2173 2174 if (nr_tokens) 2175 *nr_tokens = ureg->domain[DOMAIN_DECL].size; 2176 2177 ureg->domain[DOMAIN_DECL].tokens = 0; 2178 ureg->domain[DOMAIN_DECL].size = 0; 2179 ureg->domain[DOMAIN_DECL].order = 0; 2180 ureg->domain[DOMAIN_DECL].count = 0; 2181 2182 return tokens; 2183 } 2184 2185 2186 void ureg_free_tokens( const struct tgsi_token *tokens ) 2187 { 2188 FREE((struct tgsi_token *)tokens); 2189 } 2190 2191 2192 struct ureg_program * 2193 ureg_create(unsigned processor) 2194 { 2195 return ureg_create_with_screen(processor, NULL); 2196 } 2197 2198 2199 struct ureg_program * 2200 ureg_create_with_screen(unsigned processor, struct pipe_screen *screen) 2201 { 2202 int i; 2203 struct ureg_program *ureg = CALLOC_STRUCT( ureg_program ); 2204 if (!ureg) 2205 goto no_ureg; 2206 2207 ureg->processor = processor; 2208 ureg->supports_any_inout_decl_range = 2209 screen && 2210 screen->get_shader_param(screen, processor, 2211 PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE) != 0; 2212 ureg->next_shader_processor = -1; 2213 2214 for (i = 0; i < ARRAY_SIZE(ureg->properties); i++) 2215 ureg->properties[i] = ~0; 2216 2217 ureg->free_temps = util_bitmask_create(); 2218 if (ureg->free_temps == NULL) 2219 goto no_free_temps; 2220 2221 ureg->local_temps = util_bitmask_create(); 2222 if (ureg->local_temps == NULL) 2223 goto no_local_temps; 2224 2225 ureg->decl_temps = util_bitmask_create(); 2226 if (ureg->decl_temps == NULL) 2227 goto no_decl_temps; 2228 2229 return ureg; 2230 2231 no_decl_temps: 2232 util_bitmask_destroy(ureg->local_temps); 2233 no_local_temps: 2234 util_bitmask_destroy(ureg->free_temps); 2235 no_free_temps: 2236 FREE(ureg); 2237 no_ureg: 2238 return NULL; 2239 } 2240 2241 2242 void 2243 ureg_set_next_shader_processor(struct ureg_program *ureg, unsigned processor) 2244 { 2245 ureg->next_shader_processor = processor; 2246 } 2247 2248 2249 unsigned 2250 ureg_get_nr_outputs( const struct ureg_program *ureg ) 2251 { 2252 if (!ureg) 2253 return 0; 2254 return ureg->nr_outputs; 2255 } 2256 2257 2258 void ureg_destroy( struct ureg_program *ureg ) 2259 { 2260 unsigned i; 2261 2262 for (i = 0; i < ARRAY_SIZE(ureg->domain); i++) { 2263 if (ureg->domain[i].tokens && 2264 ureg->domain[i].tokens != error_tokens) 2265 FREE(ureg->domain[i].tokens); 2266 } 2267 2268 util_bitmask_destroy(ureg->free_temps); 2269 util_bitmask_destroy(ureg->local_temps); 2270 util_bitmask_destroy(ureg->decl_temps); 2271 2272 FREE(ureg); 2273 } 2274