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