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