1848b8605Smrg/**************************************************************************
2b8e80941Smrg *
3848b8605Smrg * Copyright 2009-2010 VMware, Inc.
4848b8605Smrg * All Rights Reserved.
5b8e80941Smrg *
6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a
7848b8605Smrg * copy of this software and associated documentation files (the
8848b8605Smrg * "Software"), to deal in the Software without restriction, including
9848b8605Smrg * without limitation the rights to use, copy, modify, merge, publish,
10848b8605Smrg * distribute, sub license, and/or sell copies of the Software, and to
11848b8605Smrg * permit persons to whom the Software is furnished to do so, subject to
12848b8605Smrg * the following conditions:
13b8e80941Smrg *
14848b8605Smrg * The above copyright notice and this permission notice (including the
15848b8605Smrg * next paragraph) shall be included in all copies or substantial portions
16848b8605Smrg * of the Software.
17b8e80941Smrg *
18848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20848b8605Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21848b8605Smrg * IN NO EVENT SHALL VMWARE, INC AND/OR ITS SUPPLIERS BE LIABLE FOR
22848b8605Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23848b8605Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24848b8605Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25b8e80941Smrg *
26848b8605Smrg **************************************************************************/
27848b8605Smrg
28848b8605Smrg
29b8e80941Smrg#include "pipe/p_screen.h"
30848b8605Smrg#include "pipe/p_context.h"
31848b8605Smrg#include "pipe/p_state.h"
32848b8605Smrg#include "tgsi/tgsi_ureg.h"
33848b8605Smrg#include "tgsi/tgsi_build.h"
34848b8605Smrg#include "tgsi/tgsi_info.h"
35848b8605Smrg#include "tgsi/tgsi_dump.h"
36848b8605Smrg#include "tgsi/tgsi_sanity.h"
37848b8605Smrg#include "util/u_debug.h"
38b8e80941Smrg#include "util/u_inlines.h"
39848b8605Smrg#include "util/u_memory.h"
40848b8605Smrg#include "util/u_math.h"
41848b8605Smrg#include "util/u_bitmask.h"
42848b8605Smrg
43848b8605Smrgunion tgsi_any_token {
44848b8605Smrg   struct tgsi_header header;
45848b8605Smrg   struct tgsi_processor processor;
46848b8605Smrg   struct tgsi_token token;
47848b8605Smrg   struct tgsi_property prop;
48848b8605Smrg   struct tgsi_property_data prop_data;
49848b8605Smrg   struct tgsi_declaration decl;
50848b8605Smrg   struct tgsi_declaration_range decl_range;
51848b8605Smrg   struct tgsi_declaration_dimension decl_dim;
52848b8605Smrg   struct tgsi_declaration_interp decl_interp;
53b8e80941Smrg   struct tgsi_declaration_image decl_image;
54848b8605Smrg   struct tgsi_declaration_semantic decl_semantic;
55848b8605Smrg   struct tgsi_declaration_sampler_view decl_sampler_view;
56848b8605Smrg   struct tgsi_declaration_array array;
57848b8605Smrg   struct tgsi_immediate imm;
58848b8605Smrg   union  tgsi_immediate_data imm_data;
59848b8605Smrg   struct tgsi_instruction insn;
60848b8605Smrg   struct tgsi_instruction_label insn_label;
61848b8605Smrg   struct tgsi_instruction_texture insn_texture;
62b8e80941Smrg   struct tgsi_instruction_memory insn_memory;
63848b8605Smrg   struct tgsi_texture_offset insn_texture_offset;
64848b8605Smrg   struct tgsi_src_register src;
65848b8605Smrg   struct tgsi_ind_register ind;
66848b8605Smrg   struct tgsi_dimension dim;
67848b8605Smrg   struct tgsi_dst_register dst;
68848b8605Smrg   unsigned value;
69848b8605Smrg};
70848b8605Smrg
71848b8605Smrg
72848b8605Smrgstruct ureg_tokens {
73848b8605Smrg   union tgsi_any_token *tokens;
74848b8605Smrg   unsigned size;
75848b8605Smrg   unsigned order;
76848b8605Smrg   unsigned count;
77848b8605Smrg};
78848b8605Smrg
79b8e80941Smrg#define UREG_MAX_INPUT (4 * PIPE_MAX_SHADER_INPUTS)
80848b8605Smrg#define UREG_MAX_SYSTEM_VALUE PIPE_MAX_ATTRIBS
81b8e80941Smrg#define UREG_MAX_OUTPUT (4 * PIPE_MAX_SHADER_OUTPUTS)
82848b8605Smrg#define UREG_MAX_CONSTANT_RANGE 32
83b8e80941Smrg#define UREG_MAX_HW_ATOMIC_RANGE 32
84848b8605Smrg#define UREG_MAX_IMMEDIATE 4096
85848b8605Smrg#define UREG_MAX_ADDR 3
86848b8605Smrg#define UREG_MAX_ARRAY_TEMPS 256
87848b8605Smrg
88848b8605Smrgstruct const_decl {
89848b8605Smrg   struct {
90848b8605Smrg      unsigned first;
91848b8605Smrg      unsigned last;
92848b8605Smrg   } constant_range[UREG_MAX_CONSTANT_RANGE];
93848b8605Smrg   unsigned nr_constant_ranges;
94848b8605Smrg};
95848b8605Smrg
96b8e80941Smrgstruct hw_atomic_decl {
97b8e80941Smrg   struct {
98b8e80941Smrg      unsigned first;
99b8e80941Smrg      unsigned last;
100b8e80941Smrg      unsigned array_id;
101b8e80941Smrg   } hw_atomic_range[UREG_MAX_HW_ATOMIC_RANGE];
102b8e80941Smrg   unsigned nr_hw_atomic_ranges;
103b8e80941Smrg};
104b8e80941Smrg
105848b8605Smrg#define DOMAIN_DECL 0
106848b8605Smrg#define DOMAIN_INSN 1
107848b8605Smrg
108848b8605Smrgstruct ureg_program
109848b8605Smrg{
110b8e80941Smrg   enum pipe_shader_type processor;
111b8e80941Smrg   bool supports_any_inout_decl_range;
112b8e80941Smrg   int next_shader_processor;
113848b8605Smrg
114848b8605Smrg   struct {
115b8e80941Smrg      enum tgsi_semantic semantic_name;
116848b8605Smrg      unsigned semantic_index;
117b8e80941Smrg      enum tgsi_interpolate_mode interp;
118848b8605Smrg      unsigned char cylindrical_wrap;
119b8e80941Smrg      unsigned char usage_mask;
120b8e80941Smrg      enum tgsi_interpolate_loc interp_location;
121b8e80941Smrg      unsigned first;
122b8e80941Smrg      unsigned last;
123b8e80941Smrg      unsigned array_id;
124b8e80941Smrg   } input[UREG_MAX_INPUT];
125b8e80941Smrg   unsigned nr_inputs, nr_input_regs;
126848b8605Smrg
127b8e80941Smrg   unsigned vs_inputs[PIPE_MAX_ATTRIBS/32];
128848b8605Smrg
129848b8605Smrg   struct {
130b8e80941Smrg      enum tgsi_semantic semantic_name;
131848b8605Smrg      unsigned semantic_index;
132848b8605Smrg   } system_value[UREG_MAX_SYSTEM_VALUE];
133848b8605Smrg   unsigned nr_system_values;
134848b8605Smrg
135848b8605Smrg   struct {
136b8e80941Smrg      enum tgsi_semantic semantic_name;
137848b8605Smrg      unsigned semantic_index;
138b8e80941Smrg      unsigned streams;
139848b8605Smrg      unsigned usage_mask; /* = TGSI_WRITEMASK_* */
140b8e80941Smrg      unsigned first;
141b8e80941Smrg      unsigned last;
142b8e80941Smrg      unsigned array_id;
143b8e80941Smrg      boolean invariant;
144848b8605Smrg   } output[UREG_MAX_OUTPUT];
145b8e80941Smrg   unsigned nr_outputs, nr_output_regs;
146848b8605Smrg
147848b8605Smrg   struct {
148848b8605Smrg      union {
149848b8605Smrg         float f[4];
150848b8605Smrg         unsigned u[4];
151848b8605Smrg         int i[4];
152848b8605Smrg      } value;
153848b8605Smrg      unsigned nr;
154848b8605Smrg      unsigned type;
155848b8605Smrg   } immediate[UREG_MAX_IMMEDIATE];
156848b8605Smrg   unsigned nr_immediates;
157848b8605Smrg
158848b8605Smrg   struct ureg_src sampler[PIPE_MAX_SAMPLERS];
159848b8605Smrg   unsigned nr_samplers;
160848b8605Smrg
161848b8605Smrg   struct {
162848b8605Smrg      unsigned index;
163b8e80941Smrg      enum tgsi_texture_type target;
164b8e80941Smrg      enum tgsi_return_type return_type_x;
165b8e80941Smrg      enum tgsi_return_type return_type_y;
166b8e80941Smrg      enum tgsi_return_type return_type_z;
167b8e80941Smrg      enum tgsi_return_type return_type_w;
168848b8605Smrg   } sampler_view[PIPE_MAX_SHADER_SAMPLER_VIEWS];
169848b8605Smrg   unsigned nr_sampler_views;
170848b8605Smrg
171b8e80941Smrg   struct {
172b8e80941Smrg      unsigned index;
173b8e80941Smrg      enum tgsi_texture_type target;
174b8e80941Smrg      enum pipe_format format;
175b8e80941Smrg      boolean wr;
176b8e80941Smrg      boolean raw;
177b8e80941Smrg   } image[PIPE_MAX_SHADER_IMAGES];
178b8e80941Smrg   unsigned nr_images;
179b8e80941Smrg
180b8e80941Smrg   struct {
181b8e80941Smrg      unsigned index;
182b8e80941Smrg      bool atomic;
183b8e80941Smrg   } buffer[PIPE_MAX_SHADER_BUFFERS];
184b8e80941Smrg   unsigned nr_buffers;
185b8e80941Smrg
186848b8605Smrg   struct util_bitmask *free_temps;
187848b8605Smrg   struct util_bitmask *local_temps;
188848b8605Smrg   struct util_bitmask *decl_temps;
189848b8605Smrg   unsigned nr_temps;
190848b8605Smrg
191848b8605Smrg   unsigned array_temps[UREG_MAX_ARRAY_TEMPS];
192848b8605Smrg   unsigned nr_array_temps;
193848b8605Smrg
194b8e80941Smrg   struct const_decl const_decls[PIPE_MAX_CONSTANT_BUFFERS];
195b8e80941Smrg
196b8e80941Smrg   struct hw_atomic_decl hw_atomic_decls[PIPE_MAX_HW_ATOMIC_BUFFERS];
197848b8605Smrg
198b8e80941Smrg   unsigned properties[TGSI_PROPERTY_COUNT];
199848b8605Smrg
200848b8605Smrg   unsigned nr_addrs;
201848b8605Smrg   unsigned nr_instructions;
202848b8605Smrg
203848b8605Smrg   struct ureg_tokens domain[2];
204b8e80941Smrg
205b8e80941Smrg   bool use_memory[TGSI_MEMORY_TYPE_COUNT];
206848b8605Smrg};
207848b8605Smrg
208848b8605Smrgstatic union tgsi_any_token error_tokens[32];
209848b8605Smrg
210848b8605Smrgstatic void tokens_error( struct ureg_tokens *tokens )
211848b8605Smrg{
212848b8605Smrg   if (tokens->tokens && tokens->tokens != error_tokens)
213848b8605Smrg      FREE(tokens->tokens);
214848b8605Smrg
215848b8605Smrg   tokens->tokens = error_tokens;
216b8e80941Smrg   tokens->size = ARRAY_SIZE(error_tokens);
217848b8605Smrg   tokens->count = 0;
218848b8605Smrg}
219848b8605Smrg
220848b8605Smrg
221848b8605Smrgstatic void tokens_expand( struct ureg_tokens *tokens,
222848b8605Smrg                           unsigned count )
223848b8605Smrg{
224848b8605Smrg   unsigned old_size = tokens->size * sizeof(unsigned);
225848b8605Smrg
226848b8605Smrg   if (tokens->tokens == error_tokens) {
227848b8605Smrg      return;
228848b8605Smrg   }
229848b8605Smrg
230848b8605Smrg   while (tokens->count + count > tokens->size) {
231848b8605Smrg      tokens->size = (1 << ++tokens->order);
232848b8605Smrg   }
233848b8605Smrg
234848b8605Smrg   tokens->tokens = REALLOC(tokens->tokens,
235848b8605Smrg                            old_size,
236848b8605Smrg                            tokens->size * sizeof(unsigned));
237848b8605Smrg   if (tokens->tokens == NULL) {
238848b8605Smrg      tokens_error(tokens);
239848b8605Smrg   }
240848b8605Smrg}
241848b8605Smrg
242848b8605Smrgstatic void set_bad( struct ureg_program *ureg )
243848b8605Smrg{
244848b8605Smrg   tokens_error(&ureg->domain[0]);
245848b8605Smrg}
246848b8605Smrg
247848b8605Smrg
248848b8605Smrg
249848b8605Smrgstatic union tgsi_any_token *get_tokens( struct ureg_program *ureg,
250848b8605Smrg                                         unsigned domain,
251848b8605Smrg                                         unsigned count )
252848b8605Smrg{
253848b8605Smrg   struct ureg_tokens *tokens = &ureg->domain[domain];
254848b8605Smrg   union tgsi_any_token *result;
255848b8605Smrg
256848b8605Smrg   if (tokens->count + count > tokens->size)
257848b8605Smrg      tokens_expand(tokens, count);
258848b8605Smrg
259848b8605Smrg   result = &tokens->tokens[tokens->count];
260848b8605Smrg   tokens->count += count;
261848b8605Smrg   return result;
262848b8605Smrg}
263848b8605Smrg
264848b8605Smrg
265848b8605Smrgstatic union tgsi_any_token *retrieve_token( struct ureg_program *ureg,
266848b8605Smrg                                            unsigned domain,
267848b8605Smrg                                            unsigned nr )
268848b8605Smrg{
269848b8605Smrg   if (ureg->domain[domain].tokens == error_tokens)
270848b8605Smrg      return &error_tokens[0];
271848b8605Smrg
272848b8605Smrg   return &ureg->domain[domain].tokens[nr];
273848b8605Smrg}
274848b8605Smrg
275848b8605Smrg
276848b8605Smrgvoid
277b8e80941Smrgureg_property(struct ureg_program *ureg, unsigned name, unsigned value)
278848b8605Smrg{
279b8e80941Smrg   assert(name < ARRAY_SIZE(ureg->properties));
280b8e80941Smrg   ureg->properties[name] = value;
281848b8605Smrg}
282848b8605Smrg
283848b8605Smrgstruct ureg_src
284b8e80941Smrgureg_DECL_fs_input_cyl_centroid_layout(struct ureg_program *ureg,
285b8e80941Smrg                       enum tgsi_semantic semantic_name,
286848b8605Smrg                       unsigned semantic_index,
287b8e80941Smrg                       enum tgsi_interpolate_mode interp_mode,
288848b8605Smrg                       unsigned cylindrical_wrap,
289b8e80941Smrg                       enum tgsi_interpolate_loc interp_location,
290b8e80941Smrg                       unsigned index,
291b8e80941Smrg                       unsigned usage_mask,
292b8e80941Smrg                       unsigned array_id,
293b8e80941Smrg                       unsigned array_size)
294848b8605Smrg{
295848b8605Smrg   unsigned i;
296848b8605Smrg
297b8e80941Smrg   assert(usage_mask != 0);
298b8e80941Smrg   assert(usage_mask <= TGSI_WRITEMASK_XYZW);
299b8e80941Smrg
300b8e80941Smrg   for (i = 0; i < ureg->nr_inputs; i++) {
301b8e80941Smrg      if (ureg->input[i].semantic_name == semantic_name &&
302b8e80941Smrg          ureg->input[i].semantic_index == semantic_index) {
303b8e80941Smrg         assert(ureg->input[i].interp == interp_mode);
304b8e80941Smrg         assert(ureg->input[i].cylindrical_wrap == cylindrical_wrap);
305b8e80941Smrg         assert(ureg->input[i].interp_location == interp_location);
306b8e80941Smrg         if (ureg->input[i].array_id == array_id) {
307b8e80941Smrg            ureg->input[i].usage_mask |= usage_mask;
308b8e80941Smrg            goto out;
309b8e80941Smrg         }
310b8e80941Smrg         assert((ureg->input[i].usage_mask & usage_mask) == 0);
311848b8605Smrg      }
312848b8605Smrg   }
313848b8605Smrg
314b8e80941Smrg   if (ureg->nr_inputs < UREG_MAX_INPUT) {
315b8e80941Smrg      assert(array_size >= 1);
316b8e80941Smrg      ureg->input[i].semantic_name = semantic_name;
317b8e80941Smrg      ureg->input[i].semantic_index = semantic_index;
318b8e80941Smrg      ureg->input[i].interp = interp_mode;
319b8e80941Smrg      ureg->input[i].cylindrical_wrap = cylindrical_wrap;
320b8e80941Smrg      ureg->input[i].interp_location = interp_location;
321b8e80941Smrg      ureg->input[i].first = index;
322b8e80941Smrg      ureg->input[i].last = index + array_size - 1;
323b8e80941Smrg      ureg->input[i].array_id = array_id;
324b8e80941Smrg      ureg->input[i].usage_mask = usage_mask;
325b8e80941Smrg      ureg->nr_input_regs = MAX2(ureg->nr_input_regs, index + array_size);
326b8e80941Smrg      ureg->nr_inputs++;
327848b8605Smrg   } else {
328848b8605Smrg      set_bad(ureg);
329848b8605Smrg   }
330848b8605Smrg
331848b8605Smrgout:
332b8e80941Smrg   return ureg_src_array_register(TGSI_FILE_INPUT, ureg->input[i].first,
333b8e80941Smrg                                  array_id);
334b8e80941Smrg}
335b8e80941Smrg
336b8e80941Smrgstruct ureg_src
337b8e80941Smrgureg_DECL_fs_input_cyl_centroid(struct ureg_program *ureg,
338b8e80941Smrg                       enum tgsi_semantic semantic_name,
339b8e80941Smrg                       unsigned semantic_index,
340b8e80941Smrg                       enum tgsi_interpolate_mode interp_mode,
341b8e80941Smrg                       unsigned cylindrical_wrap,
342b8e80941Smrg                       enum tgsi_interpolate_loc interp_location,
343b8e80941Smrg                       unsigned array_id,
344b8e80941Smrg                       unsigned array_size)
345b8e80941Smrg{
346b8e80941Smrg   return ureg_DECL_fs_input_cyl_centroid_layout(ureg,
347b8e80941Smrg         semantic_name, semantic_index, interp_mode,
348b8e80941Smrg         cylindrical_wrap, interp_location,
349b8e80941Smrg         ureg->nr_input_regs, TGSI_WRITEMASK_XYZW, array_id, array_size);
350848b8605Smrg}
351848b8605Smrg
352848b8605Smrg
353b8e80941Smrgstruct ureg_src
354848b8605Smrgureg_DECL_vs_input( struct ureg_program *ureg,
355848b8605Smrg                    unsigned index )
356848b8605Smrg{
357b8e80941Smrg   assert(ureg->processor == PIPE_SHADER_VERTEX);
358b8e80941Smrg   assert(index / 32 < ARRAY_SIZE(ureg->vs_inputs));
359b8e80941Smrg
360848b8605Smrg   ureg->vs_inputs[index/32] |= 1 << (index % 32);
361848b8605Smrg   return ureg_src_register( TGSI_FILE_INPUT, index );
362848b8605Smrg}
363848b8605Smrg
364848b8605Smrg
365848b8605Smrgstruct ureg_src
366b8e80941Smrgureg_DECL_input_layout(struct ureg_program *ureg,
367b8e80941Smrg                enum tgsi_semantic semantic_name,
368b8e80941Smrg                unsigned semantic_index,
369b8e80941Smrg                unsigned index,
370b8e80941Smrg                unsigned usage_mask,
371b8e80941Smrg                unsigned array_id,
372b8e80941Smrg                unsigned array_size)
373b8e80941Smrg{
374b8e80941Smrg   return ureg_DECL_fs_input_cyl_centroid_layout(ureg,
375b8e80941Smrg               semantic_name, semantic_index,
376b8e80941Smrg               TGSI_INTERPOLATE_CONSTANT, 0, TGSI_INTERPOLATE_LOC_CENTER,
377b8e80941Smrg               index, usage_mask, array_id, array_size);
378b8e80941Smrg}
379848b8605Smrg
380b8e80941Smrg
381b8e80941Smrgstruct ureg_src
382b8e80941Smrgureg_DECL_input(struct ureg_program *ureg,
383b8e80941Smrg                enum tgsi_semantic semantic_name,
384b8e80941Smrg                unsigned semantic_index,
385b8e80941Smrg                unsigned array_id,
386b8e80941Smrg                unsigned array_size)
387b8e80941Smrg{
388b8e80941Smrg   return ureg_DECL_fs_input_cyl_centroid(ureg, semantic_name, semantic_index,
389b8e80941Smrg                                          TGSI_INTERPOLATE_CONSTANT, 0,
390b8e80941Smrg                                          TGSI_INTERPOLATE_LOC_CENTER,
391b8e80941Smrg                                          array_id, array_size);
392848b8605Smrg}
393848b8605Smrg
394848b8605Smrg
395848b8605Smrgstruct ureg_src
396848b8605Smrgureg_DECL_system_value(struct ureg_program *ureg,
397b8e80941Smrg                       enum tgsi_semantic semantic_name,
398848b8605Smrg                       unsigned semantic_index)
399848b8605Smrg{
400b8e80941Smrg   unsigned i;
401b8e80941Smrg
402b8e80941Smrg   for (i = 0; i < ureg->nr_system_values; i++) {
403b8e80941Smrg      if (ureg->system_value[i].semantic_name == semantic_name &&
404b8e80941Smrg          ureg->system_value[i].semantic_index == semantic_index) {
405b8e80941Smrg         goto out;
406b8e80941Smrg      }
407b8e80941Smrg   }
408b8e80941Smrg
409848b8605Smrg   if (ureg->nr_system_values < UREG_MAX_SYSTEM_VALUE) {
410848b8605Smrg      ureg->system_value[ureg->nr_system_values].semantic_name = semantic_name;
411848b8605Smrg      ureg->system_value[ureg->nr_system_values].semantic_index = semantic_index;
412b8e80941Smrg      i = ureg->nr_system_values;
413848b8605Smrg      ureg->nr_system_values++;
414848b8605Smrg   } else {
415848b8605Smrg      set_bad(ureg);
416848b8605Smrg   }
417848b8605Smrg
418b8e80941Smrgout:
419b8e80941Smrg   return ureg_src_register(TGSI_FILE_SYSTEM_VALUE, i);
420848b8605Smrg}
421848b8605Smrg
422848b8605Smrg
423b8e80941Smrgstruct ureg_dst
424b8e80941Smrgureg_DECL_output_layout(struct ureg_program *ureg,
425b8e80941Smrg                        enum tgsi_semantic semantic_name,
426b8e80941Smrg                        unsigned semantic_index,
427b8e80941Smrg                        unsigned streams,
428b8e80941Smrg                        unsigned index,
429b8e80941Smrg                        unsigned usage_mask,
430b8e80941Smrg                        unsigned array_id,
431b8e80941Smrg                        unsigned array_size,
432b8e80941Smrg                        boolean invariant)
433848b8605Smrg{
434848b8605Smrg   unsigned i;
435848b8605Smrg
436848b8605Smrg   assert(usage_mask != 0);
437b8e80941Smrg   assert(!(streams & 0x03) || (usage_mask & 1));
438b8e80941Smrg   assert(!(streams & 0x0c) || (usage_mask & 2));
439b8e80941Smrg   assert(!(streams & 0x30) || (usage_mask & 4));
440b8e80941Smrg   assert(!(streams & 0xc0) || (usage_mask & 8));
441848b8605Smrg
442848b8605Smrg   for (i = 0; i < ureg->nr_outputs; i++) {
443b8e80941Smrg      if (ureg->output[i].semantic_name == semantic_name &&
444b8e80941Smrg          ureg->output[i].semantic_index == semantic_index) {
445b8e80941Smrg         if (ureg->output[i].array_id == array_id) {
446b8e80941Smrg            ureg->output[i].usage_mask |= usage_mask;
447b8e80941Smrg            goto out;
448b8e80941Smrg         }
449b8e80941Smrg         assert((ureg->output[i].usage_mask & usage_mask) == 0);
450848b8605Smrg      }
451848b8605Smrg   }
452848b8605Smrg
453848b8605Smrg   if (ureg->nr_outputs < UREG_MAX_OUTPUT) {
454b8e80941Smrg      ureg->output[i].semantic_name = semantic_name;
455b8e80941Smrg      ureg->output[i].semantic_index = semantic_index;
456848b8605Smrg      ureg->output[i].usage_mask = usage_mask;
457b8e80941Smrg      ureg->output[i].first = index;
458b8e80941Smrg      ureg->output[i].last = index + array_size - 1;
459b8e80941Smrg      ureg->output[i].array_id = array_id;
460b8e80941Smrg      ureg->output[i].invariant = invariant;
461b8e80941Smrg      ureg->nr_output_regs = MAX2(ureg->nr_output_regs, index + array_size);
462848b8605Smrg      ureg->nr_outputs++;
463848b8605Smrg   }
464848b8605Smrg   else {
465848b8605Smrg      set_bad( ureg );
466b8e80941Smrg      i = 0;
467848b8605Smrg   }
468848b8605Smrg
469848b8605Smrgout:
470b8e80941Smrg   ureg->output[i].streams |= streams;
471b8e80941Smrg
472b8e80941Smrg   return ureg_dst_array_register(TGSI_FILE_OUTPUT, ureg->output[i].first,
473b8e80941Smrg                                  array_id);
474848b8605Smrg}
475848b8605Smrg
476848b8605Smrg
477b8e80941Smrgstruct ureg_dst
478b8e80941Smrgureg_DECL_output_masked(struct ureg_program *ureg,
479b8e80941Smrg                        unsigned name,
480b8e80941Smrg                        unsigned index,
481b8e80941Smrg                        unsigned usage_mask,
482b8e80941Smrg                        unsigned array_id,
483b8e80941Smrg                        unsigned array_size)
484b8e80941Smrg{
485b8e80941Smrg   return ureg_DECL_output_layout(ureg, name, index, 0,
486b8e80941Smrg                                  ureg->nr_output_regs, usage_mask, array_id,
487b8e80941Smrg                                  array_size, FALSE);
488b8e80941Smrg}
489b8e80941Smrg
490b8e80941Smrg
491b8e80941Smrgstruct ureg_dst
492b8e80941Smrgureg_DECL_output(struct ureg_program *ureg,
493b8e80941Smrg                 enum tgsi_semantic name,
494b8e80941Smrg                 unsigned index)
495b8e80941Smrg{
496b8e80941Smrg   return ureg_DECL_output_masked(ureg, name, index, TGSI_WRITEMASK_XYZW,
497b8e80941Smrg                                  0, 1);
498b8e80941Smrg}
499b8e80941Smrg
500b8e80941Smrgstruct ureg_dst
501b8e80941Smrgureg_DECL_output_array(struct ureg_program *ureg,
502b8e80941Smrg                       enum tgsi_semantic semantic_name,
503b8e80941Smrg                       unsigned semantic_index,
504b8e80941Smrg                       unsigned array_id,
505b8e80941Smrg                       unsigned array_size)
506848b8605Smrg{
507b8e80941Smrg   return ureg_DECL_output_masked(ureg, semantic_name, semantic_index,
508b8e80941Smrg                                  TGSI_WRITEMASK_XYZW,
509b8e80941Smrg                                  array_id, array_size);
510848b8605Smrg}
511848b8605Smrg
512848b8605Smrg
513848b8605Smrg/* Returns a new constant register.  Keep track of which have been
514848b8605Smrg * referred to so that we can emit decls later.
515848b8605Smrg *
516848b8605Smrg * Constant operands declared with this function must be addressed
517848b8605Smrg * with a two-dimensional index.
518848b8605Smrg *
519848b8605Smrg * There is nothing in this code to bind this constant to any tracked
520848b8605Smrg * value or manage any constant_buffer contents -- that's the
521848b8605Smrg * resposibility of the calling code.
522848b8605Smrg */
523848b8605Smrgvoid
524848b8605Smrgureg_DECL_constant2D(struct ureg_program *ureg,
525848b8605Smrg                     unsigned first,
526848b8605Smrg                     unsigned last,
527848b8605Smrg                     unsigned index2D)
528848b8605Smrg{
529b8e80941Smrg   struct const_decl *decl = &ureg->const_decls[index2D];
530848b8605Smrg
531848b8605Smrg   assert(index2D < PIPE_MAX_CONSTANT_BUFFERS);
532848b8605Smrg
533848b8605Smrg   if (decl->nr_constant_ranges < UREG_MAX_CONSTANT_RANGE) {
534848b8605Smrg      uint i = decl->nr_constant_ranges++;
535848b8605Smrg
536848b8605Smrg      decl->constant_range[i].first = first;
537848b8605Smrg      decl->constant_range[i].last = last;
538848b8605Smrg   }
539848b8605Smrg}
540848b8605Smrg
541848b8605Smrg
542b8e80941Smrg/* A one-dimensional, deprecated version of ureg_DECL_constant2D().
543848b8605Smrg *
544848b8605Smrg * Constant operands declared with this function must be addressed
545848b8605Smrg * with a one-dimensional index.
546848b8605Smrg */
547848b8605Smrgstruct ureg_src
548848b8605Smrgureg_DECL_constant(struct ureg_program *ureg,
549848b8605Smrg                   unsigned index)
550848b8605Smrg{
551b8e80941Smrg   struct const_decl *decl = &ureg->const_decls[0];
552848b8605Smrg   unsigned minconst = index, maxconst = index;
553848b8605Smrg   unsigned i;
554848b8605Smrg
555848b8605Smrg   /* Inside existing range?
556848b8605Smrg    */
557848b8605Smrg   for (i = 0; i < decl->nr_constant_ranges; i++) {
558848b8605Smrg      if (decl->constant_range[i].first <= index &&
559848b8605Smrg          decl->constant_range[i].last >= index) {
560848b8605Smrg         goto out;
561848b8605Smrg      }
562848b8605Smrg   }
563848b8605Smrg
564848b8605Smrg   /* Extend existing range?
565848b8605Smrg    */
566848b8605Smrg   for (i = 0; i < decl->nr_constant_ranges; i++) {
567848b8605Smrg      if (decl->constant_range[i].last == index - 1) {
568848b8605Smrg         decl->constant_range[i].last = index;
569848b8605Smrg         goto out;
570848b8605Smrg      }
571848b8605Smrg
572848b8605Smrg      if (decl->constant_range[i].first == index + 1) {
573848b8605Smrg         decl->constant_range[i].first = index;
574848b8605Smrg         goto out;
575848b8605Smrg      }
576848b8605Smrg
577848b8605Smrg      minconst = MIN2(minconst, decl->constant_range[i].first);
578848b8605Smrg      maxconst = MAX2(maxconst, decl->constant_range[i].last);
579848b8605Smrg   }
580848b8605Smrg
581848b8605Smrg   /* Create new range?
582848b8605Smrg    */
583848b8605Smrg   if (decl->nr_constant_ranges < UREG_MAX_CONSTANT_RANGE) {
584848b8605Smrg      i = decl->nr_constant_ranges++;
585848b8605Smrg      decl->constant_range[i].first = index;
586848b8605Smrg      decl->constant_range[i].last = index;
587848b8605Smrg      goto out;
588848b8605Smrg   }
589848b8605Smrg
590848b8605Smrg   /* Collapse all ranges down to one:
591848b8605Smrg    */
592848b8605Smrg   i = 0;
593848b8605Smrg   decl->constant_range[0].first = minconst;
594848b8605Smrg   decl->constant_range[0].last = maxconst;
595848b8605Smrg   decl->nr_constant_ranges = 1;
596848b8605Smrg
597848b8605Smrgout:
598848b8605Smrg   assert(i < decl->nr_constant_ranges);
599848b8605Smrg   assert(decl->constant_range[i].first <= index);
600848b8605Smrg   assert(decl->constant_range[i].last >= index);
601b8e80941Smrg
602b8e80941Smrg   struct ureg_src src = ureg_src_register(TGSI_FILE_CONSTANT, index);
603b8e80941Smrg   return ureg_src_dimension(src, 0);
604b8e80941Smrg}
605b8e80941Smrg
606b8e80941Smrg
607b8e80941Smrg/* Returns a new hw atomic register.  Keep track of which have been
608b8e80941Smrg * referred to so that we can emit decls later.
609b8e80941Smrg */
610b8e80941Smrgvoid
611b8e80941Smrgureg_DECL_hw_atomic(struct ureg_program *ureg,
612b8e80941Smrg                    unsigned first,
613b8e80941Smrg                    unsigned last,
614b8e80941Smrg                    unsigned buffer_id,
615b8e80941Smrg                    unsigned array_id)
616b8e80941Smrg{
617b8e80941Smrg   struct hw_atomic_decl *decl = &ureg->hw_atomic_decls[buffer_id];
618b8e80941Smrg
619b8e80941Smrg   if (decl->nr_hw_atomic_ranges < UREG_MAX_HW_ATOMIC_RANGE) {
620b8e80941Smrg      uint i = decl->nr_hw_atomic_ranges++;
621b8e80941Smrg
622b8e80941Smrg      decl->hw_atomic_range[i].first = first;
623b8e80941Smrg      decl->hw_atomic_range[i].last = last;
624b8e80941Smrg      decl->hw_atomic_range[i].array_id = array_id;
625b8e80941Smrg   } else {
626b8e80941Smrg      set_bad(ureg);
627b8e80941Smrg   }
628848b8605Smrg}
629848b8605Smrg
630848b8605Smrgstatic struct ureg_dst alloc_temporary( struct ureg_program *ureg,
631848b8605Smrg                                        boolean local )
632848b8605Smrg{
633848b8605Smrg   unsigned i;
634848b8605Smrg
635848b8605Smrg   /* Look for a released temporary.
636848b8605Smrg    */
637848b8605Smrg   for (i = util_bitmask_get_first_index(ureg->free_temps);
638848b8605Smrg        i != UTIL_BITMASK_INVALID_INDEX;
639848b8605Smrg        i = util_bitmask_get_next_index(ureg->free_temps, i + 1)) {
640848b8605Smrg      if (util_bitmask_get(ureg->local_temps, i) == local)
641848b8605Smrg         break;
642848b8605Smrg   }
643848b8605Smrg
644848b8605Smrg   /* Or allocate a new one.
645848b8605Smrg    */
646848b8605Smrg   if (i == UTIL_BITMASK_INVALID_INDEX) {
647848b8605Smrg      i = ureg->nr_temps++;
648848b8605Smrg
649848b8605Smrg      if (local)
650848b8605Smrg         util_bitmask_set(ureg->local_temps, i);
651848b8605Smrg
652848b8605Smrg      /* Start a new declaration when the local flag changes */
653848b8605Smrg      if (!i || util_bitmask_get(ureg->local_temps, i - 1) != local)
654848b8605Smrg         util_bitmask_set(ureg->decl_temps, i);
655848b8605Smrg   }
656848b8605Smrg
657848b8605Smrg   util_bitmask_clear(ureg->free_temps, i);
658848b8605Smrg
659848b8605Smrg   return ureg_dst_register( TGSI_FILE_TEMPORARY, i );
660848b8605Smrg}
661848b8605Smrg
662848b8605Smrgstruct ureg_dst ureg_DECL_temporary( struct ureg_program *ureg )
663848b8605Smrg{
664848b8605Smrg   return alloc_temporary(ureg, FALSE);
665848b8605Smrg}
666848b8605Smrg
667848b8605Smrgstruct ureg_dst ureg_DECL_local_temporary( struct ureg_program *ureg )
668848b8605Smrg{
669848b8605Smrg   return alloc_temporary(ureg, TRUE);
670848b8605Smrg}
671848b8605Smrg
672848b8605Smrgstruct ureg_dst ureg_DECL_array_temporary( struct ureg_program *ureg,
673848b8605Smrg                                           unsigned size,
674848b8605Smrg                                           boolean local )
675848b8605Smrg{
676848b8605Smrg   unsigned i = ureg->nr_temps;
677848b8605Smrg   struct ureg_dst dst = ureg_dst_register( TGSI_FILE_TEMPORARY, i );
678848b8605Smrg
679848b8605Smrg   if (local)
680848b8605Smrg      util_bitmask_set(ureg->local_temps, i);
681848b8605Smrg
682848b8605Smrg   /* Always start a new declaration at the start */
683848b8605Smrg   util_bitmask_set(ureg->decl_temps, i);
684848b8605Smrg
685848b8605Smrg   ureg->nr_temps += size;
686848b8605Smrg
687848b8605Smrg   /* and also at the end of the array */
688848b8605Smrg   util_bitmask_set(ureg->decl_temps, ureg->nr_temps);
689848b8605Smrg
690848b8605Smrg   if (ureg->nr_array_temps < UREG_MAX_ARRAY_TEMPS) {
691848b8605Smrg      ureg->array_temps[ureg->nr_array_temps++] = i;
692848b8605Smrg      dst.ArrayID = ureg->nr_array_temps;
693848b8605Smrg   }
694848b8605Smrg
695848b8605Smrg   return dst;
696848b8605Smrg}
697848b8605Smrg
698848b8605Smrgvoid ureg_release_temporary( struct ureg_program *ureg,
699848b8605Smrg                             struct ureg_dst tmp )
700848b8605Smrg{
701848b8605Smrg   if(tmp.File == TGSI_FILE_TEMPORARY)
702848b8605Smrg      util_bitmask_set(ureg->free_temps, tmp.Index);
703848b8605Smrg}
704848b8605Smrg
705848b8605Smrg
706848b8605Smrg/* Allocate a new address register.
707848b8605Smrg */
708848b8605Smrgstruct ureg_dst ureg_DECL_address( struct ureg_program *ureg )
709848b8605Smrg{
710848b8605Smrg   if (ureg->nr_addrs < UREG_MAX_ADDR)
711848b8605Smrg      return ureg_dst_register( TGSI_FILE_ADDRESS, ureg->nr_addrs++ );
712848b8605Smrg
713848b8605Smrg   assert( 0 );
714848b8605Smrg   return ureg_dst_register( TGSI_FILE_ADDRESS, 0 );
715848b8605Smrg}
716848b8605Smrg
717848b8605Smrg/* Allocate a new sampler.
718848b8605Smrg */
719848b8605Smrgstruct ureg_src ureg_DECL_sampler( struct ureg_program *ureg,
720848b8605Smrg                                   unsigned nr )
721848b8605Smrg{
722848b8605Smrg   unsigned i;
723848b8605Smrg
724848b8605Smrg   for (i = 0; i < ureg->nr_samplers; i++)
725b8e80941Smrg      if (ureg->sampler[i].Index == (int)nr)
726848b8605Smrg         return ureg->sampler[i];
727b8e80941Smrg
728848b8605Smrg   if (i < PIPE_MAX_SAMPLERS) {
729848b8605Smrg      ureg->sampler[i] = ureg_src_register( TGSI_FILE_SAMPLER, nr );
730848b8605Smrg      ureg->nr_samplers++;
731848b8605Smrg      return ureg->sampler[i];
732848b8605Smrg   }
733848b8605Smrg
734848b8605Smrg   assert( 0 );
735848b8605Smrg   return ureg->sampler[0];
736848b8605Smrg}
737848b8605Smrg
738848b8605Smrg/*
739848b8605Smrg * Allocate a new shader sampler view.
740848b8605Smrg */
741848b8605Smrgstruct ureg_src
742848b8605Smrgureg_DECL_sampler_view(struct ureg_program *ureg,
743848b8605Smrg                       unsigned index,
744b8e80941Smrg                       enum tgsi_texture_type target,
745b8e80941Smrg                       enum tgsi_return_type return_type_x,
746b8e80941Smrg                       enum tgsi_return_type return_type_y,
747b8e80941Smrg                       enum tgsi_return_type return_type_z,
748b8e80941Smrg                       enum tgsi_return_type return_type_w)
749848b8605Smrg{
750848b8605Smrg   struct ureg_src reg = ureg_src_register(TGSI_FILE_SAMPLER_VIEW, index);
751848b8605Smrg   uint i;
752848b8605Smrg
753848b8605Smrg   for (i = 0; i < ureg->nr_sampler_views; i++) {
754848b8605Smrg      if (ureg->sampler_view[i].index == index) {
755848b8605Smrg         return reg;
756848b8605Smrg      }
757848b8605Smrg   }
758848b8605Smrg
759848b8605Smrg   if (i < PIPE_MAX_SHADER_SAMPLER_VIEWS) {
760848b8605Smrg      ureg->sampler_view[i].index = index;
761848b8605Smrg      ureg->sampler_view[i].target = target;
762848b8605Smrg      ureg->sampler_view[i].return_type_x = return_type_x;
763848b8605Smrg      ureg->sampler_view[i].return_type_y = return_type_y;
764848b8605Smrg      ureg->sampler_view[i].return_type_z = return_type_z;
765848b8605Smrg      ureg->sampler_view[i].return_type_w = return_type_w;
766848b8605Smrg      ureg->nr_sampler_views++;
767848b8605Smrg      return reg;
768848b8605Smrg   }
769848b8605Smrg
770848b8605Smrg   assert(0);
771848b8605Smrg   return reg;
772848b8605Smrg}
773848b8605Smrg
774b8e80941Smrg/* Allocate a new image.
775b8e80941Smrg */
776b8e80941Smrgstruct ureg_src
777b8e80941Smrgureg_DECL_image(struct ureg_program *ureg,
778b8e80941Smrg                unsigned index,
779b8e80941Smrg                enum tgsi_texture_type target,
780b8e80941Smrg                enum pipe_format format,
781b8e80941Smrg                boolean wr,
782b8e80941Smrg                boolean raw)
783b8e80941Smrg{
784b8e80941Smrg   struct ureg_src reg = ureg_src_register(TGSI_FILE_IMAGE, index);
785b8e80941Smrg   unsigned i;
786b8e80941Smrg
787b8e80941Smrg   for (i = 0; i < ureg->nr_images; i++)
788b8e80941Smrg      if (ureg->image[i].index == index)
789b8e80941Smrg         return reg;
790b8e80941Smrg
791b8e80941Smrg   if (i < PIPE_MAX_SHADER_IMAGES) {
792b8e80941Smrg      ureg->image[i].index = index;
793b8e80941Smrg      ureg->image[i].target = target;
794b8e80941Smrg      ureg->image[i].wr = wr;
795b8e80941Smrg      ureg->image[i].raw = raw;
796b8e80941Smrg      ureg->image[i].format = format;
797b8e80941Smrg      ureg->nr_images++;
798b8e80941Smrg      return reg;
799b8e80941Smrg   }
800b8e80941Smrg
801b8e80941Smrg   assert(0);
802b8e80941Smrg   return reg;
803b8e80941Smrg}
804b8e80941Smrg
805b8e80941Smrg/* Allocate a new buffer.
806b8e80941Smrg */
807b8e80941Smrgstruct ureg_src ureg_DECL_buffer(struct ureg_program *ureg, unsigned nr,
808b8e80941Smrg                                 bool atomic)
809b8e80941Smrg{
810b8e80941Smrg   struct ureg_src reg = ureg_src_register(TGSI_FILE_BUFFER, nr);
811b8e80941Smrg   unsigned i;
812b8e80941Smrg
813b8e80941Smrg   for (i = 0; i < ureg->nr_buffers; i++)
814b8e80941Smrg      if (ureg->buffer[i].index == nr)
815b8e80941Smrg         return reg;
816b8e80941Smrg
817b8e80941Smrg   if (i < PIPE_MAX_SHADER_BUFFERS) {
818b8e80941Smrg      ureg->buffer[i].index = nr;
819b8e80941Smrg      ureg->buffer[i].atomic = atomic;
820b8e80941Smrg      ureg->nr_buffers++;
821b8e80941Smrg      return reg;
822b8e80941Smrg   }
823b8e80941Smrg
824b8e80941Smrg   assert(0);
825b8e80941Smrg   return reg;
826b8e80941Smrg}
827b8e80941Smrg
828b8e80941Smrg/* Allocate a memory area.
829b8e80941Smrg */
830b8e80941Smrgstruct ureg_src ureg_DECL_memory(struct ureg_program *ureg,
831b8e80941Smrg                                 unsigned memory_type)
832b8e80941Smrg{
833b8e80941Smrg   struct ureg_src reg = ureg_src_register(TGSI_FILE_MEMORY, memory_type);
834b8e80941Smrg
835b8e80941Smrg   ureg->use_memory[memory_type] = true;
836b8e80941Smrg   return reg;
837b8e80941Smrg}
838b8e80941Smrg
839b8e80941Smrgstatic int
840b8e80941Smrgmatch_or_expand_immediate64( const unsigned *v,
841b8e80941Smrg                             unsigned nr,
842b8e80941Smrg                             unsigned *v2,
843b8e80941Smrg                             unsigned *pnr2,
844b8e80941Smrg                             unsigned *swizzle )
845b8e80941Smrg{
846b8e80941Smrg   unsigned nr2 = *pnr2;
847b8e80941Smrg   unsigned i, j;
848b8e80941Smrg   *swizzle = 0;
849b8e80941Smrg
850b8e80941Smrg   for (i = 0; i < nr; i += 2) {
851b8e80941Smrg      boolean found = FALSE;
852b8e80941Smrg
853b8e80941Smrg      for (j = 0; j < nr2 && !found; j += 2) {
854b8e80941Smrg         if (v[i] == v2[j] && v[i + 1] == v2[j + 1]) {
855b8e80941Smrg            *swizzle |= (j << (i * 2)) | ((j + 1) << ((i + 1) * 2));
856b8e80941Smrg            found = TRUE;
857b8e80941Smrg         }
858b8e80941Smrg      }
859b8e80941Smrg      if (!found) {
860b8e80941Smrg         if ((nr2) >= 4) {
861b8e80941Smrg            return FALSE;
862b8e80941Smrg         }
863b8e80941Smrg
864b8e80941Smrg         v2[nr2] = v[i];
865b8e80941Smrg         v2[nr2 + 1] = v[i + 1];
866b8e80941Smrg
867b8e80941Smrg         *swizzle |= (nr2 << (i * 2)) | ((nr2 + 1) << ((i + 1) * 2));
868b8e80941Smrg         nr2 += 2;
869b8e80941Smrg      }
870b8e80941Smrg   }
871b8e80941Smrg
872b8e80941Smrg   /* Actually expand immediate only when fully succeeded.
873b8e80941Smrg    */
874b8e80941Smrg   *pnr2 = nr2;
875b8e80941Smrg   return TRUE;
876b8e80941Smrg}
877b8e80941Smrg
878848b8605Smrgstatic int
879848b8605Smrgmatch_or_expand_immediate( const unsigned *v,
880b8e80941Smrg                           int type,
881848b8605Smrg                           unsigned nr,
882848b8605Smrg                           unsigned *v2,
883848b8605Smrg                           unsigned *pnr2,
884848b8605Smrg                           unsigned *swizzle )
885848b8605Smrg{
886848b8605Smrg   unsigned nr2 = *pnr2;
887848b8605Smrg   unsigned i, j;
888848b8605Smrg
889b8e80941Smrg   if (type == TGSI_IMM_FLOAT64 ||
890b8e80941Smrg       type == TGSI_IMM_UINT64 ||
891b8e80941Smrg       type == TGSI_IMM_INT64)
892b8e80941Smrg      return match_or_expand_immediate64(v, nr, v2, pnr2, swizzle);
893b8e80941Smrg
894848b8605Smrg   *swizzle = 0;
895848b8605Smrg
896848b8605Smrg   for (i = 0; i < nr; i++) {
897848b8605Smrg      boolean found = FALSE;
898848b8605Smrg
899848b8605Smrg      for (j = 0; j < nr2 && !found; j++) {
900848b8605Smrg         if (v[i] == v2[j]) {
901848b8605Smrg            *swizzle |= j << (i * 2);
902848b8605Smrg            found = TRUE;
903848b8605Smrg         }
904848b8605Smrg      }
905848b8605Smrg
906848b8605Smrg      if (!found) {
907848b8605Smrg         if (nr2 >= 4) {
908848b8605Smrg            return FALSE;
909848b8605Smrg         }
910848b8605Smrg
911848b8605Smrg         v2[nr2] = v[i];
912848b8605Smrg         *swizzle |= nr2 << (i * 2);
913848b8605Smrg         nr2++;
914848b8605Smrg      }
915848b8605Smrg   }
916848b8605Smrg
917848b8605Smrg   /* Actually expand immediate only when fully succeeded.
918848b8605Smrg    */
919848b8605Smrg   *pnr2 = nr2;
920848b8605Smrg   return TRUE;
921848b8605Smrg}
922848b8605Smrg
923848b8605Smrg
924848b8605Smrgstatic struct ureg_src
925848b8605Smrgdecl_immediate( struct ureg_program *ureg,
926848b8605Smrg                const unsigned *v,
927848b8605Smrg                unsigned nr,
928848b8605Smrg                unsigned type )
929848b8605Smrg{
930848b8605Smrg   unsigned i, j;
931848b8605Smrg   unsigned swizzle = 0;
932848b8605Smrg
933848b8605Smrg   /* Could do a first pass where we examine all existing immediates
934848b8605Smrg    * without expanding.
935848b8605Smrg    */
936848b8605Smrg
937848b8605Smrg   for (i = 0; i < ureg->nr_immediates; i++) {
938848b8605Smrg      if (ureg->immediate[i].type != type) {
939848b8605Smrg         continue;
940848b8605Smrg      }
941848b8605Smrg      if (match_or_expand_immediate(v,
942b8e80941Smrg                                    type,
943848b8605Smrg                                    nr,
944848b8605Smrg                                    ureg->immediate[i].value.u,
945848b8605Smrg                                    &ureg->immediate[i].nr,
946848b8605Smrg                                    &swizzle)) {
947848b8605Smrg         goto out;
948848b8605Smrg      }
949848b8605Smrg   }
950848b8605Smrg
951848b8605Smrg   if (ureg->nr_immediates < UREG_MAX_IMMEDIATE) {
952848b8605Smrg      i = ureg->nr_immediates++;
953848b8605Smrg      ureg->immediate[i].type = type;
954848b8605Smrg      if (match_or_expand_immediate(v,
955b8e80941Smrg                                    type,
956848b8605Smrg                                    nr,
957848b8605Smrg                                    ureg->immediate[i].value.u,
958848b8605Smrg                                    &ureg->immediate[i].nr,
959848b8605Smrg                                    &swizzle)) {
960848b8605Smrg         goto out;
961848b8605Smrg      }
962848b8605Smrg   }
963848b8605Smrg
964848b8605Smrg   set_bad(ureg);
965848b8605Smrg
966848b8605Smrgout:
967848b8605Smrg   /* Make sure that all referenced elements are from this immediate.
968848b8605Smrg    * Has the effect of making size-one immediates into scalars.
969848b8605Smrg    */
970b8e80941Smrg   if (type == TGSI_IMM_FLOAT64 ||
971b8e80941Smrg       type == TGSI_IMM_UINT64 ||
972b8e80941Smrg       type == TGSI_IMM_INT64) {
973b8e80941Smrg      for (j = nr; j < 4; j+=2) {
974b8e80941Smrg         swizzle |= (swizzle & 0xf) << (j * 2);
975b8e80941Smrg      }
976b8e80941Smrg   } else {
977b8e80941Smrg      for (j = nr; j < 4; j++) {
978b8e80941Smrg         swizzle |= (swizzle & 0x3) << (j * 2);
979b8e80941Smrg      }
980848b8605Smrg   }
981848b8605Smrg   return ureg_swizzle(ureg_src_register(TGSI_FILE_IMMEDIATE, i),
982848b8605Smrg                       (swizzle >> 0) & 0x3,
983848b8605Smrg                       (swizzle >> 2) & 0x3,
984848b8605Smrg                       (swizzle >> 4) & 0x3,
985848b8605Smrg                       (swizzle >> 6) & 0x3);
986848b8605Smrg}
987848b8605Smrg
988848b8605Smrg
989848b8605Smrgstruct ureg_src
990848b8605Smrgureg_DECL_immediate( struct ureg_program *ureg,
991848b8605Smrg                     const float *v,
992848b8605Smrg                     unsigned nr )
993848b8605Smrg{
994848b8605Smrg   union {
995848b8605Smrg      float f[4];
996848b8605Smrg      unsigned u[4];
997848b8605Smrg   } fu;
998848b8605Smrg   unsigned int i;
999848b8605Smrg
1000848b8605Smrg   for (i = 0; i < nr; i++) {
1001848b8605Smrg      fu.f[i] = v[i];
1002848b8605Smrg   }
1003848b8605Smrg
1004848b8605Smrg   return decl_immediate(ureg, fu.u, nr, TGSI_IMM_FLOAT32);
1005848b8605Smrg}
1006848b8605Smrg
1007b8e80941Smrgstruct ureg_src
1008b8e80941Smrgureg_DECL_immediate_f64( struct ureg_program *ureg,
1009b8e80941Smrg                         const double *v,
1010b8e80941Smrg                         unsigned nr )
1011b8e80941Smrg{
1012b8e80941Smrg   union {
1013b8e80941Smrg      unsigned u[4];
1014b8e80941Smrg      double d[2];
1015b8e80941Smrg   } fu;
1016b8e80941Smrg   unsigned int i;
1017b8e80941Smrg
1018b8e80941Smrg   assert((nr / 2) < 3);
1019b8e80941Smrg   for (i = 0; i < nr / 2; i++) {
1020b8e80941Smrg      fu.d[i] = v[i];
1021b8e80941Smrg   }
1022b8e80941Smrg
1023b8e80941Smrg   return decl_immediate(ureg, fu.u, nr, TGSI_IMM_FLOAT64);
1024b8e80941Smrg}
1025848b8605Smrg
1026848b8605Smrgstruct ureg_src
1027848b8605Smrgureg_DECL_immediate_uint( struct ureg_program *ureg,
1028848b8605Smrg                          const unsigned *v,
1029848b8605Smrg                          unsigned nr )
1030848b8605Smrg{
1031848b8605Smrg   return decl_immediate(ureg, v, nr, TGSI_IMM_UINT32);
1032848b8605Smrg}
1033848b8605Smrg
1034848b8605Smrg
1035848b8605Smrgstruct ureg_src
1036848b8605Smrgureg_DECL_immediate_block_uint( struct ureg_program *ureg,
1037848b8605Smrg                                const unsigned *v,
1038848b8605Smrg                                unsigned nr )
1039848b8605Smrg{
1040848b8605Smrg   uint index;
1041848b8605Smrg   uint i;
1042848b8605Smrg
1043848b8605Smrg   if (ureg->nr_immediates + (nr + 3) / 4 > UREG_MAX_IMMEDIATE) {
1044848b8605Smrg      set_bad(ureg);
1045848b8605Smrg      return ureg_src_register(TGSI_FILE_IMMEDIATE, 0);
1046848b8605Smrg   }
1047848b8605Smrg
1048848b8605Smrg   index = ureg->nr_immediates;
1049848b8605Smrg   ureg->nr_immediates += (nr + 3) / 4;
1050848b8605Smrg
1051848b8605Smrg   for (i = index; i < ureg->nr_immediates; i++) {
1052848b8605Smrg      ureg->immediate[i].type = TGSI_IMM_UINT32;
1053848b8605Smrg      ureg->immediate[i].nr = nr > 4 ? 4 : nr;
1054848b8605Smrg      memcpy(ureg->immediate[i].value.u,
1055848b8605Smrg             &v[(i - index) * 4],
1056848b8605Smrg             ureg->immediate[i].nr * sizeof(uint));
1057848b8605Smrg      nr -= 4;
1058848b8605Smrg   }
1059848b8605Smrg
1060848b8605Smrg   return ureg_src_register(TGSI_FILE_IMMEDIATE, index);
1061848b8605Smrg}
1062848b8605Smrg
1063848b8605Smrg
1064848b8605Smrgstruct ureg_src
1065848b8605Smrgureg_DECL_immediate_int( struct ureg_program *ureg,
1066848b8605Smrg                         const int *v,
1067848b8605Smrg                         unsigned nr )
1068848b8605Smrg{
1069848b8605Smrg   return decl_immediate(ureg, (const unsigned *)v, nr, TGSI_IMM_INT32);
1070848b8605Smrg}
1071848b8605Smrg
1072b8e80941Smrgstruct ureg_src
1073b8e80941Smrgureg_DECL_immediate_uint64( struct ureg_program *ureg,
1074b8e80941Smrg                            const uint64_t *v,
1075b8e80941Smrg                            unsigned nr )
1076b8e80941Smrg{
1077b8e80941Smrg   union {
1078b8e80941Smrg      unsigned u[4];
1079b8e80941Smrg      uint64_t u64[2];
1080b8e80941Smrg   } fu;
1081b8e80941Smrg   unsigned int i;
1082b8e80941Smrg
1083b8e80941Smrg   assert((nr / 2) < 3);
1084b8e80941Smrg   for (i = 0; i < nr / 2; i++) {
1085b8e80941Smrg      fu.u64[i] = v[i];
1086b8e80941Smrg   }
1087b8e80941Smrg
1088b8e80941Smrg   return decl_immediate(ureg, fu.u, nr, TGSI_IMM_UINT64);
1089b8e80941Smrg}
1090b8e80941Smrg
1091b8e80941Smrgstruct ureg_src
1092b8e80941Smrgureg_DECL_immediate_int64( struct ureg_program *ureg,
1093b8e80941Smrg                           const int64_t *v,
1094b8e80941Smrg                           unsigned nr )
1095b8e80941Smrg{
1096b8e80941Smrg   union {
1097b8e80941Smrg      unsigned u[4];
1098b8e80941Smrg      int64_t i64[2];
1099b8e80941Smrg   } fu;
1100b8e80941Smrg   unsigned int i;
1101b8e80941Smrg
1102b8e80941Smrg   assert((nr / 2) < 3);
1103b8e80941Smrg   for (i = 0; i < nr / 2; i++) {
1104b8e80941Smrg      fu.i64[i] = v[i];
1105b8e80941Smrg   }
1106b8e80941Smrg
1107b8e80941Smrg   return decl_immediate(ureg, fu.u, nr, TGSI_IMM_INT64);
1108b8e80941Smrg}
1109848b8605Smrg
1110848b8605Smrgvoid
1111848b8605Smrgureg_emit_src( struct ureg_program *ureg,
1112848b8605Smrg               struct ureg_src src )
1113848b8605Smrg{
1114848b8605Smrg   unsigned size = 1 + (src.Indirect ? 1 : 0) +
1115848b8605Smrg                   (src.Dimension ? (src.DimIndirect ? 2 : 1) : 0);
1116848b8605Smrg
1117848b8605Smrg   union tgsi_any_token *out = get_tokens( ureg, DOMAIN_INSN, size );
1118848b8605Smrg   unsigned n = 0;
1119848b8605Smrg
1120848b8605Smrg   assert(src.File != TGSI_FILE_NULL);
1121848b8605Smrg   assert(src.File < TGSI_FILE_COUNT);
1122b8e80941Smrg
1123848b8605Smrg   out[n].value = 0;
1124848b8605Smrg   out[n].src.File = src.File;
1125848b8605Smrg   out[n].src.SwizzleX = src.SwizzleX;
1126848b8605Smrg   out[n].src.SwizzleY = src.SwizzleY;
1127848b8605Smrg   out[n].src.SwizzleZ = src.SwizzleZ;
1128848b8605Smrg   out[n].src.SwizzleW = src.SwizzleW;
1129848b8605Smrg   out[n].src.Index = src.Index;
1130848b8605Smrg   out[n].src.Negate = src.Negate;
1131848b8605Smrg   out[0].src.Absolute = src.Absolute;
1132848b8605Smrg   n++;
1133848b8605Smrg
1134848b8605Smrg   if (src.Indirect) {
1135848b8605Smrg      out[0].src.Indirect = 1;
1136848b8605Smrg      out[n].value = 0;
1137848b8605Smrg      out[n].ind.File = src.IndirectFile;
1138848b8605Smrg      out[n].ind.Swizzle = src.IndirectSwizzle;
1139848b8605Smrg      out[n].ind.Index = src.IndirectIndex;
1140b8e80941Smrg      if (!ureg->supports_any_inout_decl_range &&
1141b8e80941Smrg          (src.File == TGSI_FILE_INPUT || src.File == TGSI_FILE_OUTPUT))
1142b8e80941Smrg         out[n].ind.ArrayID = 0;
1143b8e80941Smrg      else
1144b8e80941Smrg         out[n].ind.ArrayID = src.ArrayID;
1145848b8605Smrg      n++;
1146848b8605Smrg   }
1147848b8605Smrg
1148848b8605Smrg   if (src.Dimension) {
1149848b8605Smrg      out[0].src.Dimension = 1;
1150848b8605Smrg      out[n].dim.Dimension = 0;
1151848b8605Smrg      out[n].dim.Padding = 0;
1152848b8605Smrg      if (src.DimIndirect) {
1153848b8605Smrg         out[n].dim.Indirect = 1;
1154848b8605Smrg         out[n].dim.Index = src.DimensionIndex;
1155848b8605Smrg         n++;
1156848b8605Smrg         out[n].value = 0;
1157848b8605Smrg         out[n].ind.File = src.DimIndFile;
1158848b8605Smrg         out[n].ind.Swizzle = src.DimIndSwizzle;
1159848b8605Smrg         out[n].ind.Index = src.DimIndIndex;
1160b8e80941Smrg         if (!ureg->supports_any_inout_decl_range &&
1161b8e80941Smrg             (src.File == TGSI_FILE_INPUT || src.File == TGSI_FILE_OUTPUT))
1162b8e80941Smrg            out[n].ind.ArrayID = 0;
1163b8e80941Smrg         else
1164b8e80941Smrg            out[n].ind.ArrayID = src.ArrayID;
1165848b8605Smrg      } else {
1166848b8605Smrg         out[n].dim.Indirect = 0;
1167848b8605Smrg         out[n].dim.Index = src.DimensionIndex;
1168848b8605Smrg      }
1169848b8605Smrg      n++;
1170848b8605Smrg   }
1171848b8605Smrg
1172848b8605Smrg   assert(n == size);
1173848b8605Smrg}
1174848b8605Smrg
1175848b8605Smrg
1176b8e80941Smrgvoid
1177848b8605Smrgureg_emit_dst( struct ureg_program *ureg,
1178848b8605Smrg               struct ureg_dst dst )
1179848b8605Smrg{
1180b8e80941Smrg   unsigned size = 1 + (dst.Indirect ? 1 : 0) +
1181b8e80941Smrg                   (dst.Dimension ? (dst.DimIndirect ? 2 : 1) : 0);
1182848b8605Smrg
1183848b8605Smrg   union tgsi_any_token *out = get_tokens( ureg, DOMAIN_INSN, size );
1184848b8605Smrg   unsigned n = 0;
1185848b8605Smrg
1186848b8605Smrg   assert(dst.File != TGSI_FILE_NULL);
1187848b8605Smrg   assert(dst.File != TGSI_FILE_SAMPLER);
1188848b8605Smrg   assert(dst.File != TGSI_FILE_SAMPLER_VIEW);
1189848b8605Smrg   assert(dst.File != TGSI_FILE_IMMEDIATE);
1190848b8605Smrg   assert(dst.File < TGSI_FILE_COUNT);
1191848b8605Smrg
1192848b8605Smrg   out[n].value = 0;
1193848b8605Smrg   out[n].dst.File = dst.File;
1194848b8605Smrg   out[n].dst.WriteMask = dst.WriteMask;
1195848b8605Smrg   out[n].dst.Indirect = dst.Indirect;
1196848b8605Smrg   out[n].dst.Index = dst.Index;
1197848b8605Smrg   n++;
1198b8e80941Smrg
1199848b8605Smrg   if (dst.Indirect) {
1200848b8605Smrg      out[n].value = 0;
1201848b8605Smrg      out[n].ind.File = dst.IndirectFile;
1202848b8605Smrg      out[n].ind.Swizzle = dst.IndirectSwizzle;
1203848b8605Smrg      out[n].ind.Index = dst.IndirectIndex;
1204b8e80941Smrg      if (!ureg->supports_any_inout_decl_range &&
1205b8e80941Smrg          (dst.File == TGSI_FILE_INPUT || dst.File == TGSI_FILE_OUTPUT))
1206b8e80941Smrg         out[n].ind.ArrayID = 0;
1207b8e80941Smrg      else
1208b8e80941Smrg         out[n].ind.ArrayID = dst.ArrayID;
1209b8e80941Smrg      n++;
1210b8e80941Smrg   }
1211b8e80941Smrg
1212b8e80941Smrg   if (dst.Dimension) {
1213b8e80941Smrg      out[0].dst.Dimension = 1;
1214b8e80941Smrg      out[n].dim.Dimension = 0;
1215b8e80941Smrg      out[n].dim.Padding = 0;
1216b8e80941Smrg      if (dst.DimIndirect) {
1217b8e80941Smrg         out[n].dim.Indirect = 1;
1218b8e80941Smrg         out[n].dim.Index = dst.DimensionIndex;
1219b8e80941Smrg         n++;
1220b8e80941Smrg         out[n].value = 0;
1221b8e80941Smrg         out[n].ind.File = dst.DimIndFile;
1222b8e80941Smrg         out[n].ind.Swizzle = dst.DimIndSwizzle;
1223b8e80941Smrg         out[n].ind.Index = dst.DimIndIndex;
1224b8e80941Smrg         if (!ureg->supports_any_inout_decl_range &&
1225b8e80941Smrg             (dst.File == TGSI_FILE_INPUT || dst.File == TGSI_FILE_OUTPUT))
1226b8e80941Smrg            out[n].ind.ArrayID = 0;
1227b8e80941Smrg         else
1228b8e80941Smrg            out[n].ind.ArrayID = dst.ArrayID;
1229b8e80941Smrg      } else {
1230b8e80941Smrg         out[n].dim.Indirect = 0;
1231b8e80941Smrg         out[n].dim.Index = dst.DimensionIndex;
1232b8e80941Smrg      }
1233848b8605Smrg      n++;
1234848b8605Smrg   }
1235848b8605Smrg
1236848b8605Smrg   assert(n == size);
1237848b8605Smrg}
1238848b8605Smrg
1239848b8605Smrg
1240b8e80941Smrgstatic void validate( enum tgsi_opcode opcode,
1241848b8605Smrg                      unsigned nr_dst,
1242848b8605Smrg                      unsigned nr_src )
1243848b8605Smrg{
1244848b8605Smrg#ifdef DEBUG
1245848b8605Smrg   const struct tgsi_opcode_info *info = tgsi_get_opcode_info( opcode );
1246848b8605Smrg   assert(info);
1247b8e80941Smrg   if (info) {
1248848b8605Smrg      assert(nr_dst == info->num_dst);
1249848b8605Smrg      assert(nr_src == info->num_src);
1250848b8605Smrg   }
1251848b8605Smrg#endif
1252848b8605Smrg}
1253848b8605Smrg
1254848b8605Smrgstruct ureg_emit_insn_result
1255848b8605Smrgureg_emit_insn(struct ureg_program *ureg,
1256b8e80941Smrg               enum tgsi_opcode opcode,
1257848b8605Smrg               boolean saturate,
1258b8e80941Smrg               unsigned precise,
1259848b8605Smrg               unsigned num_dst,
1260b8e80941Smrg               unsigned num_src)
1261848b8605Smrg{
1262848b8605Smrg   union tgsi_any_token *out;
1263b8e80941Smrg   uint count = 1;
1264848b8605Smrg   struct ureg_emit_insn_result result;
1265848b8605Smrg
1266848b8605Smrg   validate( opcode, num_dst, num_src );
1267b8e80941Smrg
1268848b8605Smrg   out = get_tokens( ureg, DOMAIN_INSN, count );
1269848b8605Smrg   out[0].insn = tgsi_default_instruction();
1270848b8605Smrg   out[0].insn.Opcode = opcode;
1271848b8605Smrg   out[0].insn.Saturate = saturate;
1272b8e80941Smrg   out[0].insn.Precise = precise;
1273848b8605Smrg   out[0].insn.NumDstRegs = num_dst;
1274848b8605Smrg   out[0].insn.NumSrcRegs = num_src;
1275848b8605Smrg
1276848b8605Smrg   result.insn_token = ureg->domain[DOMAIN_INSN].count - count;
1277848b8605Smrg   result.extended_token = result.insn_token;
1278848b8605Smrg
1279848b8605Smrg   ureg->nr_instructions++;
1280848b8605Smrg
1281848b8605Smrg   return result;
1282848b8605Smrg}
1283848b8605Smrg
1284848b8605Smrg
1285b8e80941Smrg/**
1286b8e80941Smrg * Emit a label token.
1287b8e80941Smrg * \param label_token returns a token number indicating where the label
1288b8e80941Smrg * needs to be patched later.  Later, this value should be passed to the
1289b8e80941Smrg * ureg_fixup_label() function.
1290b8e80941Smrg */
1291848b8605Smrgvoid
1292848b8605Smrgureg_emit_label(struct ureg_program *ureg,
1293848b8605Smrg                unsigned extended_token,
1294848b8605Smrg                unsigned *label_token )
1295848b8605Smrg{
1296848b8605Smrg   union tgsi_any_token *out, *insn;
1297848b8605Smrg
1298b8e80941Smrg   if (!label_token)
1299848b8605Smrg      return;
1300848b8605Smrg
1301848b8605Smrg   out = get_tokens( ureg, DOMAIN_INSN, 1 );
1302848b8605Smrg   out[0].value = 0;
1303848b8605Smrg
1304848b8605Smrg   insn = retrieve_token( ureg, DOMAIN_INSN, extended_token );
1305848b8605Smrg   insn->insn.Label = 1;
1306848b8605Smrg
1307848b8605Smrg   *label_token = ureg->domain[DOMAIN_INSN].count - 1;
1308848b8605Smrg}
1309848b8605Smrg
1310848b8605Smrg/* Will return a number which can be used in a label to point to the
1311848b8605Smrg * next instruction to be emitted.
1312848b8605Smrg */
1313848b8605Smrgunsigned
1314848b8605Smrgureg_get_instruction_number( struct ureg_program *ureg )
1315848b8605Smrg{
1316848b8605Smrg   return ureg->nr_instructions;
1317848b8605Smrg}
1318848b8605Smrg
1319848b8605Smrg/* Patch a given label (expressed as a token number) to point to a
1320848b8605Smrg * given instruction (expressed as an instruction number).
1321848b8605Smrg */
1322848b8605Smrgvoid
1323848b8605Smrgureg_fixup_label(struct ureg_program *ureg,
1324848b8605Smrg                 unsigned label_token,
1325848b8605Smrg                 unsigned instruction_number )
1326848b8605Smrg{
1327848b8605Smrg   union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_INSN, label_token );
1328848b8605Smrg
1329848b8605Smrg   out->insn_label.Label = instruction_number;
1330848b8605Smrg}
1331848b8605Smrg
1332848b8605Smrg
1333848b8605Smrgvoid
1334848b8605Smrgureg_emit_texture(struct ureg_program *ureg,
1335848b8605Smrg                  unsigned extended_token,
1336b8e80941Smrg                  enum tgsi_texture_type target,
1337b8e80941Smrg                  enum tgsi_return_type return_type, unsigned num_offsets)
1338848b8605Smrg{
1339848b8605Smrg   union tgsi_any_token *out, *insn;
1340848b8605Smrg
1341848b8605Smrg   out = get_tokens( ureg, DOMAIN_INSN, 1 );
1342848b8605Smrg   insn = retrieve_token( ureg, DOMAIN_INSN, extended_token );
1343848b8605Smrg
1344848b8605Smrg   insn->insn.Texture = 1;
1345848b8605Smrg
1346848b8605Smrg   out[0].value = 0;
1347848b8605Smrg   out[0].insn_texture.Texture = target;
1348848b8605Smrg   out[0].insn_texture.NumOffsets = num_offsets;
1349b8e80941Smrg   out[0].insn_texture.ReturnType = return_type;
1350848b8605Smrg}
1351848b8605Smrg
1352848b8605Smrgvoid
1353848b8605Smrgureg_emit_texture_offset(struct ureg_program *ureg,
1354848b8605Smrg                         const struct tgsi_texture_offset *offset)
1355848b8605Smrg{
1356848b8605Smrg   union tgsi_any_token *out;
1357848b8605Smrg
1358848b8605Smrg   out = get_tokens( ureg, DOMAIN_INSN, 1);
1359848b8605Smrg
1360848b8605Smrg   out[0].value = 0;
1361848b8605Smrg   out[0].insn_texture_offset = *offset;
1362848b8605Smrg}
1363848b8605Smrg
1364b8e80941Smrgvoid
1365b8e80941Smrgureg_emit_memory(struct ureg_program *ureg,
1366b8e80941Smrg                 unsigned extended_token,
1367b8e80941Smrg                 unsigned qualifier,
1368b8e80941Smrg                 enum tgsi_texture_type texture,
1369b8e80941Smrg                 enum pipe_format format)
1370b8e80941Smrg{
1371b8e80941Smrg   union tgsi_any_token *out, *insn;
1372b8e80941Smrg
1373b8e80941Smrg   out = get_tokens( ureg, DOMAIN_INSN, 1 );
1374b8e80941Smrg   insn = retrieve_token( ureg, DOMAIN_INSN, extended_token );
1375b8e80941Smrg
1376b8e80941Smrg   insn->insn.Memory = 1;
1377b8e80941Smrg
1378b8e80941Smrg   out[0].value = 0;
1379b8e80941Smrg   out[0].insn_memory.Qualifier = qualifier;
1380b8e80941Smrg   out[0].insn_memory.Texture = texture;
1381b8e80941Smrg   out[0].insn_memory.Format = format;
1382b8e80941Smrg}
1383848b8605Smrg
1384848b8605Smrgvoid
1385848b8605Smrgureg_fixup_insn_size(struct ureg_program *ureg,
1386848b8605Smrg                     unsigned insn )
1387848b8605Smrg{
1388848b8605Smrg   union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_INSN, insn );
1389848b8605Smrg
1390848b8605Smrg   assert(out->insn.Type == TGSI_TOKEN_TYPE_INSTRUCTION);
1391848b8605Smrg   out->insn.NrTokens = ureg->domain[DOMAIN_INSN].count - insn - 1;
1392848b8605Smrg}
1393848b8605Smrg
1394848b8605Smrg
1395848b8605Smrgvoid
1396848b8605Smrgureg_insn(struct ureg_program *ureg,
1397b8e80941Smrg          enum tgsi_opcode opcode,
1398848b8605Smrg          const struct ureg_dst *dst,
1399848b8605Smrg          unsigned nr_dst,
1400848b8605Smrg          const struct ureg_src *src,
1401b8e80941Smrg          unsigned nr_src,
1402b8e80941Smrg          unsigned precise )
1403848b8605Smrg{
1404848b8605Smrg   struct ureg_emit_insn_result insn;
1405848b8605Smrg   unsigned i;
1406848b8605Smrg   boolean saturate;
1407848b8605Smrg
1408848b8605Smrg   if (nr_dst && ureg_dst_is_empty(dst[0])) {
1409848b8605Smrg      return;
1410848b8605Smrg   }
1411848b8605Smrg
1412848b8605Smrg   saturate = nr_dst ? dst[0].Saturate : FALSE;
1413848b8605Smrg
1414848b8605Smrg   insn = ureg_emit_insn(ureg,
1415848b8605Smrg                         opcode,
1416848b8605Smrg                         saturate,
1417b8e80941Smrg                         precise,
1418848b8605Smrg                         nr_dst,
1419848b8605Smrg                         nr_src);
1420848b8605Smrg
1421848b8605Smrg   for (i = 0; i < nr_dst; i++)
1422848b8605Smrg      ureg_emit_dst( ureg, dst[i] );
1423848b8605Smrg
1424848b8605Smrg   for (i = 0; i < nr_src; i++)
1425848b8605Smrg      ureg_emit_src( ureg, src[i] );
1426848b8605Smrg
1427848b8605Smrg   ureg_fixup_insn_size( ureg, insn.insn_token );
1428848b8605Smrg}
1429848b8605Smrg
1430848b8605Smrgvoid
1431848b8605Smrgureg_tex_insn(struct ureg_program *ureg,
1432b8e80941Smrg              enum tgsi_opcode opcode,
1433848b8605Smrg              const struct ureg_dst *dst,
1434848b8605Smrg              unsigned nr_dst,
1435b8e80941Smrg              enum tgsi_texture_type target,
1436b8e80941Smrg              enum tgsi_return_type return_type,
1437848b8605Smrg              const struct tgsi_texture_offset *texoffsets,
1438848b8605Smrg              unsigned nr_offset,
1439848b8605Smrg              const struct ureg_src *src,
1440848b8605Smrg              unsigned nr_src )
1441848b8605Smrg{
1442848b8605Smrg   struct ureg_emit_insn_result insn;
1443848b8605Smrg   unsigned i;
1444848b8605Smrg   boolean saturate;
1445848b8605Smrg
1446848b8605Smrg   if (nr_dst && ureg_dst_is_empty(dst[0])) {
1447848b8605Smrg      return;
1448848b8605Smrg   }
1449848b8605Smrg
1450848b8605Smrg   saturate = nr_dst ? dst[0].Saturate : FALSE;
1451848b8605Smrg
1452848b8605Smrg   insn = ureg_emit_insn(ureg,
1453848b8605Smrg                         opcode,
1454848b8605Smrg                         saturate,
1455b8e80941Smrg                         0,
1456848b8605Smrg                         nr_dst,
1457848b8605Smrg                         nr_src);
1458848b8605Smrg
1459b8e80941Smrg   ureg_emit_texture( ureg, insn.extended_token, target, return_type,
1460b8e80941Smrg                      nr_offset );
1461848b8605Smrg
1462848b8605Smrg   for (i = 0; i < nr_offset; i++)
1463848b8605Smrg      ureg_emit_texture_offset( ureg, &texoffsets[i]);
1464848b8605Smrg
1465848b8605Smrg   for (i = 0; i < nr_dst; i++)
1466848b8605Smrg      ureg_emit_dst( ureg, dst[i] );
1467848b8605Smrg
1468848b8605Smrg   for (i = 0; i < nr_src; i++)
1469848b8605Smrg      ureg_emit_src( ureg, src[i] );
1470848b8605Smrg
1471848b8605Smrg   ureg_fixup_insn_size( ureg, insn.insn_token );
1472848b8605Smrg}
1473848b8605Smrg
1474848b8605Smrg
1475848b8605Smrgvoid
1476b8e80941Smrgureg_memory_insn(struct ureg_program *ureg,
1477b8e80941Smrg                 enum tgsi_opcode opcode,
1478b8e80941Smrg                 const struct ureg_dst *dst,
1479b8e80941Smrg                 unsigned nr_dst,
1480b8e80941Smrg                 const struct ureg_src *src,
1481b8e80941Smrg                 unsigned nr_src,
1482b8e80941Smrg                 unsigned qualifier,
1483b8e80941Smrg                 enum tgsi_texture_type texture,
1484b8e80941Smrg                 enum pipe_format format)
1485848b8605Smrg{
1486848b8605Smrg   struct ureg_emit_insn_result insn;
1487848b8605Smrg   unsigned i;
1488848b8605Smrg
1489848b8605Smrg   insn = ureg_emit_insn(ureg,
1490848b8605Smrg                         opcode,
1491848b8605Smrg                         FALSE,
1492848b8605Smrg                         0,
1493b8e80941Smrg                         nr_dst,
1494848b8605Smrg                         nr_src);
1495848b8605Smrg
1496b8e80941Smrg   ureg_emit_memory(ureg, insn.extended_token, qualifier, texture, format);
1497b8e80941Smrg
1498b8e80941Smrg   for (i = 0; i < nr_dst; i++)
1499b8e80941Smrg      ureg_emit_dst(ureg, dst[i]);
1500848b8605Smrg
1501848b8605Smrg   for (i = 0; i < nr_src; i++)
1502b8e80941Smrg      ureg_emit_src(ureg, src[i]);
1503848b8605Smrg
1504b8e80941Smrg   ureg_fixup_insn_size(ureg, insn.insn_token);
1505848b8605Smrg}
1506848b8605Smrg
1507848b8605Smrg
1508848b8605Smrgstatic void
1509848b8605Smrgemit_decl_semantic(struct ureg_program *ureg,
1510848b8605Smrg                   unsigned file,
1511b8e80941Smrg                   unsigned first,
1512b8e80941Smrg                   unsigned last,
1513b8e80941Smrg                   enum tgsi_semantic semantic_name,
1514848b8605Smrg                   unsigned semantic_index,
1515b8e80941Smrg                   unsigned streams,
1516b8e80941Smrg                   unsigned usage_mask,
1517b8e80941Smrg                   unsigned array_id,
1518b8e80941Smrg                   boolean invariant)
1519848b8605Smrg{
1520b8e80941Smrg   union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, array_id ? 4 : 3);
1521848b8605Smrg
1522848b8605Smrg   out[0].value = 0;
1523848b8605Smrg   out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
1524848b8605Smrg   out[0].decl.NrTokens = 3;
1525848b8605Smrg   out[0].decl.File = file;
1526848b8605Smrg   out[0].decl.UsageMask = usage_mask;
1527848b8605Smrg   out[0].decl.Semantic = 1;
1528b8e80941Smrg   out[0].decl.Array = array_id != 0;
1529b8e80941Smrg   out[0].decl.Invariant = invariant;
1530848b8605Smrg
1531848b8605Smrg   out[1].value = 0;
1532b8e80941Smrg   out[1].decl_range.First = first;
1533b8e80941Smrg   out[1].decl_range.Last = last;
1534848b8605Smrg
1535848b8605Smrg   out[2].value = 0;
1536848b8605Smrg   out[2].decl_semantic.Name = semantic_name;
1537848b8605Smrg   out[2].decl_semantic.Index = semantic_index;
1538b8e80941Smrg   out[2].decl_semantic.StreamX = streams & 3;
1539b8e80941Smrg   out[2].decl_semantic.StreamY = (streams >> 2) & 3;
1540b8e80941Smrg   out[2].decl_semantic.StreamZ = (streams >> 4) & 3;
1541b8e80941Smrg   out[2].decl_semantic.StreamW = (streams >> 6) & 3;
1542b8e80941Smrg
1543b8e80941Smrg   if (array_id) {
1544b8e80941Smrg      out[3].value = 0;
1545b8e80941Smrg      out[3].array.ArrayID = array_id;
1546b8e80941Smrg   }
1547848b8605Smrg}
1548848b8605Smrg
1549b8e80941Smrgstatic void
1550b8e80941Smrgemit_decl_atomic_2d(struct ureg_program *ureg,
1551b8e80941Smrg                    unsigned first,
1552b8e80941Smrg                    unsigned last,
1553b8e80941Smrg                    unsigned index2D,
1554b8e80941Smrg                    unsigned array_id)
1555b8e80941Smrg{
1556b8e80941Smrg   union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, array_id ? 4 : 3);
1557b8e80941Smrg
1558b8e80941Smrg   out[0].value = 0;
1559b8e80941Smrg   out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
1560b8e80941Smrg   out[0].decl.NrTokens = 3;
1561b8e80941Smrg   out[0].decl.File = TGSI_FILE_HW_ATOMIC;
1562b8e80941Smrg   out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW;
1563b8e80941Smrg   out[0].decl.Dimension = 1;
1564b8e80941Smrg   out[0].decl.Array = array_id != 0;
1565b8e80941Smrg
1566b8e80941Smrg   out[1].value = 0;
1567b8e80941Smrg   out[1].decl_range.First = first;
1568b8e80941Smrg   out[1].decl_range.Last = last;
1569b8e80941Smrg
1570b8e80941Smrg   out[2].value = 0;
1571b8e80941Smrg   out[2].decl_dim.Index2D = index2D;
1572b8e80941Smrg
1573b8e80941Smrg   if (array_id) {
1574b8e80941Smrg      out[3].value = 0;
1575b8e80941Smrg      out[3].array.ArrayID = array_id;
1576b8e80941Smrg   }
1577b8e80941Smrg}
1578848b8605Smrg
1579848b8605Smrgstatic void
1580848b8605Smrgemit_decl_fs(struct ureg_program *ureg,
1581848b8605Smrg             unsigned file,
1582b8e80941Smrg             unsigned first,
1583b8e80941Smrg             unsigned last,
1584b8e80941Smrg             enum tgsi_semantic semantic_name,
1585848b8605Smrg             unsigned semantic_index,
1586b8e80941Smrg             enum tgsi_interpolate_mode interpolate,
1587848b8605Smrg             unsigned cylindrical_wrap,
1588b8e80941Smrg             enum tgsi_interpolate_loc interpolate_location,
1589b8e80941Smrg             unsigned array_id,
1590b8e80941Smrg             unsigned usage_mask)
1591848b8605Smrg{
1592b8e80941Smrg   union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL,
1593b8e80941Smrg                                          array_id ? 5 : 4);
1594848b8605Smrg
1595848b8605Smrg   out[0].value = 0;
1596848b8605Smrg   out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
1597848b8605Smrg   out[0].decl.NrTokens = 4;
1598848b8605Smrg   out[0].decl.File = file;
1599b8e80941Smrg   out[0].decl.UsageMask = usage_mask;
1600848b8605Smrg   out[0].decl.Interpolate = 1;
1601848b8605Smrg   out[0].decl.Semantic = 1;
1602b8e80941Smrg   out[0].decl.Array = array_id != 0;
1603848b8605Smrg
1604848b8605Smrg   out[1].value = 0;
1605b8e80941Smrg   out[1].decl_range.First = first;
1606b8e80941Smrg   out[1].decl_range.Last = last;
1607848b8605Smrg
1608848b8605Smrg   out[2].value = 0;
1609848b8605Smrg   out[2].decl_interp.Interpolate = interpolate;
1610848b8605Smrg   out[2].decl_interp.CylindricalWrap = cylindrical_wrap;
1611848b8605Smrg   out[2].decl_interp.Location = interpolate_location;
1612848b8605Smrg
1613848b8605Smrg   out[3].value = 0;
1614848b8605Smrg   out[3].decl_semantic.Name = semantic_name;
1615848b8605Smrg   out[3].decl_semantic.Index = semantic_index;
1616b8e80941Smrg
1617b8e80941Smrg   if (array_id) {
1618b8e80941Smrg      out[4].value = 0;
1619b8e80941Smrg      out[4].array.ArrayID = array_id;
1620b8e80941Smrg   }
1621848b8605Smrg}
1622848b8605Smrg
1623848b8605Smrgstatic void
1624848b8605Smrgemit_decl_temps( struct ureg_program *ureg,
1625848b8605Smrg                 unsigned first, unsigned last,
1626848b8605Smrg                 boolean local,
1627848b8605Smrg                 unsigned arrayid )
1628848b8605Smrg{
1629848b8605Smrg   union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL,
1630848b8605Smrg                                           arrayid ? 3 : 2 );
1631848b8605Smrg
1632848b8605Smrg   out[0].value = 0;
1633848b8605Smrg   out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
1634848b8605Smrg   out[0].decl.NrTokens = 2;
1635848b8605Smrg   out[0].decl.File = TGSI_FILE_TEMPORARY;
1636848b8605Smrg   out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW;
1637848b8605Smrg   out[0].decl.Local = local;
1638848b8605Smrg
1639848b8605Smrg   out[1].value = 0;
1640848b8605Smrg   out[1].decl_range.First = first;
1641848b8605Smrg   out[1].decl_range.Last = last;
1642848b8605Smrg
1643848b8605Smrg   if (arrayid) {
1644848b8605Smrg      out[0].decl.Array = 1;
1645848b8605Smrg      out[2].value = 0;
1646848b8605Smrg      out[2].array.ArrayID = arrayid;
1647848b8605Smrg   }
1648848b8605Smrg}
1649848b8605Smrg
1650848b8605Smrgstatic void emit_decl_range( struct ureg_program *ureg,
1651848b8605Smrg                             unsigned file,
1652848b8605Smrg                             unsigned first,
1653848b8605Smrg                             unsigned count )
1654848b8605Smrg{
1655848b8605Smrg   union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 2 );
1656848b8605Smrg
1657848b8605Smrg   out[0].value = 0;
1658848b8605Smrg   out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
1659848b8605Smrg   out[0].decl.NrTokens = 2;
1660848b8605Smrg   out[0].decl.File = file;
1661848b8605Smrg   out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW;
1662848b8605Smrg   out[0].decl.Semantic = 0;
1663848b8605Smrg
1664848b8605Smrg   out[1].value = 0;
1665848b8605Smrg   out[1].decl_range.First = first;
1666848b8605Smrg   out[1].decl_range.Last = first + count - 1;
1667848b8605Smrg}
1668848b8605Smrg
1669848b8605Smrgstatic void
1670848b8605Smrgemit_decl_range2D(struct ureg_program *ureg,
1671848b8605Smrg                  unsigned file,
1672848b8605Smrg                  unsigned first,
1673848b8605Smrg                  unsigned last,
1674848b8605Smrg                  unsigned index2D)
1675848b8605Smrg{
1676848b8605Smrg   union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 3);
1677848b8605Smrg
1678848b8605Smrg   out[0].value = 0;
1679848b8605Smrg   out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
1680848b8605Smrg   out[0].decl.NrTokens = 3;
1681848b8605Smrg   out[0].decl.File = file;
1682848b8605Smrg   out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW;
1683848b8605Smrg   out[0].decl.Dimension = 1;
1684848b8605Smrg
1685848b8605Smrg   out[1].value = 0;
1686848b8605Smrg   out[1].decl_range.First = first;
1687848b8605Smrg   out[1].decl_range.Last = last;
1688848b8605Smrg
1689848b8605Smrg   out[2].value = 0;
1690848b8605Smrg   out[2].decl_dim.Index2D = index2D;
1691848b8605Smrg}
1692848b8605Smrg
1693848b8605Smrgstatic void
1694848b8605Smrgemit_decl_sampler_view(struct ureg_program *ureg,
1695848b8605Smrg                       unsigned index,
1696b8e80941Smrg                       enum tgsi_texture_type target,
1697b8e80941Smrg                       enum tgsi_return_type return_type_x,
1698b8e80941Smrg                       enum tgsi_return_type return_type_y,
1699b8e80941Smrg                       enum tgsi_return_type return_type_z,
1700b8e80941Smrg                       enum tgsi_return_type return_type_w )
1701848b8605Smrg{
1702848b8605Smrg   union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 3);
1703848b8605Smrg
1704848b8605Smrg   out[0].value = 0;
1705848b8605Smrg   out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
1706848b8605Smrg   out[0].decl.NrTokens = 3;
1707848b8605Smrg   out[0].decl.File = TGSI_FILE_SAMPLER_VIEW;
1708b8e80941Smrg   out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW;
1709848b8605Smrg
1710848b8605Smrg   out[1].value = 0;
1711848b8605Smrg   out[1].decl_range.First = index;
1712848b8605Smrg   out[1].decl_range.Last = index;
1713848b8605Smrg
1714848b8605Smrg   out[2].value = 0;
1715848b8605Smrg   out[2].decl_sampler_view.Resource    = target;
1716848b8605Smrg   out[2].decl_sampler_view.ReturnTypeX = return_type_x;
1717848b8605Smrg   out[2].decl_sampler_view.ReturnTypeY = return_type_y;
1718848b8605Smrg   out[2].decl_sampler_view.ReturnTypeZ = return_type_z;
1719848b8605Smrg   out[2].decl_sampler_view.ReturnTypeW = return_type_w;
1720848b8605Smrg}
1721848b8605Smrg
1722b8e80941Smrgstatic void
1723b8e80941Smrgemit_decl_image(struct ureg_program *ureg,
1724b8e80941Smrg                unsigned index,
1725b8e80941Smrg                enum tgsi_texture_type target,
1726b8e80941Smrg                enum pipe_format format,
1727b8e80941Smrg                boolean wr,
1728b8e80941Smrg                boolean raw)
1729b8e80941Smrg{
1730b8e80941Smrg   union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 3);
1731b8e80941Smrg
1732b8e80941Smrg   out[0].value = 0;
1733b8e80941Smrg   out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
1734b8e80941Smrg   out[0].decl.NrTokens = 3;
1735b8e80941Smrg   out[0].decl.File = TGSI_FILE_IMAGE;
1736b8e80941Smrg   out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW;
1737b8e80941Smrg
1738b8e80941Smrg   out[1].value = 0;
1739b8e80941Smrg   out[1].decl_range.First = index;
1740b8e80941Smrg   out[1].decl_range.Last = index;
1741b8e80941Smrg
1742b8e80941Smrg   out[2].value = 0;
1743b8e80941Smrg   out[2].decl_image.Resource = target;
1744b8e80941Smrg   out[2].decl_image.Writable = wr;
1745b8e80941Smrg   out[2].decl_image.Raw      = raw;
1746b8e80941Smrg   out[2].decl_image.Format   = format;
1747b8e80941Smrg}
1748b8e80941Smrg
1749b8e80941Smrgstatic void
1750b8e80941Smrgemit_decl_buffer(struct ureg_program *ureg,
1751b8e80941Smrg                 unsigned index,
1752b8e80941Smrg                 bool atomic)
1753b8e80941Smrg{
1754b8e80941Smrg   union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 2);
1755b8e80941Smrg
1756b8e80941Smrg   out[0].value = 0;
1757b8e80941Smrg   out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
1758b8e80941Smrg   out[0].decl.NrTokens = 2;
1759b8e80941Smrg   out[0].decl.File = TGSI_FILE_BUFFER;
1760b8e80941Smrg   out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW;
1761b8e80941Smrg   out[0].decl.Atomic = atomic;
1762b8e80941Smrg
1763b8e80941Smrg   out[1].value = 0;
1764b8e80941Smrg   out[1].decl_range.First = index;
1765b8e80941Smrg   out[1].decl_range.Last = index;
1766b8e80941Smrg}
1767b8e80941Smrg
1768b8e80941Smrgstatic void
1769b8e80941Smrgemit_decl_memory(struct ureg_program *ureg, unsigned memory_type)
1770b8e80941Smrg{
1771b8e80941Smrg   union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 2);
1772b8e80941Smrg
1773b8e80941Smrg   out[0].value = 0;
1774b8e80941Smrg   out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
1775b8e80941Smrg   out[0].decl.NrTokens = 2;
1776b8e80941Smrg   out[0].decl.File = TGSI_FILE_MEMORY;
1777b8e80941Smrg   out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW;
1778b8e80941Smrg   out[0].decl.MemType = memory_type;
1779b8e80941Smrg
1780b8e80941Smrg   out[1].value = 0;
1781b8e80941Smrg   out[1].decl_range.First = memory_type;
1782b8e80941Smrg   out[1].decl_range.Last = memory_type;
1783b8e80941Smrg}
1784b8e80941Smrg
1785848b8605Smrgstatic void
1786848b8605Smrgemit_immediate( struct ureg_program *ureg,
1787848b8605Smrg                const unsigned *v,
1788848b8605Smrg                unsigned type )
1789848b8605Smrg{
1790848b8605Smrg   union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 5 );
1791848b8605Smrg
1792848b8605Smrg   out[0].value = 0;
1793848b8605Smrg   out[0].imm.Type = TGSI_TOKEN_TYPE_IMMEDIATE;
1794848b8605Smrg   out[0].imm.NrTokens = 5;
1795848b8605Smrg   out[0].imm.DataType = type;
1796848b8605Smrg   out[0].imm.Padding = 0;
1797848b8605Smrg
1798848b8605Smrg   out[1].imm_data.Uint = v[0];
1799848b8605Smrg   out[2].imm_data.Uint = v[1];
1800848b8605Smrg   out[3].imm_data.Uint = v[2];
1801848b8605Smrg   out[4].imm_data.Uint = v[3];
1802848b8605Smrg}
1803848b8605Smrg
1804848b8605Smrgstatic void
1805848b8605Smrgemit_property(struct ureg_program *ureg,
1806848b8605Smrg              unsigned name,
1807848b8605Smrg              unsigned data)
1808848b8605Smrg{
1809848b8605Smrg   union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 2);
1810848b8605Smrg
1811848b8605Smrg   out[0].value = 0;
1812848b8605Smrg   out[0].prop.Type = TGSI_TOKEN_TYPE_PROPERTY;
1813848b8605Smrg   out[0].prop.NrTokens = 2;
1814848b8605Smrg   out[0].prop.PropertyName = name;
1815848b8605Smrg
1816848b8605Smrg   out[1].prop_data.Data = data;
1817848b8605Smrg}
1818848b8605Smrg
1819848b8605Smrg
1820848b8605Smrgstatic void emit_decls( struct ureg_program *ureg )
1821848b8605Smrg{
1822b8e80941Smrg   unsigned i,j;
1823848b8605Smrg
1824b8e80941Smrg   for (i = 0; i < ARRAY_SIZE(ureg->properties); i++)
1825b8e80941Smrg      if (ureg->properties[i] != ~0u)
1826b8e80941Smrg         emit_property(ureg, i, ureg->properties[i]);
1827848b8605Smrg
1828b8e80941Smrg   if (ureg->processor == PIPE_SHADER_VERTEX) {
1829b8e80941Smrg      for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
1830b8e80941Smrg         if (ureg->vs_inputs[i/32] & (1u << (i%32))) {
1831848b8605Smrg            emit_decl_range( ureg, TGSI_FILE_INPUT, i, 1 );
1832848b8605Smrg         }
1833848b8605Smrg      }
1834b8e80941Smrg   } else if (ureg->processor == PIPE_SHADER_FRAGMENT) {
1835b8e80941Smrg      if (ureg->supports_any_inout_decl_range) {
1836b8e80941Smrg         for (i = 0; i < ureg->nr_inputs; i++) {
1837b8e80941Smrg            emit_decl_fs(ureg,
1838b8e80941Smrg                         TGSI_FILE_INPUT,
1839b8e80941Smrg                         ureg->input[i].first,
1840b8e80941Smrg                         ureg->input[i].last,
1841b8e80941Smrg                         ureg->input[i].semantic_name,
1842b8e80941Smrg                         ureg->input[i].semantic_index,
1843b8e80941Smrg                         ureg->input[i].interp,
1844b8e80941Smrg                         ureg->input[i].cylindrical_wrap,
1845b8e80941Smrg                         ureg->input[i].interp_location,
1846b8e80941Smrg                         ureg->input[i].array_id,
1847b8e80941Smrg                         ureg->input[i].usage_mask);
1848b8e80941Smrg         }
1849848b8605Smrg      }
1850b8e80941Smrg      else {
1851b8e80941Smrg         for (i = 0; i < ureg->nr_inputs; i++) {
1852b8e80941Smrg            for (j = ureg->input[i].first; j <= ureg->input[i].last; j++) {
1853b8e80941Smrg               emit_decl_fs(ureg,
1854848b8605Smrg                            TGSI_FILE_INPUT,
1855b8e80941Smrg                            j, j,
1856b8e80941Smrg                            ureg->input[i].semantic_name,
1857b8e80941Smrg                            ureg->input[i].semantic_index +
1858b8e80941Smrg                            (j - ureg->input[i].first),
1859b8e80941Smrg                            ureg->input[i].interp,
1860b8e80941Smrg                            ureg->input[i].cylindrical_wrap,
1861b8e80941Smrg                            ureg->input[i].interp_location, 0,
1862b8e80941Smrg                            ureg->input[i].usage_mask);
1863b8e80941Smrg            }
1864b8e80941Smrg         }
1865b8e80941Smrg      }
1866b8e80941Smrg   } else {
1867b8e80941Smrg      if (ureg->supports_any_inout_decl_range) {
1868b8e80941Smrg         for (i = 0; i < ureg->nr_inputs; i++) {
1869b8e80941Smrg            emit_decl_semantic(ureg,
1870b8e80941Smrg                               TGSI_FILE_INPUT,
1871b8e80941Smrg                               ureg->input[i].first,
1872b8e80941Smrg                               ureg->input[i].last,
1873b8e80941Smrg                               ureg->input[i].semantic_name,
1874b8e80941Smrg                               ureg->input[i].semantic_index,
1875b8e80941Smrg                               0,
1876b8e80941Smrg                               TGSI_WRITEMASK_XYZW,
1877b8e80941Smrg                               ureg->input[i].array_id,
1878b8e80941Smrg                               FALSE);
1879b8e80941Smrg         }
1880b8e80941Smrg      }
1881b8e80941Smrg      else {
1882b8e80941Smrg         for (i = 0; i < ureg->nr_inputs; i++) {
1883b8e80941Smrg            for (j = ureg->input[i].first; j <= ureg->input[i].last; j++) {
1884b8e80941Smrg               emit_decl_semantic(ureg,
1885b8e80941Smrg                                  TGSI_FILE_INPUT,
1886b8e80941Smrg                                  j, j,
1887b8e80941Smrg                                  ureg->input[i].semantic_name,
1888b8e80941Smrg                                  ureg->input[i].semantic_index +
1889b8e80941Smrg                                  (j - ureg->input[i].first),
1890b8e80941Smrg                                  0,
1891b8e80941Smrg                                  TGSI_WRITEMASK_XYZW, 0, FALSE);
1892b8e80941Smrg            }
1893b8e80941Smrg         }
1894848b8605Smrg      }
1895848b8605Smrg   }
1896848b8605Smrg
1897848b8605Smrg   for (i = 0; i < ureg->nr_system_values; i++) {
1898848b8605Smrg      emit_decl_semantic(ureg,
1899848b8605Smrg                         TGSI_FILE_SYSTEM_VALUE,
1900b8e80941Smrg                         i,
1901b8e80941Smrg                         i,
1902848b8605Smrg                         ureg->system_value[i].semantic_name,
1903848b8605Smrg                         ureg->system_value[i].semantic_index,
1904b8e80941Smrg                         0,
1905b8e80941Smrg                         TGSI_WRITEMASK_XYZW, 0, FALSE);
1906848b8605Smrg   }
1907848b8605Smrg
1908b8e80941Smrg   if (ureg->supports_any_inout_decl_range) {
1909b8e80941Smrg      for (i = 0; i < ureg->nr_outputs; i++) {
1910b8e80941Smrg         emit_decl_semantic(ureg,
1911b8e80941Smrg                            TGSI_FILE_OUTPUT,
1912b8e80941Smrg                            ureg->output[i].first,
1913b8e80941Smrg                            ureg->output[i].last,
1914b8e80941Smrg                            ureg->output[i].semantic_name,
1915b8e80941Smrg                            ureg->output[i].semantic_index,
1916b8e80941Smrg                            ureg->output[i].streams,
1917b8e80941Smrg                            ureg->output[i].usage_mask,
1918b8e80941Smrg                            ureg->output[i].array_id,
1919b8e80941Smrg                            ureg->output[i].invariant);
1920b8e80941Smrg      }
1921b8e80941Smrg   }
1922b8e80941Smrg   else {
1923b8e80941Smrg      for (i = 0; i < ureg->nr_outputs; i++) {
1924b8e80941Smrg         for (j = ureg->output[i].first; j <= ureg->output[i].last; j++) {
1925b8e80941Smrg            emit_decl_semantic(ureg,
1926b8e80941Smrg                               TGSI_FILE_OUTPUT,
1927b8e80941Smrg                               j, j,
1928b8e80941Smrg                               ureg->output[i].semantic_name,
1929b8e80941Smrg                               ureg->output[i].semantic_index +
1930b8e80941Smrg                               (j - ureg->output[i].first),
1931b8e80941Smrg                               ureg->output[i].streams,
1932b8e80941Smrg                               ureg->output[i].usage_mask,
1933b8e80941Smrg                               0,
1934b8e80941Smrg                               ureg->output[i].invariant);
1935b8e80941Smrg         }
1936b8e80941Smrg      }
1937848b8605Smrg   }
1938848b8605Smrg
1939848b8605Smrg   for (i = 0; i < ureg->nr_samplers; i++) {
1940b8e80941Smrg      emit_decl_range( ureg,
1941848b8605Smrg                       TGSI_FILE_SAMPLER,
1942848b8605Smrg                       ureg->sampler[i].Index, 1 );
1943848b8605Smrg   }
1944848b8605Smrg
1945848b8605Smrg   for (i = 0; i < ureg->nr_sampler_views; i++) {
1946848b8605Smrg      emit_decl_sampler_view(ureg,
1947848b8605Smrg                             ureg->sampler_view[i].index,
1948848b8605Smrg                             ureg->sampler_view[i].target,
1949848b8605Smrg                             ureg->sampler_view[i].return_type_x,
1950848b8605Smrg                             ureg->sampler_view[i].return_type_y,
1951848b8605Smrg                             ureg->sampler_view[i].return_type_z,
1952848b8605Smrg                             ureg->sampler_view[i].return_type_w);
1953848b8605Smrg   }
1954848b8605Smrg
1955b8e80941Smrg   for (i = 0; i < ureg->nr_images; i++) {
1956b8e80941Smrg      emit_decl_image(ureg,
1957b8e80941Smrg                      ureg->image[i].index,
1958b8e80941Smrg                      ureg->image[i].target,
1959b8e80941Smrg                      ureg->image[i].format,
1960b8e80941Smrg                      ureg->image[i].wr,
1961b8e80941Smrg                      ureg->image[i].raw);
1962b8e80941Smrg   }
1963b8e80941Smrg
1964b8e80941Smrg   for (i = 0; i < ureg->nr_buffers; i++) {
1965b8e80941Smrg      emit_decl_buffer(ureg, ureg->buffer[i].index, ureg->buffer[i].atomic);
1966b8e80941Smrg   }
1967b8e80941Smrg
1968b8e80941Smrg   for (i = 0; i < TGSI_MEMORY_TYPE_COUNT; i++) {
1969b8e80941Smrg      if (ureg->use_memory[i])
1970b8e80941Smrg         emit_decl_memory(ureg, i);
1971848b8605Smrg   }
1972848b8605Smrg
1973848b8605Smrg   for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
1974b8e80941Smrg      struct const_decl *decl = &ureg->const_decls[i];
1975848b8605Smrg
1976848b8605Smrg      if (decl->nr_constant_ranges) {
1977848b8605Smrg         uint j;
1978848b8605Smrg
1979848b8605Smrg         for (j = 0; j < decl->nr_constant_ranges; j++) {
1980848b8605Smrg            emit_decl_range2D(ureg,
1981848b8605Smrg                              TGSI_FILE_CONSTANT,
1982848b8605Smrg                              decl->constant_range[j].first,
1983848b8605Smrg                              decl->constant_range[j].last,
1984848b8605Smrg                              i);
1985848b8605Smrg         }
1986848b8605Smrg      }
1987848b8605Smrg   }
1988848b8605Smrg
1989b8e80941Smrg   for (i = 0; i < PIPE_MAX_HW_ATOMIC_BUFFERS; i++) {
1990b8e80941Smrg      struct hw_atomic_decl *decl = &ureg->hw_atomic_decls[i];
1991b8e80941Smrg
1992b8e80941Smrg      if (decl->nr_hw_atomic_ranges) {
1993b8e80941Smrg         uint j;
1994b8e80941Smrg
1995b8e80941Smrg         for (j = 0; j < decl->nr_hw_atomic_ranges; j++) {
1996b8e80941Smrg            emit_decl_atomic_2d(ureg,
1997b8e80941Smrg                                decl->hw_atomic_range[j].first,
1998b8e80941Smrg                                decl->hw_atomic_range[j].last,
1999b8e80941Smrg                                i,
2000b8e80941Smrg                                decl->hw_atomic_range[j].array_id);
2001b8e80941Smrg         }
2002b8e80941Smrg      }
2003b8e80941Smrg   }
2004b8e80941Smrg
2005848b8605Smrg   if (ureg->nr_temps) {
2006848b8605Smrg      unsigned array = 0;
2007848b8605Smrg      for (i = 0; i < ureg->nr_temps;) {
2008848b8605Smrg         boolean local = util_bitmask_get(ureg->local_temps, i);
2009848b8605Smrg         unsigned first = i;
2010848b8605Smrg         i = util_bitmask_get_next_index(ureg->decl_temps, i + 1);
2011848b8605Smrg         if (i == UTIL_BITMASK_INVALID_INDEX)
2012848b8605Smrg            i = ureg->nr_temps;
2013848b8605Smrg
2014848b8605Smrg         if (array < ureg->nr_array_temps && ureg->array_temps[array] == first)
2015848b8605Smrg            emit_decl_temps( ureg, first, i - 1, local, ++array );
2016848b8605Smrg         else
2017848b8605Smrg            emit_decl_temps( ureg, first, i - 1, local, 0 );
2018848b8605Smrg      }
2019848b8605Smrg   }
2020848b8605Smrg
2021848b8605Smrg   if (ureg->nr_addrs) {
2022848b8605Smrg      emit_decl_range( ureg,
2023848b8605Smrg                       TGSI_FILE_ADDRESS,
2024848b8605Smrg                       0, ureg->nr_addrs );
2025848b8605Smrg   }
2026848b8605Smrg
2027848b8605Smrg   for (i = 0; i < ureg->nr_immediates; i++) {
2028848b8605Smrg      emit_immediate( ureg,
2029848b8605Smrg                      ureg->immediate[i].value.u,
2030848b8605Smrg                      ureg->immediate[i].type );
2031848b8605Smrg   }
2032848b8605Smrg}
2033848b8605Smrg
2034848b8605Smrg/* Append the instruction tokens onto the declarations to build a
2035848b8605Smrg * contiguous stream suitable to send to the driver.
2036848b8605Smrg */
2037848b8605Smrgstatic void copy_instructions( struct ureg_program *ureg )
2038848b8605Smrg{
2039848b8605Smrg   unsigned nr_tokens = ureg->domain[DOMAIN_INSN].count;
2040b8e80941Smrg   union tgsi_any_token *out = get_tokens( ureg,
2041b8e80941Smrg                                           DOMAIN_DECL,
2042848b8605Smrg                                           nr_tokens );
2043848b8605Smrg
2044b8e80941Smrg   memcpy(out,
2045b8e80941Smrg          ureg->domain[DOMAIN_INSN].tokens,
2046848b8605Smrg          nr_tokens * sizeof out[0] );
2047848b8605Smrg}
2048848b8605Smrg
2049848b8605Smrg
2050848b8605Smrgstatic void
2051848b8605Smrgfixup_header_size(struct ureg_program *ureg)
2052848b8605Smrg{
2053848b8605Smrg   union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_DECL, 0 );
2054848b8605Smrg
2055848b8605Smrg   out->header.BodySize = ureg->domain[DOMAIN_DECL].count - 2;
2056848b8605Smrg}
2057848b8605Smrg
2058848b8605Smrg
2059848b8605Smrgstatic void
2060848b8605Smrgemit_header( struct ureg_program *ureg )
2061848b8605Smrg{
2062848b8605Smrg   union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 2 );
2063848b8605Smrg
2064848b8605Smrg   out[0].header.HeaderSize = 2;
2065848b8605Smrg   out[0].header.BodySize = 0;
2066848b8605Smrg
2067848b8605Smrg   out[1].processor.Processor = ureg->processor;
2068848b8605Smrg   out[1].processor.Padding = 0;
2069848b8605Smrg}
2070848b8605Smrg
2071848b8605Smrg
2072848b8605Smrgconst struct tgsi_token *ureg_finalize( struct ureg_program *ureg )
2073848b8605Smrg{
2074848b8605Smrg   const struct tgsi_token *tokens;
2075848b8605Smrg
2076b8e80941Smrg   switch (ureg->processor) {
2077b8e80941Smrg   case PIPE_SHADER_VERTEX:
2078b8e80941Smrg   case PIPE_SHADER_TESS_EVAL:
2079b8e80941Smrg      ureg_property(ureg, TGSI_PROPERTY_NEXT_SHADER,
2080b8e80941Smrg                    ureg->next_shader_processor == -1 ?
2081b8e80941Smrg                       PIPE_SHADER_FRAGMENT :
2082b8e80941Smrg                       ureg->next_shader_processor);
2083b8e80941Smrg      break;
2084b8e80941Smrg   default:
2085b8e80941Smrg      ; /* nothing */
2086b8e80941Smrg   }
2087b8e80941Smrg
2088848b8605Smrg   emit_header( ureg );
2089848b8605Smrg   emit_decls( ureg );
2090848b8605Smrg   copy_instructions( ureg );
2091848b8605Smrg   fixup_header_size( ureg );
2092b8e80941Smrg
2093848b8605Smrg   if (ureg->domain[0].tokens == error_tokens ||
2094848b8605Smrg       ureg->domain[1].tokens == error_tokens) {
2095848b8605Smrg      debug_printf("%s: error in generated shader\n", __FUNCTION__);
2096848b8605Smrg      assert(0);
2097848b8605Smrg      return NULL;
2098848b8605Smrg   }
2099848b8605Smrg
2100848b8605Smrg   tokens = &ureg->domain[DOMAIN_DECL].tokens[0].token;
2101848b8605Smrg
2102848b8605Smrg   if (0) {
2103b8e80941Smrg      debug_printf("%s: emitted shader %d tokens:\n", __FUNCTION__,
2104848b8605Smrg                   ureg->domain[DOMAIN_DECL].count);
2105848b8605Smrg      tgsi_dump( tokens, 0 );
2106848b8605Smrg   }
2107848b8605Smrg
2108848b8605Smrg#if DEBUG
2109b8e80941Smrg   /* tgsi_sanity doesn't seem to return if there are too many constants. */
2110b8e80941Smrg   bool too_many_constants = false;
2111b8e80941Smrg   for (unsigned i = 0; i < ARRAY_SIZE(ureg->const_decls); i++) {
2112b8e80941Smrg      for (unsigned j = 0; j < ureg->const_decls[i].nr_constant_ranges; j++) {
2113b8e80941Smrg         if (ureg->const_decls[i].constant_range[j].last > 4096) {
2114b8e80941Smrg            too_many_constants = true;
2115b8e80941Smrg            break;
2116b8e80941Smrg         }
2117b8e80941Smrg      }
2118b8e80941Smrg   }
2119b8e80941Smrg
2120b8e80941Smrg   if (tokens && !too_many_constants && !tgsi_sanity_check(tokens)) {
2121848b8605Smrg      debug_printf("tgsi_ureg.c, sanity check failed on generated tokens:\n");
2122848b8605Smrg      tgsi_dump(tokens, 0);
2123848b8605Smrg      assert(0);
2124848b8605Smrg   }
2125848b8605Smrg#endif
2126848b8605Smrg
2127b8e80941Smrg
2128848b8605Smrg   return tokens;
2129848b8605Smrg}
2130848b8605Smrg
2131848b8605Smrg
2132848b8605Smrgvoid *ureg_create_shader( struct ureg_program *ureg,
2133848b8605Smrg                          struct pipe_context *pipe,
2134848b8605Smrg                          const struct pipe_stream_output_info *so )
2135848b8605Smrg{
2136848b8605Smrg   struct pipe_shader_state state;
2137848b8605Smrg
2138b8e80941Smrg   pipe_shader_state_from_tgsi(&state, ureg_finalize(ureg));
2139848b8605Smrg   if(!state.tokens)
2140848b8605Smrg      return NULL;
2141848b8605Smrg
2142848b8605Smrg   if (so)
2143848b8605Smrg      state.stream_output = *so;
2144848b8605Smrg
2145b8e80941Smrg   switch (ureg->processor) {
2146b8e80941Smrg   case PIPE_SHADER_VERTEX:
2147b8e80941Smrg      return pipe->create_vs_state(pipe, &state);
2148b8e80941Smrg   case PIPE_SHADER_TESS_CTRL:
2149b8e80941Smrg      return pipe->create_tcs_state(pipe, &state);
2150b8e80941Smrg   case PIPE_SHADER_TESS_EVAL:
2151b8e80941Smrg      return pipe->create_tes_state(pipe, &state);
2152b8e80941Smrg   case PIPE_SHADER_GEOMETRY:
2153b8e80941Smrg      return pipe->create_gs_state(pipe, &state);
2154b8e80941Smrg   case PIPE_SHADER_FRAGMENT:
2155b8e80941Smrg      return pipe->create_fs_state(pipe, &state);
2156b8e80941Smrg   default:
2157b8e80941Smrg      return NULL;
2158b8e80941Smrg   }
2159848b8605Smrg}
2160848b8605Smrg
2161848b8605Smrg
2162848b8605Smrgconst struct tgsi_token *ureg_get_tokens( struct ureg_program *ureg,
2163848b8605Smrg                                          unsigned *nr_tokens )
2164848b8605Smrg{
2165848b8605Smrg   const struct tgsi_token *tokens;
2166848b8605Smrg
2167848b8605Smrg   ureg_finalize(ureg);
2168848b8605Smrg
2169848b8605Smrg   tokens = &ureg->domain[DOMAIN_DECL].tokens[0].token;
2170848b8605Smrg
2171b8e80941Smrg   if (nr_tokens)
2172b8e80941Smrg      *nr_tokens = ureg->domain[DOMAIN_DECL].count;
2173848b8605Smrg
2174848b8605Smrg   ureg->domain[DOMAIN_DECL].tokens = 0;
2175848b8605Smrg   ureg->domain[DOMAIN_DECL].size = 0;
2176848b8605Smrg   ureg->domain[DOMAIN_DECL].order = 0;
2177848b8605Smrg   ureg->domain[DOMAIN_DECL].count = 0;
2178848b8605Smrg
2179848b8605Smrg   return tokens;
2180848b8605Smrg}
2181848b8605Smrg
2182848b8605Smrg
2183848b8605Smrgvoid ureg_free_tokens( const struct tgsi_token *tokens )
2184848b8605Smrg{
2185848b8605Smrg   FREE((struct tgsi_token *)tokens);
2186848b8605Smrg}
2187848b8605Smrg
2188848b8605Smrg
2189b8e80941Smrgstruct ureg_program *
2190b8e80941Smrgureg_create(enum pipe_shader_type processor)
2191848b8605Smrg{
2192b8e80941Smrg   return ureg_create_with_screen(processor, NULL);
2193b8e80941Smrg}
2194b8e80941Smrg
2195b8e80941Smrg
2196b8e80941Smrgstruct ureg_program *
2197b8e80941Smrgureg_create_with_screen(enum pipe_shader_type processor,
2198b8e80941Smrg                        struct pipe_screen *screen)
2199b8e80941Smrg{
2200b8e80941Smrg   uint i;
2201848b8605Smrg   struct ureg_program *ureg = CALLOC_STRUCT( ureg_program );
2202b8e80941Smrg   if (!ureg)
2203848b8605Smrg      goto no_ureg;
2204848b8605Smrg
2205848b8605Smrg   ureg->processor = processor;
2206b8e80941Smrg   ureg->supports_any_inout_decl_range =
2207b8e80941Smrg      screen &&
2208b8e80941Smrg      screen->get_shader_param(screen, processor,
2209b8e80941Smrg                               PIPE_SHADER_CAP_TGSI_ANY_INOUT_DECL_RANGE) != 0;
2210b8e80941Smrg   ureg->next_shader_processor = -1;
2211b8e80941Smrg
2212b8e80941Smrg   for (i = 0; i < ARRAY_SIZE(ureg->properties); i++)
2213b8e80941Smrg      ureg->properties[i] = ~0;
2214848b8605Smrg
2215848b8605Smrg   ureg->free_temps = util_bitmask_create();
2216848b8605Smrg   if (ureg->free_temps == NULL)
2217848b8605Smrg      goto no_free_temps;
2218848b8605Smrg
2219848b8605Smrg   ureg->local_temps = util_bitmask_create();
2220848b8605Smrg   if (ureg->local_temps == NULL)
2221848b8605Smrg      goto no_local_temps;
2222848b8605Smrg
2223848b8605Smrg   ureg->decl_temps = util_bitmask_create();
2224848b8605Smrg   if (ureg->decl_temps == NULL)
2225848b8605Smrg      goto no_decl_temps;
2226848b8605Smrg
2227848b8605Smrg   return ureg;
2228848b8605Smrg
2229848b8605Smrgno_decl_temps:
2230848b8605Smrg   util_bitmask_destroy(ureg->local_temps);
2231848b8605Smrgno_local_temps:
2232848b8605Smrg   util_bitmask_destroy(ureg->free_temps);
2233848b8605Smrgno_free_temps:
2234848b8605Smrg   FREE(ureg);
2235848b8605Smrgno_ureg:
2236848b8605Smrg   return NULL;
2237848b8605Smrg}
2238848b8605Smrg
2239848b8605Smrg
2240b8e80941Smrgvoid
2241b8e80941Smrgureg_set_next_shader_processor(struct ureg_program *ureg, unsigned processor)
2242b8e80941Smrg{
2243b8e80941Smrg   ureg->next_shader_processor = processor;
2244b8e80941Smrg}
2245b8e80941Smrg
2246b8e80941Smrg
2247848b8605Smrgunsigned
2248848b8605Smrgureg_get_nr_outputs( const struct ureg_program *ureg )
2249848b8605Smrg{
2250848b8605Smrg   if (!ureg)
2251848b8605Smrg      return 0;
2252848b8605Smrg   return ureg->nr_outputs;
2253848b8605Smrg}
2254848b8605Smrg
2255848b8605Smrg
2256848b8605Smrgvoid ureg_destroy( struct ureg_program *ureg )
2257848b8605Smrg{
2258848b8605Smrg   unsigned i;
2259848b8605Smrg
2260b8e80941Smrg   for (i = 0; i < ARRAY_SIZE(ureg->domain); i++) {
2261b8e80941Smrg      if (ureg->domain[i].tokens &&
2262848b8605Smrg          ureg->domain[i].tokens != error_tokens)
2263848b8605Smrg         FREE(ureg->domain[i].tokens);
2264848b8605Smrg   }
2265848b8605Smrg
2266848b8605Smrg   util_bitmask_destroy(ureg->free_temps);
2267848b8605Smrg   util_bitmask_destroy(ureg->local_temps);
2268848b8605Smrg   util_bitmask_destroy(ureg->decl_temps);
2269848b8605Smrg
2270848b8605Smrg   FREE(ureg);
2271848b8605Smrg}
2272