gallium: plumb invariant output attrib thru TGSI
[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 #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
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
1365 void
1366 ureg_emit_memory(struct ureg_program *ureg,
1367 unsigned extended_token,
1368 unsigned qualifier,
1369 enum tgsi_texture_type texture,
1370 enum pipe_format format)
1371 {
1372 union tgsi_any_token *out, *insn;
1373
1374 out = get_tokens( ureg, DOMAIN_INSN, 1 );
1375 insn = retrieve_token( ureg, DOMAIN_INSN, extended_token );
1376
1377 insn->insn.Memory = 1;
1378
1379 out[0].value = 0;
1380 out[0].insn_memory.Qualifier = qualifier;
1381 out[0].insn_memory.Texture = texture;
1382 out[0].insn_memory.Format = format;
1383 }
1384
1385 void
1386 ureg_fixup_insn_size(struct ureg_program *ureg,
1387 unsigned insn )
1388 {
1389 union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_INSN, insn );
1390
1391 assert(out->insn.Type == TGSI_TOKEN_TYPE_INSTRUCTION);
1392 out->insn.NrTokens = ureg->domain[DOMAIN_INSN].count - insn - 1;
1393 }
1394
1395
1396 void
1397 ureg_insn(struct ureg_program *ureg,
1398 enum tgsi_opcode opcode,
1399 const struct ureg_dst *dst,
1400 unsigned nr_dst,
1401 const struct ureg_src *src,
1402 unsigned nr_src,
1403 unsigned precise )
1404 {
1405 struct ureg_emit_insn_result insn;
1406 unsigned i;
1407 boolean saturate;
1408
1409 if (nr_dst && ureg_dst_is_empty(dst[0])) {
1410 return;
1411 }
1412
1413 saturate = nr_dst ? dst[0].Saturate : FALSE;
1414
1415 insn = ureg_emit_insn(ureg,
1416 opcode,
1417 saturate,
1418 precise,
1419 nr_dst,
1420 nr_src);
1421
1422 for (i = 0; i < nr_dst; i++)
1423 ureg_emit_dst( ureg, dst[i] );
1424
1425 for (i = 0; i < nr_src; i++)
1426 ureg_emit_src( ureg, src[i] );
1427
1428 ureg_fixup_insn_size( ureg, insn.insn_token );
1429 }
1430
1431 void
1432 ureg_tex_insn(struct ureg_program *ureg,
1433 enum tgsi_opcode opcode,
1434 const struct ureg_dst *dst,
1435 unsigned nr_dst,
1436 enum tgsi_texture_type target,
1437 enum tgsi_return_type return_type,
1438 const struct tgsi_texture_offset *texoffsets,
1439 unsigned nr_offset,
1440 const struct ureg_src *src,
1441 unsigned nr_src )
1442 {
1443 struct ureg_emit_insn_result insn;
1444 unsigned i;
1445 boolean saturate;
1446
1447 if (nr_dst && ureg_dst_is_empty(dst[0])) {
1448 return;
1449 }
1450
1451 saturate = nr_dst ? dst[0].Saturate : FALSE;
1452
1453 insn = ureg_emit_insn(ureg,
1454 opcode,
1455 saturate,
1456 0,
1457 nr_dst,
1458 nr_src);
1459
1460 ureg_emit_texture( ureg, insn.extended_token, target, return_type,
1461 nr_offset );
1462
1463 for (i = 0; i < nr_offset; i++)
1464 ureg_emit_texture_offset( ureg, &texoffsets[i]);
1465
1466 for (i = 0; i < nr_dst; i++)
1467 ureg_emit_dst( ureg, dst[i] );
1468
1469 for (i = 0; i < nr_src; i++)
1470 ureg_emit_src( ureg, src[i] );
1471
1472 ureg_fixup_insn_size( ureg, insn.insn_token );
1473 }
1474
1475
1476 void
1477 ureg_memory_insn(struct ureg_program *ureg,
1478 enum tgsi_opcode opcode,
1479 const struct ureg_dst *dst,
1480 unsigned nr_dst,
1481 const struct ureg_src *src,
1482 unsigned nr_src,
1483 unsigned qualifier,
1484 enum tgsi_texture_type texture,
1485 enum pipe_format format)
1486 {
1487 struct ureg_emit_insn_result insn;
1488 unsigned i;
1489
1490 insn = ureg_emit_insn(ureg,
1491 opcode,
1492 FALSE,
1493 0,
1494 nr_dst,
1495 nr_src);
1496
1497 ureg_emit_memory(ureg, insn.extended_token, qualifier, texture, format);
1498
1499 for (i = 0; i < nr_dst; i++)
1500 ureg_emit_dst(ureg, dst[i]);
1501
1502 for (i = 0; i < nr_src; i++)
1503 ureg_emit_src(ureg, src[i]);
1504
1505 ureg_fixup_insn_size(ureg, insn.insn_token);
1506 }
1507
1508
1509 static void
1510 emit_decl_semantic(struct ureg_program *ureg,
1511 unsigned file,
1512 unsigned first,
1513 unsigned last,
1514 enum tgsi_semantic semantic_name,
1515 unsigned semantic_index,
1516 unsigned streams,
1517 unsigned usage_mask,
1518 unsigned array_id,
1519 boolean invariant)
1520 {
1521 union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, array_id ? 4 : 3);
1522
1523 out[0].value = 0;
1524 out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
1525 out[0].decl.NrTokens = 3;
1526 out[0].decl.File = file;
1527 out[0].decl.UsageMask = usage_mask;
1528 out[0].decl.Semantic = 1;
1529 out[0].decl.Array = array_id != 0;
1530 out[0].decl.Invariant = invariant;
1531
1532 out[1].value = 0;
1533 out[1].decl_range.First = first;
1534 out[1].decl_range.Last = last;
1535
1536 out[2].value = 0;
1537 out[2].decl_semantic.Name = semantic_name;
1538 out[2].decl_semantic.Index = semantic_index;
1539 out[2].decl_semantic.StreamX = streams & 3;
1540 out[2].decl_semantic.StreamY = (streams >> 2) & 3;
1541 out[2].decl_semantic.StreamZ = (streams >> 4) & 3;
1542 out[2].decl_semantic.StreamW = (streams >> 6) & 3;
1543
1544 if (array_id) {
1545 out[3].value = 0;
1546 out[3].array.ArrayID = array_id;
1547 }
1548 }
1549
1550 static void
1551 emit_decl_atomic_2d(struct ureg_program *ureg,
1552 unsigned first,
1553 unsigned last,
1554 unsigned index2D,
1555 unsigned array_id)
1556 {
1557 union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, array_id ? 4 : 3);
1558
1559 out[0].value = 0;
1560 out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
1561 out[0].decl.NrTokens = 3;
1562 out[0].decl.File = TGSI_FILE_HW_ATOMIC;
1563 out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW;
1564 out[0].decl.Dimension = 1;
1565 out[0].decl.Array = array_id != 0;
1566
1567 out[1].value = 0;
1568 out[1].decl_range.First = first;
1569 out[1].decl_range.Last = last;
1570
1571 out[2].value = 0;
1572 out[2].decl_dim.Index2D = index2D;
1573
1574 if (array_id) {
1575 out[3].value = 0;
1576 out[3].array.ArrayID = array_id;
1577 }
1578 }
1579
1580 static void
1581 emit_decl_fs(struct ureg_program *ureg,
1582 unsigned file,
1583 unsigned first,
1584 unsigned last,
1585 enum tgsi_semantic semantic_name,
1586 unsigned semantic_index,
1587 enum tgsi_interpolate_mode interpolate,
1588 unsigned cylindrical_wrap,
1589 enum tgsi_interpolate_loc interpolate_location,
1590 unsigned array_id,
1591 unsigned usage_mask)
1592 {
1593 union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL,
1594 array_id ? 5 : 4);
1595
1596 out[0].value = 0;
1597 out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
1598 out[0].decl.NrTokens = 4;
1599 out[0].decl.File = file;
1600 out[0].decl.UsageMask = usage_mask;
1601 out[0].decl.Interpolate = 1;
1602 out[0].decl.Semantic = 1;
1603 out[0].decl.Array = array_id != 0;
1604
1605 out[1].value = 0;
1606 out[1].decl_range.First = first;
1607 out[1].decl_range.Last = last;
1608
1609 out[2].value = 0;
1610 out[2].decl_interp.Interpolate = interpolate;
1611 out[2].decl_interp.CylindricalWrap = cylindrical_wrap;
1612 out[2].decl_interp.Location = interpolate_location;
1613
1614 out[3].value = 0;
1615 out[3].decl_semantic.Name = semantic_name;
1616 out[3].decl_semantic.Index = semantic_index;
1617
1618 if (array_id) {
1619 out[4].value = 0;
1620 out[4].array.ArrayID = array_id;
1621 }
1622 }
1623
1624 static void
1625 emit_decl_temps( struct ureg_program *ureg,
1626 unsigned first, unsigned last,
1627 boolean local,
1628 unsigned arrayid )
1629 {
1630 union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL,
1631 arrayid ? 3 : 2 );
1632
1633 out[0].value = 0;
1634 out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
1635 out[0].decl.NrTokens = 2;
1636 out[0].decl.File = TGSI_FILE_TEMPORARY;
1637 out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW;
1638 out[0].decl.Local = local;
1639
1640 out[1].value = 0;
1641 out[1].decl_range.First = first;
1642 out[1].decl_range.Last = last;
1643
1644 if (arrayid) {
1645 out[0].decl.Array = 1;
1646 out[2].value = 0;
1647 out[2].array.ArrayID = arrayid;
1648 }
1649 }
1650
1651 static void emit_decl_range( struct ureg_program *ureg,
1652 unsigned file,
1653 unsigned first,
1654 unsigned count )
1655 {
1656 union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 2 );
1657
1658 out[0].value = 0;
1659 out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
1660 out[0].decl.NrTokens = 2;
1661 out[0].decl.File = file;
1662 out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW;
1663 out[0].decl.Semantic = 0;
1664
1665 out[1].value = 0;
1666 out[1].decl_range.First = first;
1667 out[1].decl_range.Last = first + count - 1;
1668 }
1669
1670 static void
1671 emit_decl_range2D(struct ureg_program *ureg,
1672 unsigned file,
1673 unsigned first,
1674 unsigned last,
1675 unsigned index2D)
1676 {
1677 union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 3);
1678
1679 out[0].value = 0;
1680 out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
1681 out[0].decl.NrTokens = 3;
1682 out[0].decl.File = file;
1683 out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW;
1684 out[0].decl.Dimension = 1;
1685
1686 out[1].value = 0;
1687 out[1].decl_range.First = first;
1688 out[1].decl_range.Last = last;
1689
1690 out[2].value = 0;
1691 out[2].decl_dim.Index2D = index2D;
1692 }
1693
1694 static void
1695 emit_decl_sampler_view(struct ureg_program *ureg,
1696 unsigned index,
1697 enum tgsi_texture_type target,
1698 enum tgsi_return_type return_type_x,
1699 enum tgsi_return_type return_type_y,
1700 enum tgsi_return_type return_type_z,
1701 enum tgsi_return_type return_type_w )
1702 {
1703 union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 3);
1704
1705 out[0].value = 0;
1706 out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
1707 out[0].decl.NrTokens = 3;
1708 out[0].decl.File = TGSI_FILE_SAMPLER_VIEW;
1709 out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW;
1710
1711 out[1].value = 0;
1712 out[1].decl_range.First = index;
1713 out[1].decl_range.Last = index;
1714
1715 out[2].value = 0;
1716 out[2].decl_sampler_view.Resource = target;
1717 out[2].decl_sampler_view.ReturnTypeX = return_type_x;
1718 out[2].decl_sampler_view.ReturnTypeY = return_type_y;
1719 out[2].decl_sampler_view.ReturnTypeZ = return_type_z;
1720 out[2].decl_sampler_view.ReturnTypeW = return_type_w;
1721 }
1722
1723 static void
1724 emit_decl_image(struct ureg_program *ureg,
1725 unsigned index,
1726 enum tgsi_texture_type target,
1727 enum pipe_format format,
1728 boolean wr,
1729 boolean raw)
1730 {
1731 union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 3);
1732
1733 out[0].value = 0;
1734 out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
1735 out[0].decl.NrTokens = 3;
1736 out[0].decl.File = TGSI_FILE_IMAGE;
1737 out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW;
1738
1739 out[1].value = 0;
1740 out[1].decl_range.First = index;
1741 out[1].decl_range.Last = index;
1742
1743 out[2].value = 0;
1744 out[2].decl_image.Resource = target;
1745 out[2].decl_image.Writable = wr;
1746 out[2].decl_image.Raw = raw;
1747 out[2].decl_image.Format = format;
1748 }
1749
1750 static void
1751 emit_decl_buffer(struct ureg_program *ureg,
1752 unsigned index,
1753 bool atomic)
1754 {
1755 union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 2);
1756
1757 out[0].value = 0;
1758 out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
1759 out[0].decl.NrTokens = 2;
1760 out[0].decl.File = TGSI_FILE_BUFFER;
1761 out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW;
1762 out[0].decl.Atomic = atomic;
1763
1764 out[1].value = 0;
1765 out[1].decl_range.First = index;
1766 out[1].decl_range.Last = index;
1767 }
1768
1769 static void
1770 emit_decl_memory(struct ureg_program *ureg, unsigned memory_type)
1771 {
1772 union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 2);
1773
1774 out[0].value = 0;
1775 out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
1776 out[0].decl.NrTokens = 2;
1777 out[0].decl.File = TGSI_FILE_MEMORY;
1778 out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW;
1779 out[0].decl.MemType = memory_type;
1780
1781 out[1].value = 0;
1782 out[1].decl_range.First = memory_type;
1783 out[1].decl_range.Last = memory_type;
1784 }
1785
1786 static void
1787 emit_immediate( struct ureg_program *ureg,
1788 const unsigned *v,
1789 unsigned type )
1790 {
1791 union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 5 );
1792
1793 out[0].value = 0;
1794 out[0].imm.Type = TGSI_TOKEN_TYPE_IMMEDIATE;
1795 out[0].imm.NrTokens = 5;
1796 out[0].imm.DataType = type;
1797 out[0].imm.Padding = 0;
1798
1799 out[1].imm_data.Uint = v[0];
1800 out[2].imm_data.Uint = v[1];
1801 out[3].imm_data.Uint = v[2];
1802 out[4].imm_data.Uint = v[3];
1803 }
1804
1805 static void
1806 emit_property(struct ureg_program *ureg,
1807 unsigned name,
1808 unsigned data)
1809 {
1810 union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 2);
1811
1812 out[0].value = 0;
1813 out[0].prop.Type = TGSI_TOKEN_TYPE_PROPERTY;
1814 out[0].prop.NrTokens = 2;
1815 out[0].prop.PropertyName = name;
1816
1817 out[1].prop_data.Data = data;
1818 }
1819
1820
1821 static void emit_decls( struct ureg_program *ureg )
1822 {
1823 unsigned i,j;
1824
1825 for (i = 0; i < ARRAY_SIZE(ureg->properties); i++)
1826 if (ureg->properties[i] != ~0u)
1827 emit_property(ureg, i, ureg->properties[i]);
1828
1829 if (ureg->processor == PIPE_SHADER_VERTEX) {
1830 for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
1831 if (ureg->vs_inputs[i/32] & (1u << (i%32))) {
1832 emit_decl_range( ureg, TGSI_FILE_INPUT, i, 1 );
1833 }
1834 }
1835 } else if (ureg->processor == PIPE_SHADER_FRAGMENT) {
1836 if (ureg->supports_any_inout_decl_range) {
1837 for (i = 0; i < ureg->nr_inputs; i++) {
1838 emit_decl_fs(ureg,
1839 TGSI_FILE_INPUT,
1840 ureg->input[i].first,
1841 ureg->input[i].last,
1842 ureg->input[i].semantic_name,
1843 ureg->input[i].semantic_index,
1844 ureg->input[i].interp,
1845 ureg->input[i].cylindrical_wrap,
1846 ureg->input[i].interp_location,
1847 ureg->input[i].array_id,
1848 ureg->input[i].usage_mask);
1849 }
1850 }
1851 else {
1852 for (i = 0; i < ureg->nr_inputs; i++) {
1853 for (j = ureg->input[i].first; j <= ureg->input[i].last; j++) {
1854 emit_decl_fs(ureg,
1855 TGSI_FILE_INPUT,
1856 j, j,
1857 ureg->input[i].semantic_name,
1858 ureg->input[i].semantic_index +
1859 (j - ureg->input[i].first),
1860 ureg->input[i].interp,
1861 ureg->input[i].cylindrical_wrap,
1862 ureg->input[i].interp_location, 0,
1863 ureg->input[i].usage_mask);
1864 }
1865 }
1866 }
1867 } else {
1868 if (ureg->supports_any_inout_decl_range) {
1869 for (i = 0; i < ureg->nr_inputs; i++) {
1870 emit_decl_semantic(ureg,
1871 TGSI_FILE_INPUT,
1872 ureg->input[i].first,
1873 ureg->input[i].last,
1874 ureg->input[i].semantic_name,
1875 ureg->input[i].semantic_index,
1876 0,
1877 TGSI_WRITEMASK_XYZW,
1878 ureg->input[i].array_id,
1879 FALSE);
1880 }
1881 }
1882 else {
1883 for (i = 0; i < ureg->nr_inputs; i++) {
1884 for (j = ureg->input[i].first; j <= ureg->input[i].last; j++) {
1885 emit_decl_semantic(ureg,
1886 TGSI_FILE_INPUT,
1887 j, j,
1888 ureg->input[i].semantic_name,
1889 ureg->input[i].semantic_index +
1890 (j - ureg->input[i].first),
1891 0,
1892 TGSI_WRITEMASK_XYZW, 0, FALSE);
1893 }
1894 }
1895 }
1896 }
1897
1898 for (i = 0; i < ureg->nr_system_values; i++) {
1899 emit_decl_semantic(ureg,
1900 TGSI_FILE_SYSTEM_VALUE,
1901 i,
1902 i,
1903 ureg->system_value[i].semantic_name,
1904 ureg->system_value[i].semantic_index,
1905 0,
1906 TGSI_WRITEMASK_XYZW, 0, FALSE);
1907 }
1908
1909 if (ureg->supports_any_inout_decl_range) {
1910 for (i = 0; i < ureg->nr_outputs; i++) {
1911 emit_decl_semantic(ureg,
1912 TGSI_FILE_OUTPUT,
1913 ureg->output[i].first,
1914 ureg->output[i].last,
1915 ureg->output[i].semantic_name,
1916 ureg->output[i].semantic_index,
1917 ureg->output[i].streams,
1918 ureg->output[i].usage_mask,
1919 ureg->output[i].array_id,
1920 ureg->output[i].invariant);
1921 }
1922 }
1923 else {
1924 for (i = 0; i < ureg->nr_outputs; i++) {
1925 for (j = ureg->output[i].first; j <= ureg->output[i].last; j++) {
1926 emit_decl_semantic(ureg,
1927 TGSI_FILE_OUTPUT,
1928 j, j,
1929 ureg->output[i].semantic_name,
1930 ureg->output[i].semantic_index +
1931 (j - ureg->output[i].first),
1932 ureg->output[i].streams,
1933 ureg->output[i].usage_mask,
1934 0,
1935 ureg->output[i].invariant);
1936 }
1937 }
1938 }
1939
1940 for (i = 0; i < ureg->nr_samplers; i++) {
1941 emit_decl_range( ureg,
1942 TGSI_FILE_SAMPLER,
1943 ureg->sampler[i].Index, 1 );
1944 }
1945
1946 for (i = 0; i < ureg->nr_sampler_views; i++) {
1947 emit_decl_sampler_view(ureg,
1948 ureg->sampler_view[i].index,
1949 ureg->sampler_view[i].target,
1950 ureg->sampler_view[i].return_type_x,
1951 ureg->sampler_view[i].return_type_y,
1952 ureg->sampler_view[i].return_type_z,
1953 ureg->sampler_view[i].return_type_w);
1954 }
1955
1956 for (i = 0; i < ureg->nr_images; i++) {
1957 emit_decl_image(ureg,
1958 ureg->image[i].index,
1959 ureg->image[i].target,
1960 ureg->image[i].format,
1961 ureg->image[i].wr,
1962 ureg->image[i].raw);
1963 }
1964
1965 for (i = 0; i < ureg->nr_buffers; i++) {
1966 emit_decl_buffer(ureg, ureg->buffer[i].index, ureg->buffer[i].atomic);
1967 }
1968
1969 for (i = 0; i < TGSI_MEMORY_TYPE_COUNT; i++) {
1970 if (ureg->use_memory[i])
1971 emit_decl_memory(ureg, i);
1972 }
1973
1974 for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
1975 struct const_decl *decl = &ureg->const_decls[i];
1976
1977 if (decl->nr_constant_ranges) {
1978 uint j;
1979
1980 for (j = 0; j < decl->nr_constant_ranges; j++) {
1981 emit_decl_range2D(ureg,
1982 TGSI_FILE_CONSTANT,
1983 decl->constant_range[j].first,
1984 decl->constant_range[j].last,
1985 i);
1986 }
1987 }
1988 }
1989
1990 for (i = 0; i < PIPE_MAX_HW_ATOMIC_BUFFERS; i++) {
1991 struct hw_atomic_decl *decl = &ureg->hw_atomic_decls[i];
1992
1993 if (decl->nr_hw_atomic_ranges) {
1994 uint j;
1995
1996 for (j = 0; j < decl->nr_hw_atomic_ranges; j++) {
1997 emit_decl_atomic_2d(ureg,
1998 decl->hw_atomic_range[j].first,
1999 decl->hw_atomic_range[j].last,
2000 i,
2001 decl->hw_atomic_range[j].array_id);
2002 }
2003 }
2004 }
2005
2006 if (ureg->nr_temps) {
2007 unsigned array = 0;
2008 for (i = 0; i < ureg->nr_temps;) {
2009 boolean local = util_bitmask_get(ureg->local_temps, i);
2010 unsigned first = i;
2011 i = util_bitmask_get_next_index(ureg->decl_temps, i + 1);
2012 if (i == UTIL_BITMASK_INVALID_INDEX)
2013 i = ureg->nr_temps;
2014
2015 if (array < ureg->nr_array_temps && ureg->array_temps[array] == first)
2016 emit_decl_temps( ureg, first, i - 1, local, ++array );
2017 else
2018 emit_decl_temps( ureg, first, i - 1, local, 0 );
2019 }
2020 }
2021
2022 if (ureg->nr_addrs) {
2023 emit_decl_range( ureg,
2024 TGSI_FILE_ADDRESS,
2025 0, ureg->nr_addrs );
2026 }
2027
2028 for (i = 0; i < ureg->nr_immediates; i++) {
2029 emit_immediate( ureg,
2030 ureg->immediate[i].value.u,
2031 ureg->immediate[i].type );
2032 }
2033 }
2034
2035 /* Append the instruction tokens onto the declarations to build a
2036 * contiguous stream suitable to send to the driver.
2037 */
2038 static void copy_instructions( struct ureg_program *ureg )
2039 {
2040 unsigned nr_tokens = ureg->domain[DOMAIN_INSN].count;
2041 union tgsi_any_token *out = get_tokens( ureg,
2042 DOMAIN_DECL,
2043 nr_tokens );
2044
2045 memcpy(out,
2046 ureg->domain[DOMAIN_INSN].tokens,
2047 nr_tokens * sizeof out[0] );
2048 }
2049
2050
2051 static void
2052 fixup_header_size(struct ureg_program *ureg)
2053 {
2054 union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_DECL, 0 );
2055
2056 out->header.BodySize = ureg->domain[DOMAIN_DECL].count - 2;
2057 }
2058
2059
2060 static void
2061 emit_header( struct ureg_program *ureg )
2062 {
2063 union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 2 );
2064
2065 out[0].header.HeaderSize = 2;
2066 out[0].header.BodySize = 0;
2067
2068 out[1].processor.Processor = ureg->processor;
2069 out[1].processor.Padding = 0;
2070 }
2071
2072
2073 const struct tgsi_token *ureg_finalize( struct ureg_program *ureg )
2074 {
2075 const struct tgsi_token *tokens;
2076
2077 switch (ureg->processor) {
2078 case PIPE_SHADER_VERTEX:
2079 case PIPE_SHADER_TESS_EVAL:
2080 ureg_property(ureg, TGSI_PROPERTY_NEXT_SHADER,
2081 ureg->next_shader_processor == -1 ?
2082 PIPE_SHADER_FRAGMENT :
2083 ureg->next_shader_processor);
2084 break;
2085 default:
2086 ; /* nothing */
2087 }
2088
2089 emit_header( ureg );
2090 emit_decls( ureg );
2091 copy_instructions( ureg );
2092 fixup_header_size( ureg );
2093
2094 if (ureg->domain[0].tokens == error_tokens ||
2095 ureg->domain[1].tokens == error_tokens) {
2096 debug_printf("%s: error in generated shader\n", __FUNCTION__);
2097 assert(0);
2098 return NULL;
2099 }
2100
2101 tokens = &ureg->domain[DOMAIN_DECL].tokens[0].token;
2102
2103 if (0) {
2104 debug_printf("%s: emitted shader %d tokens:\n", __FUNCTION__,
2105 ureg->domain[DOMAIN_DECL].count);
2106 tgsi_dump( tokens, 0 );
2107 }
2108
2109 #if DEBUG
2110 if (tokens && !tgsi_sanity_check(tokens)) {
2111 debug_printf("tgsi_ureg.c, sanity check failed on generated tokens:\n");
2112 tgsi_dump(tokens, 0);
2113 assert(0);
2114 }
2115 #endif
2116
2117
2118 return tokens;
2119 }
2120
2121
2122 void *ureg_create_shader( struct ureg_program *ureg,
2123 struct pipe_context *pipe,
2124 const struct pipe_stream_output_info *so )
2125 {
2126 struct pipe_shader_state state;
2127
2128 pipe_shader_state_from_tgsi(&state, ureg_finalize(ureg));
2129 if(!state.tokens)
2130 return NULL;
2131
2132 if (so)
2133 state.stream_output = *so;
2134
2135 switch (ureg->processor) {
2136 case PIPE_SHADER_VERTEX:
2137 return pipe->create_vs_state(pipe, &state);
2138 case PIPE_SHADER_TESS_CTRL:
2139 return pipe->create_tcs_state(pipe, &state);
2140 case PIPE_SHADER_TESS_EVAL:
2141 return pipe->create_tes_state(pipe, &state);
2142 case PIPE_SHADER_GEOMETRY:
2143 return pipe->create_gs_state(pipe, &state);
2144 case PIPE_SHADER_FRAGMENT:
2145 return pipe->create_fs_state(pipe, &state);
2146 default:
2147 return NULL;
2148 }
2149 }
2150
2151
2152 const struct tgsi_token *ureg_get_tokens( struct ureg_program *ureg,
2153 unsigned *nr_tokens )
2154 {
2155 const struct tgsi_token *tokens;
2156
2157 ureg_finalize(ureg);
2158
2159 tokens = &ureg->domain[DOMAIN_DECL].tokens[0].token;
2160
2161 if (nr_tokens)
2162 *nr_tokens = ureg->domain[DOMAIN_DECL].count;
2163
2164 ureg->domain[DOMAIN_DECL].tokens = 0;
2165 ureg->domain[DOMAIN_DECL].size = 0;
2166 ureg->domain[DOMAIN_DECL].order = 0;
2167 ureg->domain[DOMAIN_DECL].count = 0;
2168
2169 return tokens;
2170 }
2171
2172
2173 void ureg_free_tokens( const struct tgsi_token *tokens )
2174 {
2175 FREE((struct tgsi_token *)tokens);
2176 }
2177
2178
2179 struct ureg_program *
2180 ureg_create(enum pipe_shader_type processor)
2181 {
2182 return ureg_create_with_screen(processor, NULL);
2183 }
2184
2185
2186 struct ureg_program *
2187 ureg_create_with_screen(enum pipe_shader_type processor,
2188 struct pipe_screen *screen)
2189 {
2190 uint i;
2191 struct ureg_program *ureg = CALLOC_STRUCT( ureg_program );
2192 if (!ureg)
2193 goto no_ureg;
2194
2195 ureg->processor = processor;
2196 ureg->supports_any_inout_decl_range =
2197 screen &&
2198 screen->get_shader_param(screen, processor,
2199 PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE) != 0;
2200 ureg->next_shader_processor = -1;
2201
2202 for (i = 0; i < ARRAY_SIZE(ureg->properties); i++)
2203 ureg->properties[i] = ~0;
2204
2205 ureg->free_temps = util_bitmask_create();
2206 if (ureg->free_temps == NULL)
2207 goto no_free_temps;
2208
2209 ureg->local_temps = util_bitmask_create();
2210 if (ureg->local_temps == NULL)
2211 goto no_local_temps;
2212
2213 ureg->decl_temps = util_bitmask_create();
2214 if (ureg->decl_temps == NULL)
2215 goto no_decl_temps;
2216
2217 return ureg;
2218
2219 no_decl_temps:
2220 util_bitmask_destroy(ureg->local_temps);
2221 no_local_temps:
2222 util_bitmask_destroy(ureg->free_temps);
2223 no_free_temps:
2224 FREE(ureg);
2225 no_ureg:
2226 return NULL;
2227 }
2228
2229
2230 void
2231 ureg_set_next_shader_processor(struct ureg_program *ureg, unsigned processor)
2232 {
2233 ureg->next_shader_processor = processor;
2234 }
2235
2236
2237 unsigned
2238 ureg_get_nr_outputs( const struct ureg_program *ureg )
2239 {
2240 if (!ureg)
2241 return 0;
2242 return ureg->nr_outputs;
2243 }
2244
2245
2246 void ureg_destroy( struct ureg_program *ureg )
2247 {
2248 unsigned i;
2249
2250 for (i = 0; i < ARRAY_SIZE(ureg->domain); i++) {
2251 if (ureg->domain[i].tokens &&
2252 ureg->domain[i].tokens != error_tokens)
2253 FREE(ureg->domain[i].tokens);
2254 }
2255
2256 util_bitmask_destroy(ureg->free_temps);
2257 util_bitmask_destroy(ureg->local_temps);
2258 util_bitmask_destroy(ureg->decl_temps);
2259
2260 FREE(ureg);
2261 }