f3c58761e1877fbf0966652f7ef0d3cd848e17bb
[mesa.git] / src / gallium / auxiliary / tgsi / tgsi_ureg.c
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 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
208 static union tgsi_any_token error_tokens[32];
209
210 static 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
221 static 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
242 static void set_bad( struct ureg_program *ureg )
243 {
244 tokens_error(&ureg->domain[0]);
245 }
246
247
248
249 static 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
265 static 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
276 void
277 ureg_property(struct ureg_program *ureg, unsigned name, unsigned value)
278 {
279 assert(name < ARRAY_SIZE(ureg->properties));
280 ureg->properties[name] = value;
281 }
282
283 struct ureg_src
284 ureg_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
331 out:
332 return ureg_src_array_register(TGSI_FILE_INPUT, ureg->input[i].first,
333 array_id);
334 }
335
336 struct ureg_src
337 ureg_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
353 struct ureg_src
354 ureg_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
365 struct ureg_src
366 ureg_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
381 struct ureg_src
382 ureg_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
395 struct ureg_src
396 ureg_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
418 out:
419 return ureg_src_register(TGSI_FILE_SYSTEM_VALUE, i);
420 }
421
422
423 struct ureg_dst
424 ureg_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
469 out:
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
477 struct ureg_dst
478 ureg_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
491 struct ureg_dst
492 ureg_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
500 struct ureg_dst
501 ureg_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 */
523 void
524 ureg_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 */
547 struct ureg_src
548 ureg_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
597 out:
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 */
610 void
611 ureg_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
630 static 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
662 struct ureg_dst ureg_DECL_temporary( struct ureg_program *ureg )
663 {
664 return alloc_temporary(ureg, FALSE);
665 }
666
667 struct ureg_dst ureg_DECL_local_temporary( struct ureg_program *ureg )
668 {
669 return alloc_temporary(ureg, TRUE);
670 }
671
672 struct 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
698 void 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 */
708 struct 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 */
719 struct 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 */
741 struct ureg_src
742 ureg_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 */
776 struct ureg_src
777 ureg_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 */
807 struct 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 */
830 struct 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
839 static int
840 match_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
878 static int
879 match_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
924 static struct ureg_src
925 decl_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
966 out:
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
989 struct ureg_src
990 ureg_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
1007 struct ureg_src
1008 ureg_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
1026 struct ureg_src
1027 ureg_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
1035 struct ureg_src
1036 ureg_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
1064 struct ureg_src
1065 ureg_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
1072 struct ureg_src
1073 ureg_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
1091 struct ureg_src
1092 ureg_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
1110 void
1111 ureg_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
1176 void
1177 ureg_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
1240 static void validate( enum tgsi_opcode opcode,
1241 unsigned nr_dst,
1242 unsigned nr_src )
1243 {
1244 #ifndef NDEBUG
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
1254 struct ureg_emit_insn_result
1255 ureg_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 */
1291 void
1292 ureg_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 */
1313 unsigned
1314 ureg_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 */
1322 void
1323 ureg_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
1333 void
1334 ureg_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
1352 void
1353 ureg_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
1364 void
1365 ureg_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
1384 void
1385 ureg_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
1395 void
1396 ureg_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
1430 void
1431 ureg_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
1475 void
1476 ureg_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
1508 static void
1509 emit_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
1549 static void
1550 emit_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
1579 static void
1580 emit_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
1623 static void
1624 emit_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
1650 static 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
1669 static void
1670 emit_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
1693 static void
1694 emit_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
1722 static void
1723 emit_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
1749 static void
1750 emit_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
1768 static void
1769 emit_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
1785 static void
1786 emit_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
1804 static void
1805 emit_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
1820 static 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 */
2037 static 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
2050 static void
2051 fixup_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
2059 static void
2060 emit_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
2072 const 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
2132 void *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 = {0};
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
2162 const 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
2183 void ureg_free_tokens( const struct tgsi_token *tokens )
2184 {
2185 FREE((struct tgsi_token *)tokens);
2186 }
2187
2188
2189 struct ureg_program *
2190 ureg_create(enum pipe_shader_type processor)
2191 {
2192 return ureg_create_with_screen(processor, NULL);
2193 }
2194
2195
2196 struct ureg_program *
2197 ureg_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
2229 no_decl_temps:
2230 util_bitmask_destroy(ureg->local_temps);
2231 no_local_temps:
2232 util_bitmask_destroy(ureg->free_temps);
2233 no_free_temps:
2234 FREE(ureg);
2235 no_ureg:
2236 return NULL;
2237 }
2238
2239
2240 void
2241 ureg_set_next_shader_processor(struct ureg_program *ureg, unsigned processor)
2242 {
2243 ureg->next_shader_processor = processor;
2244 }
2245
2246
2247 unsigned
2248 ureg_get_nr_outputs( const struct ureg_program *ureg )
2249 {
2250 if (!ureg)
2251 return 0;
2252 return ureg->nr_outputs;
2253 }
2254
2255
2256 void 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 }