1b8e80941Smrg/*
2b8e80941Smrg * Copyright © 2014 Intel Corporation
3b8e80941Smrg *
4b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5b8e80941Smrg * copy of this software and associated documentation files (the "Software"),
6b8e80941Smrg * to deal in the Software without restriction, including without limitation
7b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the
9b8e80941Smrg * Software is furnished to do so, subject to the following conditions:
10b8e80941Smrg *
11b8e80941Smrg * The above copyright notice and this permission notice (including the next
12b8e80941Smrg * paragraph) shall be included in all copies or substantial portions of the
13b8e80941Smrg * Software.
14b8e80941Smrg *
15b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20b8e80941Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21b8e80941Smrg * IN THE SOFTWARE.
22b8e80941Smrg *
23b8e80941Smrg * Authors:
24b8e80941Smrg *    Connor Abbott (cwabbott0@gmail.com)
25b8e80941Smrg *
26b8e80941Smrg */
27b8e80941Smrg
28b8e80941Smrg#include "nir.h"
29b8e80941Smrg#include "compiler/shader_enums.h"
30b8e80941Smrg#include "util/half_float.h"
31b8e80941Smrg#include "vulkan/vulkan_core.h"
32b8e80941Smrg#include <stdio.h>
33b8e80941Smrg#include <stdlib.h>
34b8e80941Smrg#include <inttypes.h> /* for PRIx64 macro */
35b8e80941Smrg
36b8e80941Smrgstatic void
37b8e80941Smrgprint_tabs(unsigned num_tabs, FILE *fp)
38b8e80941Smrg{
39b8e80941Smrg   for (unsigned i = 0; i < num_tabs; i++)
40b8e80941Smrg      fprintf(fp, "\t");
41b8e80941Smrg}
42b8e80941Smrg
43b8e80941Smrgtypedef struct {
44b8e80941Smrg   FILE *fp;
45b8e80941Smrg   nir_shader *shader;
46b8e80941Smrg   /** map from nir_variable -> printable name */
47b8e80941Smrg   struct hash_table *ht;
48b8e80941Smrg
49b8e80941Smrg   /** set of names used so far for nir_variables */
50b8e80941Smrg   struct set *syms;
51b8e80941Smrg
52b8e80941Smrg   /* an index used to make new non-conflicting names */
53b8e80941Smrg   unsigned index;
54b8e80941Smrg
55b8e80941Smrg   /**
56b8e80941Smrg    * Optional table of annotations mapping nir object
57b8e80941Smrg    * (such as instr or var) to message to print.
58b8e80941Smrg    */
59b8e80941Smrg   struct hash_table *annotations;
60b8e80941Smrg} print_state;
61b8e80941Smrg
62b8e80941Smrgstatic void
63b8e80941Smrgprint_annotation(print_state *state, void *obj)
64b8e80941Smrg{
65b8e80941Smrg   if (!state->annotations)
66b8e80941Smrg      return;
67b8e80941Smrg
68b8e80941Smrg   struct hash_entry *entry = _mesa_hash_table_search(state->annotations, obj);
69b8e80941Smrg   if (!entry)
70b8e80941Smrg      return;
71b8e80941Smrg
72b8e80941Smrg   const char *note = entry->data;
73b8e80941Smrg   _mesa_hash_table_remove(state->annotations, entry);
74b8e80941Smrg
75b8e80941Smrg   fprintf(stderr, "%s\n\n", note);
76b8e80941Smrg}
77b8e80941Smrg
78b8e80941Smrgstatic void
79b8e80941Smrgprint_register(nir_register *reg, print_state *state)
80b8e80941Smrg{
81b8e80941Smrg   FILE *fp = state->fp;
82b8e80941Smrg   if (reg->name != NULL)
83b8e80941Smrg      fprintf(fp, "/* %s */ ", reg->name);
84b8e80941Smrg   fprintf(fp, "r%u", reg->index);
85b8e80941Smrg}
86b8e80941Smrg
87b8e80941Smrgstatic const char *sizes[] = { "error", "vec1", "vec2", "vec3", "vec4",
88b8e80941Smrg                               "error", "error", "error", "vec8",
89b8e80941Smrg                               "error", "error", "error", "error",
90b8e80941Smrg                               "error", "error", "error", "vec16"};
91b8e80941Smrg
92b8e80941Smrgstatic void
93b8e80941Smrgprint_register_decl(nir_register *reg, print_state *state)
94b8e80941Smrg{
95b8e80941Smrg   FILE *fp = state->fp;
96b8e80941Smrg   fprintf(fp, "decl_reg %s %u ", sizes[reg->num_components], reg->bit_size);
97b8e80941Smrg   print_register(reg, state);
98b8e80941Smrg   if (reg->num_array_elems != 0)
99b8e80941Smrg      fprintf(fp, "[%u]", reg->num_array_elems);
100b8e80941Smrg   fprintf(fp, "\n");
101b8e80941Smrg}
102b8e80941Smrg
103b8e80941Smrgstatic void
104b8e80941Smrgprint_ssa_def(nir_ssa_def *def, print_state *state)
105b8e80941Smrg{
106b8e80941Smrg   FILE *fp = state->fp;
107b8e80941Smrg   if (def->name != NULL)
108b8e80941Smrg      fprintf(fp, "/* %s */ ", def->name);
109b8e80941Smrg   fprintf(fp, "%s %u ssa_%u", sizes[def->num_components], def->bit_size,
110b8e80941Smrg           def->index);
111b8e80941Smrg}
112b8e80941Smrg
113b8e80941Smrgstatic void
114b8e80941Smrgprint_ssa_use(nir_ssa_def *def, print_state *state)
115b8e80941Smrg{
116b8e80941Smrg   FILE *fp = state->fp;
117b8e80941Smrg   if (def->name != NULL)
118b8e80941Smrg      fprintf(fp, "/* %s */ ", def->name);
119b8e80941Smrg   fprintf(fp, "ssa_%u", def->index);
120b8e80941Smrg}
121b8e80941Smrg
122b8e80941Smrgstatic void print_src(const nir_src *src, print_state *state);
123b8e80941Smrg
124b8e80941Smrgstatic void
125b8e80941Smrgprint_reg_src(const nir_reg_src *src, print_state *state)
126b8e80941Smrg{
127b8e80941Smrg   FILE *fp = state->fp;
128b8e80941Smrg   print_register(src->reg, state);
129b8e80941Smrg   if (src->reg->num_array_elems != 0) {
130b8e80941Smrg      fprintf(fp, "[%u", src->base_offset);
131b8e80941Smrg      if (src->indirect != NULL) {
132b8e80941Smrg         fprintf(fp, " + ");
133b8e80941Smrg         print_src(src->indirect, state);
134b8e80941Smrg      }
135b8e80941Smrg      fprintf(fp, "]");
136b8e80941Smrg   }
137b8e80941Smrg}
138b8e80941Smrg
139b8e80941Smrgstatic void
140b8e80941Smrgprint_reg_dest(nir_reg_dest *dest, print_state *state)
141b8e80941Smrg{
142b8e80941Smrg   FILE *fp = state->fp;
143b8e80941Smrg   print_register(dest->reg, state);
144b8e80941Smrg   if (dest->reg->num_array_elems != 0) {
145b8e80941Smrg      fprintf(fp, "[%u", dest->base_offset);
146b8e80941Smrg      if (dest->indirect != NULL) {
147b8e80941Smrg         fprintf(fp, " + ");
148b8e80941Smrg         print_src(dest->indirect, state);
149b8e80941Smrg      }
150b8e80941Smrg      fprintf(fp, "]");
151b8e80941Smrg   }
152b8e80941Smrg}
153b8e80941Smrg
154b8e80941Smrgstatic void
155b8e80941Smrgprint_src(const nir_src *src, print_state *state)
156b8e80941Smrg{
157b8e80941Smrg   if (src->is_ssa)
158b8e80941Smrg      print_ssa_use(src->ssa, state);
159b8e80941Smrg   else
160b8e80941Smrg      print_reg_src(&src->reg, state);
161b8e80941Smrg}
162b8e80941Smrg
163b8e80941Smrgstatic void
164b8e80941Smrgprint_dest(nir_dest *dest, print_state *state)
165b8e80941Smrg{
166b8e80941Smrg   if (dest->is_ssa)
167b8e80941Smrg      print_ssa_def(&dest->ssa, state);
168b8e80941Smrg   else
169b8e80941Smrg      print_reg_dest(&dest->reg, state);
170b8e80941Smrg}
171b8e80941Smrg
172b8e80941Smrgstatic void
173b8e80941Smrgprint_alu_src(nir_alu_instr *instr, unsigned src, print_state *state)
174b8e80941Smrg{
175b8e80941Smrg   FILE *fp = state->fp;
176b8e80941Smrg
177b8e80941Smrg   if (instr->src[src].negate)
178b8e80941Smrg      fprintf(fp, "-");
179b8e80941Smrg   if (instr->src[src].abs)
180b8e80941Smrg      fprintf(fp, "abs(");
181b8e80941Smrg
182b8e80941Smrg   print_src(&instr->src[src].src, state);
183b8e80941Smrg
184b8e80941Smrg   bool print_swizzle = false;
185b8e80941Smrg   nir_component_mask_t used_channels = 0;
186b8e80941Smrg
187b8e80941Smrg   for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++) {
188b8e80941Smrg      if (!nir_alu_instr_channel_used(instr, src, i))
189b8e80941Smrg         continue;
190b8e80941Smrg
191b8e80941Smrg      used_channels++;
192b8e80941Smrg
193b8e80941Smrg      if (instr->src[src].swizzle[i] != i) {
194b8e80941Smrg         print_swizzle = true;
195b8e80941Smrg         break;
196b8e80941Smrg      }
197b8e80941Smrg   }
198b8e80941Smrg
199b8e80941Smrg   unsigned live_channels = nir_src_num_components(instr->src[src].src);
200b8e80941Smrg
201b8e80941Smrg   if (print_swizzle || used_channels != live_channels) {
202b8e80941Smrg      fprintf(fp, ".");
203b8e80941Smrg      for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++) {
204b8e80941Smrg         if (!nir_alu_instr_channel_used(instr, src, i))
205b8e80941Smrg            continue;
206b8e80941Smrg
207b8e80941Smrg         fprintf(fp, "%c", "xyzw"[instr->src[src].swizzle[i]]);
208b8e80941Smrg      }
209b8e80941Smrg   }
210b8e80941Smrg
211b8e80941Smrg   if (instr->src[src].abs)
212b8e80941Smrg      fprintf(fp, ")");
213b8e80941Smrg}
214b8e80941Smrg
215b8e80941Smrgstatic void
216b8e80941Smrgprint_alu_dest(nir_alu_dest *dest, print_state *state)
217b8e80941Smrg{
218b8e80941Smrg   FILE *fp = state->fp;
219b8e80941Smrg   /* we're going to print the saturate modifier later, after the opcode */
220b8e80941Smrg
221b8e80941Smrg   print_dest(&dest->dest, state);
222b8e80941Smrg
223b8e80941Smrg   if (!dest->dest.is_ssa &&
224b8e80941Smrg       dest->write_mask != (1 << dest->dest.reg.reg->num_components) - 1) {
225b8e80941Smrg      fprintf(fp, ".");
226b8e80941Smrg      for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++)
227b8e80941Smrg         if ((dest->write_mask >> i) & 1)
228b8e80941Smrg            fprintf(fp, "%c", "xyzw"[i]);
229b8e80941Smrg   }
230b8e80941Smrg}
231b8e80941Smrg
232b8e80941Smrgstatic void
233b8e80941Smrgprint_alu_instr(nir_alu_instr *instr, print_state *state)
234b8e80941Smrg{
235b8e80941Smrg   FILE *fp = state->fp;
236b8e80941Smrg
237b8e80941Smrg   print_alu_dest(&instr->dest, state);
238b8e80941Smrg
239b8e80941Smrg   fprintf(fp, " = %s", nir_op_infos[instr->op].name);
240b8e80941Smrg   if (instr->exact)
241b8e80941Smrg      fprintf(fp, "!");
242b8e80941Smrg   if (instr->dest.saturate)
243b8e80941Smrg      fprintf(fp, ".sat");
244b8e80941Smrg   fprintf(fp, " ");
245b8e80941Smrg
246b8e80941Smrg   for (unsigned i = 0; i < nir_op_infos[instr->op].num_inputs; i++) {
247b8e80941Smrg      if (i != 0)
248b8e80941Smrg         fprintf(fp, ", ");
249b8e80941Smrg
250b8e80941Smrg      print_alu_src(instr, i, state);
251b8e80941Smrg   }
252b8e80941Smrg}
253b8e80941Smrg
254b8e80941Smrgstatic const char *
255b8e80941Smrgget_var_name(nir_variable *var, print_state *state)
256b8e80941Smrg{
257b8e80941Smrg   if (state->ht == NULL)
258b8e80941Smrg      return var->name ? var->name : "unnamed";
259b8e80941Smrg
260b8e80941Smrg   assert(state->syms);
261b8e80941Smrg
262b8e80941Smrg   struct hash_entry *entry = _mesa_hash_table_search(state->ht, var);
263b8e80941Smrg   if (entry)
264b8e80941Smrg      return entry->data;
265b8e80941Smrg
266b8e80941Smrg   char *name;
267b8e80941Smrg   if (var->name == NULL) {
268b8e80941Smrg      name = ralloc_asprintf(state->syms, "@%u", state->index++);
269b8e80941Smrg   } else {
270b8e80941Smrg      struct set_entry *set_entry = _mesa_set_search(state->syms, var->name);
271b8e80941Smrg      if (set_entry != NULL) {
272b8e80941Smrg         /* we have a collision with another name, append an @ + a unique
273b8e80941Smrg          * index */
274b8e80941Smrg         name = ralloc_asprintf(state->syms, "%s@%u", var->name,
275b8e80941Smrg                                state->index++);
276b8e80941Smrg      } else {
277b8e80941Smrg         /* Mark this one as seen */
278b8e80941Smrg         _mesa_set_add(state->syms, var->name);
279b8e80941Smrg         name = var->name;
280b8e80941Smrg      }
281b8e80941Smrg   }
282b8e80941Smrg
283b8e80941Smrg   _mesa_hash_table_insert(state->ht, var, name);
284b8e80941Smrg
285b8e80941Smrg   return name;
286b8e80941Smrg}
287b8e80941Smrg
288b8e80941Smrgstatic void
289b8e80941Smrgprint_constant(nir_constant *c, const struct glsl_type *type, print_state *state)
290b8e80941Smrg{
291b8e80941Smrg   FILE *fp = state->fp;
292b8e80941Smrg   const unsigned rows = glsl_get_vector_elements(type);
293b8e80941Smrg   const unsigned cols = glsl_get_matrix_columns(type);
294b8e80941Smrg   unsigned i, j;
295b8e80941Smrg
296b8e80941Smrg   switch (glsl_get_base_type(type)) {
297b8e80941Smrg   case GLSL_TYPE_BOOL:
298b8e80941Smrg      /* Only float base types can be matrices. */
299b8e80941Smrg      assert(cols == 1);
300b8e80941Smrg
301b8e80941Smrg      for (i = 0; i < rows; i++) {
302b8e80941Smrg         if (i > 0) fprintf(fp, ", ");
303b8e80941Smrg         fprintf(fp, "%s", c->values[0][i].b ? "true" : "false");
304b8e80941Smrg      }
305b8e80941Smrg      break;
306b8e80941Smrg
307b8e80941Smrg   case GLSL_TYPE_UINT8:
308b8e80941Smrg   case GLSL_TYPE_INT8:
309b8e80941Smrg      /* Only float base types can be matrices. */
310b8e80941Smrg      assert(cols == 1);
311b8e80941Smrg
312b8e80941Smrg      for (i = 0; i < rows; i++) {
313b8e80941Smrg         if (i > 0) fprintf(fp, ", ");
314b8e80941Smrg         fprintf(fp, "0x%02x", c->values[0][i].u8);
315b8e80941Smrg      }
316b8e80941Smrg      break;
317b8e80941Smrg
318b8e80941Smrg   case GLSL_TYPE_UINT16:
319b8e80941Smrg   case GLSL_TYPE_INT16:
320b8e80941Smrg      /* Only float base types can be matrices. */
321b8e80941Smrg      assert(cols == 1);
322b8e80941Smrg
323b8e80941Smrg      for (i = 0; i < rows; i++) {
324b8e80941Smrg         if (i > 0) fprintf(fp, ", ");
325b8e80941Smrg         fprintf(fp, "0x%04x", c->values[0][i].u16);
326b8e80941Smrg      }
327b8e80941Smrg      break;
328b8e80941Smrg
329b8e80941Smrg   case GLSL_TYPE_UINT:
330b8e80941Smrg   case GLSL_TYPE_INT:
331b8e80941Smrg      /* Only float base types can be matrices. */
332b8e80941Smrg      assert(cols == 1);
333b8e80941Smrg
334b8e80941Smrg      for (i = 0; i < rows; i++) {
335b8e80941Smrg         if (i > 0) fprintf(fp, ", ");
336b8e80941Smrg         fprintf(fp, "0x%08x", c->values[0][i].u32);
337b8e80941Smrg      }
338b8e80941Smrg      break;
339b8e80941Smrg
340b8e80941Smrg   case GLSL_TYPE_FLOAT16:
341b8e80941Smrg      for (i = 0; i < cols; i++) {
342b8e80941Smrg         for (j = 0; j < rows; j++) {
343b8e80941Smrg            if (i + j > 0) fprintf(fp, ", ");
344b8e80941Smrg            fprintf(fp, "%f", _mesa_half_to_float(c->values[i][j].u16));
345b8e80941Smrg         }
346b8e80941Smrg      }
347b8e80941Smrg      break;
348b8e80941Smrg
349b8e80941Smrg   case GLSL_TYPE_FLOAT:
350b8e80941Smrg      for (i = 0; i < cols; i++) {
351b8e80941Smrg         for (j = 0; j < rows; j++) {
352b8e80941Smrg            if (i + j > 0) fprintf(fp, ", ");
353b8e80941Smrg            fprintf(fp, "%f", c->values[i][j].f32);
354b8e80941Smrg         }
355b8e80941Smrg      }
356b8e80941Smrg      break;
357b8e80941Smrg
358b8e80941Smrg   case GLSL_TYPE_DOUBLE:
359b8e80941Smrg      for (i = 0; i < cols; i++) {
360b8e80941Smrg         for (j = 0; j < rows; j++) {
361b8e80941Smrg            if (i + j > 0) fprintf(fp, ", ");
362b8e80941Smrg            fprintf(fp, "%f", c->values[i][j].f64);
363b8e80941Smrg         }
364b8e80941Smrg      }
365b8e80941Smrg      break;
366b8e80941Smrg
367b8e80941Smrg   case GLSL_TYPE_UINT64:
368b8e80941Smrg   case GLSL_TYPE_INT64:
369b8e80941Smrg      /* Only float base types can be matrices. */
370b8e80941Smrg      assert(cols == 1);
371b8e80941Smrg
372b8e80941Smrg      for (i = 0; i < cols; i++) {
373b8e80941Smrg         if (i > 0) fprintf(fp, ", ");
374b8e80941Smrg         fprintf(fp, "0x%08" PRIx64, c->values[0][i].u64);
375b8e80941Smrg      }
376b8e80941Smrg      break;
377b8e80941Smrg
378b8e80941Smrg   case GLSL_TYPE_STRUCT:
379b8e80941Smrg      for (i = 0; i < c->num_elements; i++) {
380b8e80941Smrg         if (i > 0) fprintf(fp, ", ");
381b8e80941Smrg         fprintf(fp, "{ ");
382b8e80941Smrg         print_constant(c->elements[i], glsl_get_struct_field(type, i), state);
383b8e80941Smrg         fprintf(fp, " }");
384b8e80941Smrg      }
385b8e80941Smrg      break;
386b8e80941Smrg
387b8e80941Smrg   case GLSL_TYPE_ARRAY:
388b8e80941Smrg      for (i = 0; i < c->num_elements; i++) {
389b8e80941Smrg         if (i > 0) fprintf(fp, ", ");
390b8e80941Smrg         fprintf(fp, "{ ");
391b8e80941Smrg         print_constant(c->elements[i], glsl_get_array_element(type), state);
392b8e80941Smrg         fprintf(fp, " }");
393b8e80941Smrg      }
394b8e80941Smrg      break;
395b8e80941Smrg
396b8e80941Smrg   default:
397b8e80941Smrg      unreachable("not reached");
398b8e80941Smrg   }
399b8e80941Smrg}
400b8e80941Smrg
401b8e80941Smrgstatic const char *
402b8e80941Smrgget_variable_mode_str(nir_variable_mode mode, bool want_local_global_mode)
403b8e80941Smrg{
404b8e80941Smrg   switch (mode) {
405b8e80941Smrg   case nir_var_shader_in:
406b8e80941Smrg      return "shader_in";
407b8e80941Smrg   case nir_var_shader_out:
408b8e80941Smrg      return "shader_out";
409b8e80941Smrg   case nir_var_uniform:
410b8e80941Smrg      return "uniform";
411b8e80941Smrg   case nir_var_mem_ubo:
412b8e80941Smrg      return "ubo";
413b8e80941Smrg   case nir_var_system_value:
414b8e80941Smrg      return "system";
415b8e80941Smrg   case nir_var_mem_ssbo:
416b8e80941Smrg      return "ssbo";
417b8e80941Smrg   case nir_var_mem_shared:
418b8e80941Smrg      return "shared";
419b8e80941Smrg   case nir_var_mem_global:
420b8e80941Smrg      return "global";
421b8e80941Smrg   case nir_var_shader_temp:
422b8e80941Smrg      return want_local_global_mode ? "shader_temp" : "";
423b8e80941Smrg   case nir_var_function_temp:
424b8e80941Smrg      return want_local_global_mode ? "function_temp" : "";
425b8e80941Smrg   default:
426b8e80941Smrg      return "";
427b8e80941Smrg   }
428b8e80941Smrg}
429b8e80941Smrg
430b8e80941Smrgstatic void
431b8e80941Smrgprint_var_decl(nir_variable *var, print_state *state)
432b8e80941Smrg{
433b8e80941Smrg   FILE *fp = state->fp;
434b8e80941Smrg
435b8e80941Smrg   fprintf(fp, "decl_var ");
436b8e80941Smrg
437b8e80941Smrg   const char *const cent = (var->data.centroid) ? "centroid " : "";
438b8e80941Smrg   const char *const samp = (var->data.sample) ? "sample " : "";
439b8e80941Smrg   const char *const patch = (var->data.patch) ? "patch " : "";
440b8e80941Smrg   const char *const inv = (var->data.invariant) ? "invariant " : "";
441b8e80941Smrg   fprintf(fp, "%s%s%s%s%s %s ",
442b8e80941Smrg           cent, samp, patch, inv, get_variable_mode_str(var->data.mode, false),
443b8e80941Smrg           glsl_interp_mode_name(var->data.interpolation));
444b8e80941Smrg
445b8e80941Smrg   enum gl_access_qualifier access = var->data.image.access;
446b8e80941Smrg   const char *const coher = (access & ACCESS_COHERENT) ? "coherent " : "";
447b8e80941Smrg   const char *const volat = (access & ACCESS_VOLATILE) ? "volatile " : "";
448b8e80941Smrg   const char *const restr = (access & ACCESS_RESTRICT) ? "restrict " : "";
449b8e80941Smrg   const char *const ronly = (access & ACCESS_NON_WRITEABLE) ? "readonly " : "";
450b8e80941Smrg   const char *const wonly = (access & ACCESS_NON_READABLE) ? "writeonly " : "";
451b8e80941Smrg   fprintf(fp, "%s%s%s%s%s", coher, volat, restr, ronly, wonly);
452b8e80941Smrg
453b8e80941Smrg#define FORMAT_CASE(x) case x: fprintf(stderr, #x " "); break
454b8e80941Smrg   switch (var->data.image.format) {
455b8e80941Smrg   FORMAT_CASE(GL_RGBA32F);
456b8e80941Smrg   FORMAT_CASE(GL_RGBA32UI);
457b8e80941Smrg   FORMAT_CASE(GL_RGBA32I);
458b8e80941Smrg   FORMAT_CASE(GL_R32F);
459b8e80941Smrg   FORMAT_CASE(GL_R32UI);
460b8e80941Smrg   FORMAT_CASE(GL_R32I);
461b8e80941Smrg   FORMAT_CASE(GL_RG32F);
462b8e80941Smrg   FORMAT_CASE(GL_RG32UI);
463b8e80941Smrg   FORMAT_CASE(GL_RG32I);
464b8e80941Smrg   FORMAT_CASE(GL_R8);
465b8e80941Smrg   FORMAT_CASE(GL_RG8);
466b8e80941Smrg   FORMAT_CASE(GL_RGBA8);
467b8e80941Smrg   FORMAT_CASE(GL_R8_SNORM);
468b8e80941Smrg   FORMAT_CASE(GL_RG8_SNORM);
469b8e80941Smrg   FORMAT_CASE(GL_RGBA8_SNORM);
470b8e80941Smrg   FORMAT_CASE(GL_R16);
471b8e80941Smrg   FORMAT_CASE(GL_RG16);
472b8e80941Smrg   FORMAT_CASE(GL_RGBA16);
473b8e80941Smrg   FORMAT_CASE(GL_R16_SNORM);
474b8e80941Smrg   FORMAT_CASE(GL_RG16_SNORM);
475b8e80941Smrg   FORMAT_CASE(GL_RGBA16_SNORM);
476b8e80941Smrg   FORMAT_CASE(GL_R16F);
477b8e80941Smrg   FORMAT_CASE(GL_RG16F);
478b8e80941Smrg   FORMAT_CASE(GL_RGBA16F);
479b8e80941Smrg   FORMAT_CASE(GL_R8UI);
480b8e80941Smrg   FORMAT_CASE(GL_R8I);
481b8e80941Smrg   FORMAT_CASE(GL_RG8UI);
482b8e80941Smrg   FORMAT_CASE(GL_RG8I);
483b8e80941Smrg   FORMAT_CASE(GL_RGBA8UI);
484b8e80941Smrg   FORMAT_CASE(GL_RGBA8I);
485b8e80941Smrg   FORMAT_CASE(GL_R16UI);
486b8e80941Smrg   FORMAT_CASE(GL_R16I);
487b8e80941Smrg   FORMAT_CASE(GL_RG16UI);
488b8e80941Smrg   FORMAT_CASE(GL_RG16I);
489b8e80941Smrg   FORMAT_CASE(GL_RGBA16UI);
490b8e80941Smrg   FORMAT_CASE(GL_RGBA16I);
491b8e80941Smrg   FORMAT_CASE(GL_R11F_G11F_B10F);
492b8e80941Smrg   FORMAT_CASE(GL_RGB9_E5);
493b8e80941Smrg   FORMAT_CASE(GL_RGB10_A2);
494b8e80941Smrg   FORMAT_CASE(GL_RGB10_A2UI);
495b8e80941Smrg   default: /* Including the normal GL_NONE */
496b8e80941Smrg      break;
497b8e80941Smrg   }
498b8e80941Smrg#undef FORMAT_CASE
499b8e80941Smrg
500b8e80941Smrg   fprintf(fp, "%s %s", glsl_get_type_name(var->type),
501b8e80941Smrg           get_var_name(var, state));
502b8e80941Smrg
503b8e80941Smrg   if (var->data.mode == nir_var_shader_in ||
504b8e80941Smrg       var->data.mode == nir_var_shader_out ||
505b8e80941Smrg       var->data.mode == nir_var_uniform ||
506b8e80941Smrg       var->data.mode == nir_var_mem_ubo ||
507b8e80941Smrg       var->data.mode == nir_var_mem_ssbo) {
508b8e80941Smrg      const char *loc = NULL;
509b8e80941Smrg      char buf[4];
510b8e80941Smrg
511b8e80941Smrg      switch (state->shader->info.stage) {
512b8e80941Smrg      case MESA_SHADER_VERTEX:
513b8e80941Smrg         if (var->data.mode == nir_var_shader_in)
514b8e80941Smrg            loc = gl_vert_attrib_name(var->data.location);
515b8e80941Smrg         else if (var->data.mode == nir_var_shader_out)
516b8e80941Smrg            loc = gl_varying_slot_name(var->data.location);
517b8e80941Smrg         break;
518b8e80941Smrg      case MESA_SHADER_GEOMETRY:
519b8e80941Smrg         if ((var->data.mode == nir_var_shader_in) ||
520b8e80941Smrg             (var->data.mode == nir_var_shader_out))
521b8e80941Smrg            loc = gl_varying_slot_name(var->data.location);
522b8e80941Smrg         break;
523b8e80941Smrg      case MESA_SHADER_FRAGMENT:
524b8e80941Smrg         if (var->data.mode == nir_var_shader_in)
525b8e80941Smrg            loc = gl_varying_slot_name(var->data.location);
526b8e80941Smrg         else if (var->data.mode == nir_var_shader_out)
527b8e80941Smrg            loc = gl_frag_result_name(var->data.location);
528b8e80941Smrg         break;
529b8e80941Smrg      case MESA_SHADER_TESS_CTRL:
530b8e80941Smrg      case MESA_SHADER_TESS_EVAL:
531b8e80941Smrg      case MESA_SHADER_COMPUTE:
532b8e80941Smrg      case MESA_SHADER_KERNEL:
533b8e80941Smrg      default:
534b8e80941Smrg         /* TODO */
535b8e80941Smrg         break;
536b8e80941Smrg      }
537b8e80941Smrg
538b8e80941Smrg      if (!loc) {
539b8e80941Smrg         snprintf(buf, sizeof(buf), "%u", var->data.location);
540b8e80941Smrg         loc = buf;
541b8e80941Smrg      }
542b8e80941Smrg
543b8e80941Smrg      /* For shader I/O vars that have been split to components or packed,
544b8e80941Smrg       * print the fractional location within the input/output.
545b8e80941Smrg       */
546b8e80941Smrg      unsigned int num_components =
547b8e80941Smrg         glsl_get_components(glsl_without_array(var->type));
548b8e80941Smrg      const char *components = NULL;
549b8e80941Smrg      char components_local[6] = {'.' /* the rest is 0-filled */};
550b8e80941Smrg      switch (var->data.mode) {
551b8e80941Smrg      case nir_var_shader_in:
552b8e80941Smrg      case nir_var_shader_out:
553b8e80941Smrg         if (num_components < 4 && num_components != 0) {
554b8e80941Smrg            const char *xyzw = "xyzw";
555b8e80941Smrg            for (int i = 0; i < num_components; i++)
556b8e80941Smrg               components_local[i + 1] = xyzw[i + var->data.location_frac];
557b8e80941Smrg
558b8e80941Smrg            components = components_local;
559b8e80941Smrg         }
560b8e80941Smrg         break;
561b8e80941Smrg      default:
562b8e80941Smrg         break;
563b8e80941Smrg      }
564b8e80941Smrg
565b8e80941Smrg      fprintf(fp, " (%s%s, %u, %u)%s", loc,
566b8e80941Smrg              components ? components : "",
567b8e80941Smrg              var->data.driver_location, var->data.binding,
568b8e80941Smrg              var->data.compact ? " compact" : "");
569b8e80941Smrg   }
570b8e80941Smrg
571b8e80941Smrg   if (var->constant_initializer) {
572b8e80941Smrg      fprintf(fp, " = { ");
573b8e80941Smrg      print_constant(var->constant_initializer, var->type, state);
574b8e80941Smrg      fprintf(fp, " }");
575b8e80941Smrg   }
576b8e80941Smrg
577b8e80941Smrg   fprintf(fp, "\n");
578b8e80941Smrg   print_annotation(state, var);
579b8e80941Smrg}
580b8e80941Smrg
581b8e80941Smrgstatic void
582b8e80941Smrgprint_deref_link(const nir_deref_instr *instr, bool whole_chain, print_state *state)
583b8e80941Smrg{
584b8e80941Smrg   FILE *fp = state->fp;
585b8e80941Smrg
586b8e80941Smrg   if (instr->deref_type == nir_deref_type_var) {
587b8e80941Smrg      fprintf(fp, "%s", get_var_name(instr->var, state));
588b8e80941Smrg      return;
589b8e80941Smrg   } else if (instr->deref_type == nir_deref_type_cast) {
590b8e80941Smrg      fprintf(fp, "(%s *)", glsl_get_type_name(instr->type));
591b8e80941Smrg      print_src(&instr->parent, state);
592b8e80941Smrg      return;
593b8e80941Smrg   }
594b8e80941Smrg
595b8e80941Smrg   assert(instr->parent.is_ssa);
596b8e80941Smrg   nir_deref_instr *parent =
597b8e80941Smrg      nir_instr_as_deref(instr->parent.ssa->parent_instr);
598b8e80941Smrg
599b8e80941Smrg   /* Is the parent we're going to print a bare cast? */
600b8e80941Smrg   const bool is_parent_cast =
601b8e80941Smrg      whole_chain && parent->deref_type == nir_deref_type_cast;
602b8e80941Smrg
603b8e80941Smrg   /* If we're not printing the whole chain, the parent we print will be a SSA
604b8e80941Smrg    * value that represents a pointer.  The only deref type that naturally
605b8e80941Smrg    * gives a pointer is a cast.
606b8e80941Smrg    */
607b8e80941Smrg   const bool is_parent_pointer =
608b8e80941Smrg      !whole_chain || parent->deref_type == nir_deref_type_cast;
609b8e80941Smrg
610b8e80941Smrg   /* Struct derefs have a nice syntax that works on pointers, arrays derefs
611b8e80941Smrg    * do not.
612b8e80941Smrg    */
613b8e80941Smrg   const bool need_deref =
614b8e80941Smrg      is_parent_pointer && instr->deref_type != nir_deref_type_struct;
615b8e80941Smrg
616b8e80941Smrg   /* Cast need extra parens and so * dereferences */
617b8e80941Smrg   if (is_parent_cast || need_deref)
618b8e80941Smrg      fprintf(fp, "(");
619b8e80941Smrg
620b8e80941Smrg   if (need_deref)
621b8e80941Smrg      fprintf(fp, "*");
622b8e80941Smrg
623b8e80941Smrg   if (whole_chain) {
624b8e80941Smrg      print_deref_link(parent, whole_chain, state);
625b8e80941Smrg   } else {
626b8e80941Smrg      print_src(&instr->parent, state);
627b8e80941Smrg   }
628b8e80941Smrg
629b8e80941Smrg   if (is_parent_cast || need_deref)
630b8e80941Smrg      fprintf(fp, ")");
631b8e80941Smrg
632b8e80941Smrg   switch (instr->deref_type) {
633b8e80941Smrg   case nir_deref_type_struct:
634b8e80941Smrg      fprintf(fp, "%s%s", is_parent_pointer ? "->" : ".",
635b8e80941Smrg              glsl_get_struct_elem_name(parent->type, instr->strct.index));
636b8e80941Smrg      break;
637b8e80941Smrg
638b8e80941Smrg   case nir_deref_type_array:
639b8e80941Smrg   case nir_deref_type_ptr_as_array: {
640b8e80941Smrg      if (nir_src_is_const(instr->arr.index)) {
641b8e80941Smrg         fprintf(fp, "[%"PRIx64"]", nir_src_as_int(instr->arr.index));
642b8e80941Smrg      } else {
643b8e80941Smrg         fprintf(fp, "[");
644b8e80941Smrg         print_src(&instr->arr.index, state);
645b8e80941Smrg         fprintf(fp, "]");
646b8e80941Smrg      }
647b8e80941Smrg      break;
648b8e80941Smrg   }
649b8e80941Smrg
650b8e80941Smrg   case nir_deref_type_array_wildcard:
651b8e80941Smrg      fprintf(fp, "[*]");
652b8e80941Smrg      break;
653b8e80941Smrg
654b8e80941Smrg   default:
655b8e80941Smrg      unreachable("Invalid deref instruction type");
656b8e80941Smrg   }
657b8e80941Smrg}
658b8e80941Smrg
659b8e80941Smrgstatic void
660b8e80941Smrgprint_deref_instr(nir_deref_instr *instr, print_state *state)
661b8e80941Smrg{
662b8e80941Smrg   FILE *fp = state->fp;
663b8e80941Smrg
664b8e80941Smrg   print_dest(&instr->dest, state);
665b8e80941Smrg
666b8e80941Smrg   switch (instr->deref_type) {
667b8e80941Smrg   case nir_deref_type_var:
668b8e80941Smrg      fprintf(fp, " = deref_var ");
669b8e80941Smrg      break;
670b8e80941Smrg   case nir_deref_type_array:
671b8e80941Smrg   case nir_deref_type_array_wildcard:
672b8e80941Smrg      fprintf(fp, " = deref_array ");
673b8e80941Smrg      break;
674b8e80941Smrg   case nir_deref_type_struct:
675b8e80941Smrg      fprintf(fp, " = deref_struct ");
676b8e80941Smrg      break;
677b8e80941Smrg   case nir_deref_type_cast:
678b8e80941Smrg      fprintf(fp, " = deref_cast ");
679b8e80941Smrg      break;
680b8e80941Smrg   case nir_deref_type_ptr_as_array:
681b8e80941Smrg      fprintf(fp, " = deref_ptr_as_array ");
682b8e80941Smrg      break;
683b8e80941Smrg   default:
684b8e80941Smrg      unreachable("Invalid deref instruction type");
685b8e80941Smrg   }
686b8e80941Smrg
687b8e80941Smrg   /* Only casts naturally return a pointer type */
688b8e80941Smrg   if (instr->deref_type != nir_deref_type_cast)
689b8e80941Smrg      fprintf(fp, "&");
690b8e80941Smrg
691b8e80941Smrg   print_deref_link(instr, false, state);
692b8e80941Smrg
693b8e80941Smrg   fprintf(fp, " (%s %s) ",
694b8e80941Smrg           get_variable_mode_str(instr->mode, true),
695b8e80941Smrg           glsl_get_type_name(instr->type));
696b8e80941Smrg
697b8e80941Smrg   if (instr->deref_type != nir_deref_type_var &&
698b8e80941Smrg       instr->deref_type != nir_deref_type_cast) {
699b8e80941Smrg      /* Print the entire chain as a comment */
700b8e80941Smrg      fprintf(fp, "/* &");
701b8e80941Smrg      print_deref_link(instr, true, state);
702b8e80941Smrg      fprintf(fp, " */");
703b8e80941Smrg   }
704b8e80941Smrg}
705b8e80941Smrg
706b8e80941Smrgstatic const char *
707b8e80941Smrgvulkan_descriptor_type_name(VkDescriptorType type)
708b8e80941Smrg{
709b8e80941Smrg   switch (type) {
710b8e80941Smrg   case VK_DESCRIPTOR_TYPE_SAMPLER: return "sampler";
711b8e80941Smrg   case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: return "texture+sampler";
712b8e80941Smrg   case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: return "texture";
713b8e80941Smrg   case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: return "image";
714b8e80941Smrg   case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: return "texture-buffer";
715b8e80941Smrg   case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: return "image-buffer";
716b8e80941Smrg   case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: return "UBO";
717b8e80941Smrg   case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: return "SSBO";
718b8e80941Smrg   case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: return "UBO";
719b8e80941Smrg   case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: return "SSBO";
720b8e80941Smrg   case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: return "input-att";
721b8e80941Smrg   case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT: return "inline-UBO";
722b8e80941Smrg   default: return "unknown";
723b8e80941Smrg   }
724b8e80941Smrg}
725b8e80941Smrg
726b8e80941Smrgstatic void
727b8e80941Smrgprint_intrinsic_instr(nir_intrinsic_instr *instr, print_state *state)
728b8e80941Smrg{
729b8e80941Smrg   const nir_intrinsic_info *info = &nir_intrinsic_infos[instr->intrinsic];
730b8e80941Smrg   unsigned num_srcs = info->num_srcs;
731b8e80941Smrg   FILE *fp = state->fp;
732b8e80941Smrg
733b8e80941Smrg   if (info->has_dest) {
734b8e80941Smrg      print_dest(&instr->dest, state);
735b8e80941Smrg      fprintf(fp, " = ");
736b8e80941Smrg   }
737b8e80941Smrg
738b8e80941Smrg   fprintf(fp, "intrinsic %s (", info->name);
739b8e80941Smrg
740b8e80941Smrg   for (unsigned i = 0; i < num_srcs; i++) {
741b8e80941Smrg      if (i != 0)
742b8e80941Smrg         fprintf(fp, ", ");
743b8e80941Smrg
744b8e80941Smrg      print_src(&instr->src[i], state);
745b8e80941Smrg   }
746b8e80941Smrg
747b8e80941Smrg   fprintf(fp, ") (");
748b8e80941Smrg
749b8e80941Smrg   for (unsigned i = 0; i < info->num_indices; i++) {
750b8e80941Smrg      if (i != 0)
751b8e80941Smrg         fprintf(fp, ", ");
752b8e80941Smrg
753b8e80941Smrg      fprintf(fp, "%d", instr->const_index[i]);
754b8e80941Smrg   }
755b8e80941Smrg
756b8e80941Smrg   fprintf(fp, ")");
757b8e80941Smrg
758b8e80941Smrg   static const char *index_name[NIR_INTRINSIC_NUM_INDEX_FLAGS] = {
759b8e80941Smrg      [NIR_INTRINSIC_BASE] = "base",
760b8e80941Smrg      [NIR_INTRINSIC_WRMASK] = "wrmask",
761b8e80941Smrg      [NIR_INTRINSIC_STREAM_ID] = "stream-id",
762b8e80941Smrg      [NIR_INTRINSIC_UCP_ID] = "ucp-id",
763b8e80941Smrg      [NIR_INTRINSIC_RANGE] = "range",
764b8e80941Smrg      [NIR_INTRINSIC_DESC_SET] = "desc-set",
765b8e80941Smrg      [NIR_INTRINSIC_BINDING] = "binding",
766b8e80941Smrg      [NIR_INTRINSIC_COMPONENT] = "component",
767b8e80941Smrg      [NIR_INTRINSIC_INTERP_MODE] = "interp_mode",
768b8e80941Smrg      [NIR_INTRINSIC_REDUCTION_OP] = "reduction_op",
769b8e80941Smrg      [NIR_INTRINSIC_CLUSTER_SIZE] = "cluster_size",
770b8e80941Smrg      [NIR_INTRINSIC_PARAM_IDX] = "param_idx",
771b8e80941Smrg      [NIR_INTRINSIC_IMAGE_DIM] = "image_dim",
772b8e80941Smrg      [NIR_INTRINSIC_IMAGE_ARRAY] = "image_array",
773b8e80941Smrg      [NIR_INTRINSIC_ACCESS] = "access",
774b8e80941Smrg      [NIR_INTRINSIC_SRC_ACCESS] = "src-access",
775b8e80941Smrg      [NIR_INTRINSIC_DST_ACCESS] = "dst-access",
776b8e80941Smrg      [NIR_INTRINSIC_FORMAT] = "format",
777b8e80941Smrg      [NIR_INTRINSIC_ALIGN_MUL] = "align_mul",
778b8e80941Smrg      [NIR_INTRINSIC_ALIGN_OFFSET] = "align_offset",
779b8e80941Smrg      [NIR_INTRINSIC_DESC_TYPE] = "desc_type",
780b8e80941Smrg   };
781b8e80941Smrg   for (unsigned idx = 1; idx < NIR_INTRINSIC_NUM_INDEX_FLAGS; idx++) {
782b8e80941Smrg      if (!info->index_map[idx])
783b8e80941Smrg         continue;
784b8e80941Smrg      fprintf(fp, " /*");
785b8e80941Smrg      if (idx == NIR_INTRINSIC_WRMASK) {
786b8e80941Smrg         /* special case wrmask to show it as a writemask.. */
787b8e80941Smrg         unsigned wrmask = nir_intrinsic_write_mask(instr);
788b8e80941Smrg         fprintf(fp, " wrmask=");
789b8e80941Smrg         for (unsigned i = 0; i < 4; i++)
790b8e80941Smrg            if ((wrmask >> i) & 1)
791b8e80941Smrg               fprintf(fp, "%c", "xyzw"[i]);
792b8e80941Smrg      } else if (idx == NIR_INTRINSIC_REDUCTION_OP) {
793b8e80941Smrg         nir_op reduction_op = nir_intrinsic_reduction_op(instr);
794b8e80941Smrg         fprintf(fp, " reduction_op=%s", nir_op_infos[reduction_op].name);
795b8e80941Smrg      } else if (idx == NIR_INTRINSIC_IMAGE_DIM) {
796b8e80941Smrg         static const char *dim_name[] = {
797b8e80941Smrg            [GLSL_SAMPLER_DIM_1D] = "1D",
798b8e80941Smrg            [GLSL_SAMPLER_DIM_2D] = "2D",
799b8e80941Smrg            [GLSL_SAMPLER_DIM_3D] = "3D",
800b8e80941Smrg            [GLSL_SAMPLER_DIM_CUBE] = "Cube",
801b8e80941Smrg            [GLSL_SAMPLER_DIM_RECT] = "Rect",
802b8e80941Smrg            [GLSL_SAMPLER_DIM_BUF] = "Buf",
803b8e80941Smrg            [GLSL_SAMPLER_DIM_MS] = "2D-MSAA",
804b8e80941Smrg            [GLSL_SAMPLER_DIM_SUBPASS] = "Subpass",
805b8e80941Smrg            [GLSL_SAMPLER_DIM_SUBPASS_MS] = "Subpass-MSAA",
806b8e80941Smrg         };
807b8e80941Smrg         enum glsl_sampler_dim dim = nir_intrinsic_image_dim(instr);
808b8e80941Smrg         assert(dim < ARRAY_SIZE(dim_name) && dim_name[dim]);
809b8e80941Smrg         fprintf(fp, " image_dim=%s", dim_name[dim]);
810b8e80941Smrg      } else if (idx == NIR_INTRINSIC_IMAGE_ARRAY) {
811b8e80941Smrg         bool array = nir_intrinsic_image_array(instr);
812b8e80941Smrg         fprintf(fp, " image_array=%s", array ? "true" : "false");
813b8e80941Smrg      } else if (idx == NIR_INTRINSIC_DESC_TYPE) {
814b8e80941Smrg         VkDescriptorType desc_type = nir_intrinsic_desc_type(instr);
815b8e80941Smrg         fprintf(fp, " desc_type=%s", vulkan_descriptor_type_name(desc_type));
816b8e80941Smrg      } else {
817b8e80941Smrg         unsigned off = info->index_map[idx] - 1;
818b8e80941Smrg         assert(index_name[idx]);  /* forgot to update index_name table? */
819b8e80941Smrg         fprintf(fp, " %s=%d", index_name[idx], instr->const_index[off]);
820b8e80941Smrg      }
821b8e80941Smrg      fprintf(fp, " */");
822b8e80941Smrg   }
823b8e80941Smrg
824b8e80941Smrg   if (!state->shader)
825b8e80941Smrg      return;
826b8e80941Smrg
827b8e80941Smrg   struct exec_list *var_list = NULL;
828b8e80941Smrg
829b8e80941Smrg   switch (instr->intrinsic) {
830b8e80941Smrg   case nir_intrinsic_load_uniform:
831b8e80941Smrg      var_list = &state->shader->uniforms;
832b8e80941Smrg      break;
833b8e80941Smrg   case nir_intrinsic_load_input:
834b8e80941Smrg   case nir_intrinsic_load_interpolated_input:
835b8e80941Smrg   case nir_intrinsic_load_per_vertex_input:
836b8e80941Smrg      var_list = &state->shader->inputs;
837b8e80941Smrg      break;
838b8e80941Smrg   case nir_intrinsic_load_output:
839b8e80941Smrg   case nir_intrinsic_store_output:
840b8e80941Smrg   case nir_intrinsic_store_per_vertex_output:
841b8e80941Smrg      var_list = &state->shader->outputs;
842b8e80941Smrg      break;
843b8e80941Smrg   default:
844b8e80941Smrg      return;
845b8e80941Smrg   }
846b8e80941Smrg
847b8e80941Smrg   nir_foreach_variable(var, var_list) {
848b8e80941Smrg      if ((var->data.driver_location == nir_intrinsic_base(instr)) &&
849b8e80941Smrg          (instr->intrinsic == nir_intrinsic_load_uniform ||
850b8e80941Smrg           (nir_intrinsic_component(instr) >= var->data.location_frac  &&
851b8e80941Smrg            nir_intrinsic_component(instr) <
852b8e80941Smrg            (var->data.location_frac + glsl_get_components(var->type)))) &&
853b8e80941Smrg           var->name) {
854b8e80941Smrg         fprintf(fp, "\t/* %s */", var->name);
855b8e80941Smrg         break;
856b8e80941Smrg      }
857b8e80941Smrg   }
858b8e80941Smrg}
859b8e80941Smrg
860b8e80941Smrgstatic void
861b8e80941Smrgprint_tex_instr(nir_tex_instr *instr, print_state *state)
862b8e80941Smrg{
863b8e80941Smrg   FILE *fp = state->fp;
864b8e80941Smrg
865b8e80941Smrg   print_dest(&instr->dest, state);
866b8e80941Smrg
867b8e80941Smrg   fprintf(fp, " = ");
868b8e80941Smrg
869b8e80941Smrg   switch (instr->op) {
870b8e80941Smrg   case nir_texop_tex:
871b8e80941Smrg      fprintf(fp, "tex ");
872b8e80941Smrg      break;
873b8e80941Smrg   case nir_texop_txb:
874b8e80941Smrg      fprintf(fp, "txb ");
875b8e80941Smrg      break;
876b8e80941Smrg   case nir_texop_txl:
877b8e80941Smrg      fprintf(fp, "txl ");
878b8e80941Smrg      break;
879b8e80941Smrg   case nir_texop_txd:
880b8e80941Smrg      fprintf(fp, "txd ");
881b8e80941Smrg      break;
882b8e80941Smrg   case nir_texop_txf:
883b8e80941Smrg      fprintf(fp, "txf ");
884b8e80941Smrg      break;
885b8e80941Smrg   case nir_texop_txf_ms:
886b8e80941Smrg      fprintf(fp, "txf_ms ");
887b8e80941Smrg      break;
888b8e80941Smrg   case nir_texop_txf_ms_fb:
889b8e80941Smrg      fprintf(fp, "txf_ms_fb ");
890b8e80941Smrg      break;
891b8e80941Smrg   case nir_texop_txf_ms_mcs:
892b8e80941Smrg      fprintf(fp, "txf_ms_mcs ");
893b8e80941Smrg      break;
894b8e80941Smrg   case nir_texop_txs:
895b8e80941Smrg      fprintf(fp, "txs ");
896b8e80941Smrg      break;
897b8e80941Smrg   case nir_texop_lod:
898b8e80941Smrg      fprintf(fp, "lod ");
899b8e80941Smrg      break;
900b8e80941Smrg   case nir_texop_tg4:
901b8e80941Smrg      fprintf(fp, "tg4 ");
902b8e80941Smrg      break;
903b8e80941Smrg   case nir_texop_query_levels:
904b8e80941Smrg      fprintf(fp, "query_levels ");
905b8e80941Smrg      break;
906b8e80941Smrg   case nir_texop_texture_samples:
907b8e80941Smrg      fprintf(fp, "texture_samples ");
908b8e80941Smrg      break;
909b8e80941Smrg   case nir_texop_samples_identical:
910b8e80941Smrg      fprintf(fp, "samples_identical ");
911b8e80941Smrg      break;
912b8e80941Smrg   default:
913b8e80941Smrg      unreachable("Invalid texture operation");
914b8e80941Smrg      break;
915b8e80941Smrg   }
916b8e80941Smrg
917b8e80941Smrg   bool has_texture_deref = false, has_sampler_deref = false;
918b8e80941Smrg   for (unsigned i = 0; i < instr->num_srcs; i++) {
919b8e80941Smrg      if (i > 0) {
920b8e80941Smrg         fprintf(fp, ", ");
921b8e80941Smrg      }
922b8e80941Smrg
923b8e80941Smrg      print_src(&instr->src[i].src, state);
924b8e80941Smrg      fprintf(fp, " ");
925b8e80941Smrg
926b8e80941Smrg      switch(instr->src[i].src_type) {
927b8e80941Smrg      case nir_tex_src_coord:
928b8e80941Smrg         fprintf(fp, "(coord)");
929b8e80941Smrg         break;
930b8e80941Smrg      case nir_tex_src_projector:
931b8e80941Smrg         fprintf(fp, "(projector)");
932b8e80941Smrg         break;
933b8e80941Smrg      case nir_tex_src_comparator:
934b8e80941Smrg         fprintf(fp, "(comparator)");
935b8e80941Smrg         break;
936b8e80941Smrg      case nir_tex_src_offset:
937b8e80941Smrg         fprintf(fp, "(offset)");
938b8e80941Smrg         break;
939b8e80941Smrg      case nir_tex_src_bias:
940b8e80941Smrg         fprintf(fp, "(bias)");
941b8e80941Smrg         break;
942b8e80941Smrg      case nir_tex_src_lod:
943b8e80941Smrg         fprintf(fp, "(lod)");
944b8e80941Smrg         break;
945b8e80941Smrg      case nir_tex_src_min_lod:
946b8e80941Smrg         fprintf(fp, "(min_lod)");
947b8e80941Smrg         break;
948b8e80941Smrg      case nir_tex_src_ms_index:
949b8e80941Smrg         fprintf(fp, "(ms_index)");
950b8e80941Smrg         break;
951b8e80941Smrg      case nir_tex_src_ms_mcs:
952b8e80941Smrg         fprintf(fp, "(ms_mcs)");
953b8e80941Smrg         break;
954b8e80941Smrg      case nir_tex_src_ddx:
955b8e80941Smrg         fprintf(fp, "(ddx)");
956b8e80941Smrg         break;
957b8e80941Smrg      case nir_tex_src_ddy:
958b8e80941Smrg         fprintf(fp, "(ddy)");
959b8e80941Smrg         break;
960b8e80941Smrg      case nir_tex_src_texture_deref:
961b8e80941Smrg         has_texture_deref = true;
962b8e80941Smrg         fprintf(fp, "(texture_deref)");
963b8e80941Smrg         break;
964b8e80941Smrg      case nir_tex_src_sampler_deref:
965b8e80941Smrg         has_sampler_deref = true;
966b8e80941Smrg         fprintf(fp, "(sampler_deref)");
967b8e80941Smrg         break;
968b8e80941Smrg      case nir_tex_src_texture_offset:
969b8e80941Smrg         fprintf(fp, "(texture_offset)");
970b8e80941Smrg         break;
971b8e80941Smrg      case nir_tex_src_sampler_offset:
972b8e80941Smrg         fprintf(fp, "(sampler_offset)");
973b8e80941Smrg         break;
974b8e80941Smrg      case nir_tex_src_texture_handle:
975b8e80941Smrg         fprintf(fp, "(texture_handle)");
976b8e80941Smrg         break;
977b8e80941Smrg      case nir_tex_src_sampler_handle:
978b8e80941Smrg         fprintf(fp, "(sampler_handle)");
979b8e80941Smrg         break;
980b8e80941Smrg      case nir_tex_src_plane:
981b8e80941Smrg         fprintf(fp, "(plane)");
982b8e80941Smrg         break;
983b8e80941Smrg
984b8e80941Smrg      default:
985b8e80941Smrg         unreachable("Invalid texture source type");
986b8e80941Smrg         break;
987b8e80941Smrg      }
988b8e80941Smrg   }
989b8e80941Smrg
990b8e80941Smrg   if (instr->op == nir_texop_tg4) {
991b8e80941Smrg      fprintf(fp, ", %u (gather_component)", instr->component);
992b8e80941Smrg   }
993b8e80941Smrg
994b8e80941Smrg   if (nir_tex_instr_has_explicit_tg4_offsets(instr)) {
995b8e80941Smrg      fprintf(fp, ", { (%i, %i)", instr->tg4_offsets[0][0], instr->tg4_offsets[0][1]);
996b8e80941Smrg      for (unsigned i = 1; i < 4; ++i)
997b8e80941Smrg         fprintf(fp, ", (%i, %i)", instr->tg4_offsets[i][0],
998b8e80941Smrg                 instr->tg4_offsets[i][1]);
999b8e80941Smrg      fprintf(fp, " } (offsets)");
1000b8e80941Smrg   }
1001b8e80941Smrg
1002b8e80941Smrg   if (instr->op != nir_texop_txf_ms_fb) {
1003b8e80941Smrg      if (!has_texture_deref) {
1004b8e80941Smrg         fprintf(fp, ", %u (texture)", instr->texture_index);
1005b8e80941Smrg      }
1006b8e80941Smrg
1007b8e80941Smrg      if (!has_sampler_deref) {
1008b8e80941Smrg         fprintf(fp, ", %u (sampler)", instr->sampler_index);
1009b8e80941Smrg      }
1010b8e80941Smrg   }
1011b8e80941Smrg}
1012b8e80941Smrg
1013b8e80941Smrgstatic void
1014b8e80941Smrgprint_call_instr(nir_call_instr *instr, print_state *state)
1015b8e80941Smrg{
1016b8e80941Smrg   FILE *fp = state->fp;
1017b8e80941Smrg
1018b8e80941Smrg   fprintf(fp, "call %s ", instr->callee->name);
1019b8e80941Smrg
1020b8e80941Smrg   for (unsigned i = 0; i < instr->num_params; i++) {
1021b8e80941Smrg      if (i != 0)
1022b8e80941Smrg         fprintf(fp, ", ");
1023b8e80941Smrg
1024b8e80941Smrg      print_src(&instr->params[i], state);
1025b8e80941Smrg   }
1026b8e80941Smrg}
1027b8e80941Smrg
1028b8e80941Smrgstatic void
1029b8e80941Smrgprint_load_const_instr(nir_load_const_instr *instr, print_state *state)
1030b8e80941Smrg{
1031b8e80941Smrg   FILE *fp = state->fp;
1032b8e80941Smrg
1033b8e80941Smrg   print_ssa_def(&instr->def, state);
1034b8e80941Smrg
1035b8e80941Smrg   fprintf(fp, " = load_const (");
1036b8e80941Smrg
1037b8e80941Smrg   for (unsigned i = 0; i < instr->def.num_components; i++) {
1038b8e80941Smrg      if (i != 0)
1039b8e80941Smrg         fprintf(fp, ", ");
1040b8e80941Smrg
1041b8e80941Smrg      /*
1042b8e80941Smrg       * we don't really know the type of the constant (if it will be used as a
1043b8e80941Smrg       * float or an int), so just print the raw constant in hex for fidelity
1044b8e80941Smrg       * and then print the float in a comment for readability.
1045b8e80941Smrg       */
1046b8e80941Smrg
1047b8e80941Smrg      switch (instr->def.bit_size) {
1048b8e80941Smrg      case 64:
1049b8e80941Smrg         fprintf(fp, "0x%16" PRIx64 " /* %f */", instr->value[i].u64,
1050b8e80941Smrg                 instr->value[i].f64);
1051b8e80941Smrg         break;
1052b8e80941Smrg      case 32:
1053b8e80941Smrg         fprintf(fp, "0x%08x /* %f */", instr->value[i].u32, instr->value[i].f32);
1054b8e80941Smrg         break;
1055b8e80941Smrg      case 16:
1056b8e80941Smrg         fprintf(fp, "0x%04x /* %f */", instr->value[i].u16,
1057b8e80941Smrg                 _mesa_half_to_float(instr->value[i].u16));
1058b8e80941Smrg         break;
1059b8e80941Smrg      case 8:
1060b8e80941Smrg         fprintf(fp, "0x%02x", instr->value[i].u8);
1061b8e80941Smrg         break;
1062b8e80941Smrg      case 1:
1063b8e80941Smrg         fprintf(fp, "%s", instr->value[i].b ? "true" : "false");
1064b8e80941Smrg         break;
1065b8e80941Smrg      }
1066b8e80941Smrg   }
1067b8e80941Smrg
1068b8e80941Smrg   fprintf(fp, ")");
1069b8e80941Smrg}
1070b8e80941Smrg
1071b8e80941Smrgstatic void
1072b8e80941Smrgprint_jump_instr(nir_jump_instr *instr, print_state *state)
1073b8e80941Smrg{
1074b8e80941Smrg   FILE *fp = state->fp;
1075b8e80941Smrg
1076b8e80941Smrg   switch (instr->type) {
1077b8e80941Smrg   case nir_jump_break:
1078b8e80941Smrg      fprintf(fp, "break");
1079b8e80941Smrg      break;
1080b8e80941Smrg
1081b8e80941Smrg   case nir_jump_continue:
1082b8e80941Smrg      fprintf(fp, "continue");
1083b8e80941Smrg      break;
1084b8e80941Smrg
1085b8e80941Smrg   case nir_jump_return:
1086b8e80941Smrg      fprintf(fp, "return");
1087b8e80941Smrg      break;
1088b8e80941Smrg   }
1089b8e80941Smrg}
1090b8e80941Smrg
1091b8e80941Smrgstatic void
1092b8e80941Smrgprint_ssa_undef_instr(nir_ssa_undef_instr* instr, print_state *state)
1093b8e80941Smrg{
1094b8e80941Smrg   FILE *fp = state->fp;
1095b8e80941Smrg   print_ssa_def(&instr->def, state);
1096b8e80941Smrg   fprintf(fp, " = undefined");
1097b8e80941Smrg}
1098b8e80941Smrg
1099b8e80941Smrgstatic void
1100b8e80941Smrgprint_phi_instr(nir_phi_instr *instr, print_state *state)
1101b8e80941Smrg{
1102b8e80941Smrg   FILE *fp = state->fp;
1103b8e80941Smrg   print_dest(&instr->dest, state);
1104b8e80941Smrg   fprintf(fp, " = phi ");
1105b8e80941Smrg   nir_foreach_phi_src(src, instr) {
1106b8e80941Smrg      if (&src->node != exec_list_get_head(&instr->srcs))
1107b8e80941Smrg         fprintf(fp, ", ");
1108b8e80941Smrg
1109b8e80941Smrg      fprintf(fp, "block_%u: ", src->pred->index);
1110b8e80941Smrg      print_src(&src->src, state);
1111b8e80941Smrg   }
1112b8e80941Smrg}
1113b8e80941Smrg
1114b8e80941Smrgstatic void
1115b8e80941Smrgprint_parallel_copy_instr(nir_parallel_copy_instr *instr, print_state *state)
1116b8e80941Smrg{
1117b8e80941Smrg   FILE *fp = state->fp;
1118b8e80941Smrg   nir_foreach_parallel_copy_entry(entry, instr) {
1119b8e80941Smrg      if (&entry->node != exec_list_get_head(&instr->entries))
1120b8e80941Smrg         fprintf(fp, "; ");
1121b8e80941Smrg
1122b8e80941Smrg      print_dest(&entry->dest, state);
1123b8e80941Smrg      fprintf(fp, " = ");
1124b8e80941Smrg      print_src(&entry->src, state);
1125b8e80941Smrg   }
1126b8e80941Smrg}
1127b8e80941Smrg
1128b8e80941Smrgstatic void
1129b8e80941Smrgprint_instr(const nir_instr *instr, print_state *state, unsigned tabs)
1130b8e80941Smrg{
1131b8e80941Smrg   FILE *fp = state->fp;
1132b8e80941Smrg   print_tabs(tabs, fp);
1133b8e80941Smrg
1134b8e80941Smrg   switch (instr->type) {
1135b8e80941Smrg   case nir_instr_type_alu:
1136b8e80941Smrg      print_alu_instr(nir_instr_as_alu(instr), state);
1137b8e80941Smrg      break;
1138b8e80941Smrg
1139b8e80941Smrg   case nir_instr_type_deref:
1140b8e80941Smrg      print_deref_instr(nir_instr_as_deref(instr), state);
1141b8e80941Smrg      break;
1142b8e80941Smrg
1143b8e80941Smrg   case nir_instr_type_call:
1144b8e80941Smrg      print_call_instr(nir_instr_as_call(instr), state);
1145b8e80941Smrg      break;
1146b8e80941Smrg
1147b8e80941Smrg   case nir_instr_type_intrinsic:
1148b8e80941Smrg      print_intrinsic_instr(nir_instr_as_intrinsic(instr), state);
1149b8e80941Smrg      break;
1150b8e80941Smrg
1151b8e80941Smrg   case nir_instr_type_tex:
1152b8e80941Smrg      print_tex_instr(nir_instr_as_tex(instr), state);
1153b8e80941Smrg      break;
1154b8e80941Smrg
1155b8e80941Smrg   case nir_instr_type_load_const:
1156b8e80941Smrg      print_load_const_instr(nir_instr_as_load_const(instr), state);
1157b8e80941Smrg      break;
1158b8e80941Smrg
1159b8e80941Smrg   case nir_instr_type_jump:
1160b8e80941Smrg      print_jump_instr(nir_instr_as_jump(instr), state);
1161b8e80941Smrg      break;
1162b8e80941Smrg
1163b8e80941Smrg   case nir_instr_type_ssa_undef:
1164b8e80941Smrg      print_ssa_undef_instr(nir_instr_as_ssa_undef(instr), state);
1165b8e80941Smrg      break;
1166b8e80941Smrg
1167b8e80941Smrg   case nir_instr_type_phi:
1168b8e80941Smrg      print_phi_instr(nir_instr_as_phi(instr), state);
1169b8e80941Smrg      break;
1170b8e80941Smrg
1171b8e80941Smrg   case nir_instr_type_parallel_copy:
1172b8e80941Smrg      print_parallel_copy_instr(nir_instr_as_parallel_copy(instr), state);
1173b8e80941Smrg      break;
1174b8e80941Smrg
1175b8e80941Smrg   default:
1176b8e80941Smrg      unreachable("Invalid instruction type");
1177b8e80941Smrg      break;
1178b8e80941Smrg   }
1179b8e80941Smrg}
1180b8e80941Smrg
1181b8e80941Smrgstatic int
1182b8e80941Smrgcompare_block_index(const void *p1, const void *p2)
1183b8e80941Smrg{
1184b8e80941Smrg   const nir_block *block1 = *((const nir_block **) p1);
1185b8e80941Smrg   const nir_block *block2 = *((const nir_block **) p2);
1186b8e80941Smrg
1187b8e80941Smrg   return (int) block1->index - (int) block2->index;
1188b8e80941Smrg}
1189b8e80941Smrg
1190b8e80941Smrgstatic void print_cf_node(nir_cf_node *node, print_state *state,
1191b8e80941Smrg                          unsigned tabs);
1192b8e80941Smrg
1193b8e80941Smrgstatic void
1194b8e80941Smrgprint_block(nir_block *block, print_state *state, unsigned tabs)
1195b8e80941Smrg{
1196b8e80941Smrg   FILE *fp = state->fp;
1197b8e80941Smrg
1198b8e80941Smrg   print_tabs(tabs, fp);
1199b8e80941Smrg   fprintf(fp, "block block_%u:\n", block->index);
1200b8e80941Smrg
1201b8e80941Smrg   /* sort the predecessors by index so we consistently print the same thing */
1202b8e80941Smrg
1203b8e80941Smrg   nir_block **preds =
1204b8e80941Smrg      malloc(block->predecessors->entries * sizeof(nir_block *));
1205b8e80941Smrg
1206b8e80941Smrg   unsigned i = 0;
1207b8e80941Smrg   set_foreach(block->predecessors, entry) {
1208b8e80941Smrg      preds[i++] = (nir_block *) entry->key;
1209b8e80941Smrg   }
1210b8e80941Smrg
1211b8e80941Smrg   qsort(preds, block->predecessors->entries, sizeof(nir_block *),
1212b8e80941Smrg         compare_block_index);
1213b8e80941Smrg
1214b8e80941Smrg   print_tabs(tabs, fp);
1215b8e80941Smrg   fprintf(fp, "/* preds: ");
1216b8e80941Smrg   for (unsigned i = 0; i < block->predecessors->entries; i++) {
1217b8e80941Smrg      fprintf(fp, "block_%u ", preds[i]->index);
1218b8e80941Smrg   }
1219b8e80941Smrg   fprintf(fp, "*/\n");
1220b8e80941Smrg
1221b8e80941Smrg   free(preds);
1222b8e80941Smrg
1223b8e80941Smrg   nir_foreach_instr(instr, block) {
1224b8e80941Smrg      print_instr(instr, state, tabs);
1225b8e80941Smrg      fprintf(fp, "\n");
1226b8e80941Smrg      print_annotation(state, instr);
1227b8e80941Smrg   }
1228b8e80941Smrg
1229b8e80941Smrg   print_tabs(tabs, fp);
1230b8e80941Smrg   fprintf(fp, "/* succs: ");
1231b8e80941Smrg   for (unsigned i = 0; i < 2; i++)
1232b8e80941Smrg      if (block->successors[i]) {
1233b8e80941Smrg         fprintf(fp, "block_%u ", block->successors[i]->index);
1234b8e80941Smrg      }
1235b8e80941Smrg   fprintf(fp, "*/\n");
1236b8e80941Smrg}
1237b8e80941Smrg
1238b8e80941Smrgstatic void
1239b8e80941Smrgprint_if(nir_if *if_stmt, print_state *state, unsigned tabs)
1240b8e80941Smrg{
1241b8e80941Smrg   FILE *fp = state->fp;
1242b8e80941Smrg
1243b8e80941Smrg   print_tabs(tabs, fp);
1244b8e80941Smrg   fprintf(fp, "if ");
1245b8e80941Smrg   print_src(&if_stmt->condition, state);
1246b8e80941Smrg   fprintf(fp, " {\n");
1247b8e80941Smrg   foreach_list_typed(nir_cf_node, node, node, &if_stmt->then_list) {
1248b8e80941Smrg      print_cf_node(node, state, tabs + 1);
1249b8e80941Smrg   }
1250b8e80941Smrg   print_tabs(tabs, fp);
1251b8e80941Smrg   fprintf(fp, "} else {\n");
1252b8e80941Smrg   foreach_list_typed(nir_cf_node, node, node, &if_stmt->else_list) {
1253b8e80941Smrg      print_cf_node(node, state, tabs + 1);
1254b8e80941Smrg   }
1255b8e80941Smrg   print_tabs(tabs, fp);
1256b8e80941Smrg   fprintf(fp, "}\n");
1257b8e80941Smrg}
1258b8e80941Smrg
1259b8e80941Smrgstatic void
1260b8e80941Smrgprint_loop(nir_loop *loop, print_state *state, unsigned tabs)
1261b8e80941Smrg{
1262b8e80941Smrg   FILE *fp = state->fp;
1263b8e80941Smrg
1264b8e80941Smrg   print_tabs(tabs, fp);
1265b8e80941Smrg   fprintf(fp, "loop {\n");
1266b8e80941Smrg   foreach_list_typed(nir_cf_node, node, node, &loop->body) {
1267b8e80941Smrg      print_cf_node(node, state, tabs + 1);
1268b8e80941Smrg   }
1269b8e80941Smrg   print_tabs(tabs, fp);
1270b8e80941Smrg   fprintf(fp, "}\n");
1271b8e80941Smrg}
1272b8e80941Smrg
1273b8e80941Smrgstatic void
1274b8e80941Smrgprint_cf_node(nir_cf_node *node, print_state *state, unsigned int tabs)
1275b8e80941Smrg{
1276b8e80941Smrg   switch (node->type) {
1277b8e80941Smrg   case nir_cf_node_block:
1278b8e80941Smrg      print_block(nir_cf_node_as_block(node), state, tabs);
1279b8e80941Smrg      break;
1280b8e80941Smrg
1281b8e80941Smrg   case nir_cf_node_if:
1282b8e80941Smrg      print_if(nir_cf_node_as_if(node), state, tabs);
1283b8e80941Smrg      break;
1284b8e80941Smrg
1285b8e80941Smrg   case nir_cf_node_loop:
1286b8e80941Smrg      print_loop(nir_cf_node_as_loop(node), state, tabs);
1287b8e80941Smrg      break;
1288b8e80941Smrg
1289b8e80941Smrg   default:
1290b8e80941Smrg      unreachable("Invalid CFG node type");
1291b8e80941Smrg   }
1292b8e80941Smrg}
1293b8e80941Smrg
1294b8e80941Smrgstatic void
1295b8e80941Smrgprint_function_impl(nir_function_impl *impl, print_state *state)
1296b8e80941Smrg{
1297b8e80941Smrg   FILE *fp = state->fp;
1298b8e80941Smrg
1299b8e80941Smrg   fprintf(fp, "\nimpl %s ", impl->function->name);
1300b8e80941Smrg
1301b8e80941Smrg   fprintf(fp, "{\n");
1302b8e80941Smrg
1303b8e80941Smrg   nir_foreach_variable(var, &impl->locals) {
1304b8e80941Smrg      fprintf(fp, "\t");
1305b8e80941Smrg      print_var_decl(var, state);
1306b8e80941Smrg   }
1307b8e80941Smrg
1308b8e80941Smrg   foreach_list_typed(nir_register, reg, node, &impl->registers) {
1309b8e80941Smrg      fprintf(fp, "\t");
1310b8e80941Smrg      print_register_decl(reg, state);
1311b8e80941Smrg   }
1312b8e80941Smrg
1313b8e80941Smrg   nir_index_blocks(impl);
1314b8e80941Smrg
1315b8e80941Smrg   foreach_list_typed(nir_cf_node, node, node, &impl->body) {
1316b8e80941Smrg      print_cf_node(node, state, 1);
1317b8e80941Smrg   }
1318b8e80941Smrg
1319b8e80941Smrg   fprintf(fp, "\tblock block_%u:\n}\n\n", impl->end_block->index);
1320b8e80941Smrg}
1321b8e80941Smrg
1322b8e80941Smrgstatic void
1323b8e80941Smrgprint_function(nir_function *function, print_state *state)
1324b8e80941Smrg{
1325b8e80941Smrg   FILE *fp = state->fp;
1326b8e80941Smrg
1327b8e80941Smrg   fprintf(fp, "decl_function %s (%d params)", function->name,
1328b8e80941Smrg           function->num_params);
1329b8e80941Smrg
1330b8e80941Smrg   fprintf(fp, "\n");
1331b8e80941Smrg
1332b8e80941Smrg   if (function->impl != NULL) {
1333b8e80941Smrg      print_function_impl(function->impl, state);
1334b8e80941Smrg      return;
1335b8e80941Smrg   }
1336b8e80941Smrg}
1337b8e80941Smrg
1338b8e80941Smrgstatic void
1339b8e80941Smrginit_print_state(print_state *state, nir_shader *shader, FILE *fp)
1340b8e80941Smrg{
1341b8e80941Smrg   state->fp = fp;
1342b8e80941Smrg   state->shader = shader;
1343b8e80941Smrg   state->ht = _mesa_pointer_hash_table_create(NULL);
1344b8e80941Smrg   state->syms = _mesa_set_create(NULL, _mesa_key_hash_string,
1345b8e80941Smrg                                  _mesa_key_string_equal);
1346b8e80941Smrg   state->index = 0;
1347b8e80941Smrg}
1348b8e80941Smrg
1349b8e80941Smrgstatic void
1350b8e80941Smrgdestroy_print_state(print_state *state)
1351b8e80941Smrg{
1352b8e80941Smrg   _mesa_hash_table_destroy(state->ht, NULL);
1353b8e80941Smrg   _mesa_set_destroy(state->syms, NULL);
1354b8e80941Smrg}
1355b8e80941Smrg
1356b8e80941Smrgvoid
1357b8e80941Smrgnir_print_shader_annotated(nir_shader *shader, FILE *fp,
1358b8e80941Smrg                           struct hash_table *annotations)
1359b8e80941Smrg{
1360b8e80941Smrg   print_state state;
1361b8e80941Smrg   init_print_state(&state, shader, fp);
1362b8e80941Smrg
1363b8e80941Smrg   state.annotations = annotations;
1364b8e80941Smrg
1365b8e80941Smrg   fprintf(fp, "shader: %s\n", gl_shader_stage_name(shader->info.stage));
1366b8e80941Smrg
1367b8e80941Smrg   if (shader->info.name)
1368b8e80941Smrg      fprintf(fp, "name: %s\n", shader->info.name);
1369b8e80941Smrg
1370b8e80941Smrg   if (shader->info.label)
1371b8e80941Smrg      fprintf(fp, "label: %s\n", shader->info.label);
1372b8e80941Smrg
1373b8e80941Smrg   if (gl_shader_stage_is_compute(shader->info.stage)) {
1374b8e80941Smrg      fprintf(fp, "local-size: %u, %u, %u%s\n",
1375b8e80941Smrg              shader->info.cs.local_size[0],
1376b8e80941Smrg              shader->info.cs.local_size[1],
1377b8e80941Smrg              shader->info.cs.local_size[2],
1378b8e80941Smrg              shader->info.cs.local_size_variable ? " (variable)" : "");
1379b8e80941Smrg      fprintf(fp, "shared-size: %u\n", shader->info.cs.shared_size);
1380b8e80941Smrg   }
1381b8e80941Smrg
1382b8e80941Smrg   fprintf(fp, "inputs: %u\n", shader->num_inputs);
1383b8e80941Smrg   fprintf(fp, "outputs: %u\n", shader->num_outputs);
1384b8e80941Smrg   fprintf(fp, "uniforms: %u\n", shader->num_uniforms);
1385b8e80941Smrg   fprintf(fp, "shared: %u\n", shader->num_shared);
1386b8e80941Smrg   if (shader->scratch_size)
1387b8e80941Smrg      fprintf(fp, "scratch: %u\n", shader->scratch_size);
1388b8e80941Smrg
1389b8e80941Smrg   nir_foreach_variable(var, &shader->uniforms) {
1390b8e80941Smrg      print_var_decl(var, &state);
1391b8e80941Smrg   }
1392b8e80941Smrg
1393b8e80941Smrg   nir_foreach_variable(var, &shader->inputs) {
1394b8e80941Smrg      print_var_decl(var, &state);
1395b8e80941Smrg   }
1396b8e80941Smrg
1397b8e80941Smrg   nir_foreach_variable(var, &shader->outputs) {
1398b8e80941Smrg      print_var_decl(var, &state);
1399b8e80941Smrg   }
1400b8e80941Smrg
1401b8e80941Smrg   nir_foreach_variable(var, &shader->shared) {
1402b8e80941Smrg      print_var_decl(var, &state);
1403b8e80941Smrg   }
1404b8e80941Smrg
1405b8e80941Smrg   nir_foreach_variable(var, &shader->globals) {
1406b8e80941Smrg      print_var_decl(var, &state);
1407b8e80941Smrg   }
1408b8e80941Smrg
1409b8e80941Smrg   nir_foreach_variable(var, &shader->system_values) {
1410b8e80941Smrg      print_var_decl(var, &state);
1411b8e80941Smrg   }
1412b8e80941Smrg
1413b8e80941Smrg   foreach_list_typed(nir_function, func, node, &shader->functions) {
1414b8e80941Smrg      print_function(func, &state);
1415b8e80941Smrg   }
1416b8e80941Smrg
1417b8e80941Smrg   destroy_print_state(&state);
1418b8e80941Smrg}
1419b8e80941Smrg
1420b8e80941Smrgvoid
1421b8e80941Smrgnir_print_shader(nir_shader *shader, FILE *fp)
1422b8e80941Smrg{
1423b8e80941Smrg   nir_print_shader_annotated(shader, fp, NULL);
1424b8e80941Smrg   fflush(fp);
1425b8e80941Smrg}
1426b8e80941Smrg
1427b8e80941Smrgvoid
1428b8e80941Smrgnir_print_instr(const nir_instr *instr, FILE *fp)
1429b8e80941Smrg{
1430b8e80941Smrg   print_state state = {
1431b8e80941Smrg      .fp = fp,
1432b8e80941Smrg   };
1433b8e80941Smrg   print_instr(instr, &state, 0);
1434b8e80941Smrg
1435b8e80941Smrg}
1436b8e80941Smrg
1437b8e80941Smrgvoid
1438b8e80941Smrgnir_print_deref(const nir_deref_instr *deref, FILE *fp)
1439b8e80941Smrg{
1440b8e80941Smrg   print_state state = {
1441b8e80941Smrg      .fp = fp,
1442b8e80941Smrg   };
1443b8e80941Smrg   print_deref_link(deref, true, &state);
1444b8e80941Smrg}
1445