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