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