101e04c3fSmrg/*
201e04c3fSmrg * Copyright © 2014 Intel Corporation
301e04c3fSmrg *
401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a
501e04c3fSmrg * copy of this software and associated documentation files (the "Software"),
601e04c3fSmrg * to deal in the Software without restriction, including without limitation
701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the
901e04c3fSmrg * Software is furnished to do so, subject to the following conditions:
1001e04c3fSmrg *
1101e04c3fSmrg * The above copyright notice and this permission notice (including the next
1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the
1301e04c3fSmrg * Software.
1401e04c3fSmrg *
1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
2101e04c3fSmrg * IN THE SOFTWARE.
2201e04c3fSmrg *
2301e04c3fSmrg * Authors:
2401e04c3fSmrg *    Connor Abbott (cwabbott0@gmail.com)
2501e04c3fSmrg *
2601e04c3fSmrg */
2701e04c3fSmrg
2801e04c3fSmrg#include "nir.h"
2901e04c3fSmrg#include "compiler/shader_enums.h"
3001e04c3fSmrg#include "util/half_float.h"
317ec681f3Smrg#include "util/memstream.h"
327e102996Smaya#include "vulkan/vulkan_core.h"
3301e04c3fSmrg#include <stdio.h>
3401e04c3fSmrg#include <stdlib.h>
3501e04c3fSmrg#include <inttypes.h> /* for PRIx64 macro */
3601e04c3fSmrg
3701e04c3fSmrgstatic void
3801e04c3fSmrgprint_tabs(unsigned num_tabs, FILE *fp)
3901e04c3fSmrg{
4001e04c3fSmrg   for (unsigned i = 0; i < num_tabs; i++)
4101e04c3fSmrg      fprintf(fp, "\t");
4201e04c3fSmrg}
4301e04c3fSmrg
4401e04c3fSmrgtypedef struct {
4501e04c3fSmrg   FILE *fp;
4601e04c3fSmrg   nir_shader *shader;
4701e04c3fSmrg   /** map from nir_variable -> printable name */
4801e04c3fSmrg   struct hash_table *ht;
4901e04c3fSmrg
5001e04c3fSmrg   /** set of names used so far for nir_variables */
5101e04c3fSmrg   struct set *syms;
5201e04c3fSmrg
5301e04c3fSmrg   /* an index used to make new non-conflicting names */
5401e04c3fSmrg   unsigned index;
5501e04c3fSmrg
5601e04c3fSmrg   /**
5701e04c3fSmrg    * Optional table of annotations mapping nir object
5801e04c3fSmrg    * (such as instr or var) to message to print.
5901e04c3fSmrg    */
6001e04c3fSmrg   struct hash_table *annotations;
6101e04c3fSmrg} print_state;
6201e04c3fSmrg
6301e04c3fSmrgstatic void
6401e04c3fSmrgprint_annotation(print_state *state, void *obj)
6501e04c3fSmrg{
667ec681f3Smrg   FILE *fp = state->fp;
677ec681f3Smrg
6801e04c3fSmrg   if (!state->annotations)
6901e04c3fSmrg      return;
7001e04c3fSmrg
7101e04c3fSmrg   struct hash_entry *entry = _mesa_hash_table_search(state->annotations, obj);
7201e04c3fSmrg   if (!entry)
7301e04c3fSmrg      return;
7401e04c3fSmrg
7501e04c3fSmrg   const char *note = entry->data;
7601e04c3fSmrg   _mesa_hash_table_remove(state->annotations, entry);
7701e04c3fSmrg
787ec681f3Smrg   fprintf(fp, "%s\n\n", note);
7901e04c3fSmrg}
8001e04c3fSmrg
8101e04c3fSmrgstatic void
8201e04c3fSmrgprint_register(nir_register *reg, print_state *state)
8301e04c3fSmrg{
8401e04c3fSmrg   FILE *fp = state->fp;
857e102996Smaya   fprintf(fp, "r%u", reg->index);
8601e04c3fSmrg}
8701e04c3fSmrg
8801e04c3fSmrgstatic const char *sizes[] = { "error", "vec1", "vec2", "vec3", "vec4",
897ec681f3Smrg                               "vec5", "error", "error", "vec8",
9001e04c3fSmrg                               "error", "error", "error", "error",
9101e04c3fSmrg                               "error", "error", "error", "vec16"};
9201e04c3fSmrg
9301e04c3fSmrgstatic void
9401e04c3fSmrgprint_register_decl(nir_register *reg, print_state *state)
9501e04c3fSmrg{
9601e04c3fSmrg   FILE *fp = state->fp;
9701e04c3fSmrg   fprintf(fp, "decl_reg %s %u ", sizes[reg->num_components], reg->bit_size);
9801e04c3fSmrg   print_register(reg, state);
9901e04c3fSmrg   if (reg->num_array_elems != 0)
10001e04c3fSmrg      fprintf(fp, "[%u]", reg->num_array_elems);
10101e04c3fSmrg   fprintf(fp, "\n");
10201e04c3fSmrg}
10301e04c3fSmrg
10401e04c3fSmrgstatic void
10501e04c3fSmrgprint_ssa_def(nir_ssa_def *def, print_state *state)
10601e04c3fSmrg{
10701e04c3fSmrg   FILE *fp = state->fp;
10801e04c3fSmrg   fprintf(fp, "%s %u ssa_%u", sizes[def->num_components], def->bit_size,
10901e04c3fSmrg           def->index);
11001e04c3fSmrg}
11101e04c3fSmrg
11201e04c3fSmrgstatic void
11301e04c3fSmrgprint_ssa_use(nir_ssa_def *def, print_state *state)
11401e04c3fSmrg{
11501e04c3fSmrg   FILE *fp = state->fp;
11601e04c3fSmrg   fprintf(fp, "ssa_%u", def->index);
11701e04c3fSmrg}
11801e04c3fSmrg
1197e102996Smayastatic void print_src(const nir_src *src, print_state *state);
12001e04c3fSmrg
12101e04c3fSmrgstatic void
1227e102996Smayaprint_reg_src(const nir_reg_src *src, print_state *state)
12301e04c3fSmrg{
12401e04c3fSmrg   FILE *fp = state->fp;
12501e04c3fSmrg   print_register(src->reg, state);
12601e04c3fSmrg   if (src->reg->num_array_elems != 0) {
12701e04c3fSmrg      fprintf(fp, "[%u", src->base_offset);
12801e04c3fSmrg      if (src->indirect != NULL) {
12901e04c3fSmrg         fprintf(fp, " + ");
13001e04c3fSmrg         print_src(src->indirect, state);
13101e04c3fSmrg      }
13201e04c3fSmrg      fprintf(fp, "]");
13301e04c3fSmrg   }
13401e04c3fSmrg}
13501e04c3fSmrg
13601e04c3fSmrgstatic void
13701e04c3fSmrgprint_reg_dest(nir_reg_dest *dest, print_state *state)
13801e04c3fSmrg{
13901e04c3fSmrg   FILE *fp = state->fp;
14001e04c3fSmrg   print_register(dest->reg, state);
14101e04c3fSmrg   if (dest->reg->num_array_elems != 0) {
14201e04c3fSmrg      fprintf(fp, "[%u", dest->base_offset);
14301e04c3fSmrg      if (dest->indirect != NULL) {
14401e04c3fSmrg         fprintf(fp, " + ");
14501e04c3fSmrg         print_src(dest->indirect, state);
14601e04c3fSmrg      }
14701e04c3fSmrg      fprintf(fp, "]");
14801e04c3fSmrg   }
14901e04c3fSmrg}
15001e04c3fSmrg
15101e04c3fSmrgstatic void
1527e102996Smayaprint_src(const nir_src *src, print_state *state)
15301e04c3fSmrg{
15401e04c3fSmrg   if (src->is_ssa)
15501e04c3fSmrg      print_ssa_use(src->ssa, state);
15601e04c3fSmrg   else
15701e04c3fSmrg      print_reg_src(&src->reg, state);
15801e04c3fSmrg}
15901e04c3fSmrg
16001e04c3fSmrgstatic void
16101e04c3fSmrgprint_dest(nir_dest *dest, print_state *state)
16201e04c3fSmrg{
16301e04c3fSmrg   if (dest->is_ssa)
16401e04c3fSmrg      print_ssa_def(&dest->ssa, state);
16501e04c3fSmrg   else
16601e04c3fSmrg      print_reg_dest(&dest->reg, state);
16701e04c3fSmrg}
16801e04c3fSmrg
1697ec681f3Smrgstatic const char *
1707ec681f3Smrgcomp_mask_string(unsigned num_components)
1717ec681f3Smrg{
1727ec681f3Smrg   return (num_components > 4) ? "abcdefghijklmnop" : "xyzw";
1737ec681f3Smrg}
1747ec681f3Smrg
17501e04c3fSmrgstatic void
17601e04c3fSmrgprint_alu_src(nir_alu_instr *instr, unsigned src, print_state *state)
17701e04c3fSmrg{
17801e04c3fSmrg   FILE *fp = state->fp;
17901e04c3fSmrg
18001e04c3fSmrg   if (instr->src[src].negate)
18101e04c3fSmrg      fprintf(fp, "-");
18201e04c3fSmrg   if (instr->src[src].abs)
18301e04c3fSmrg      fprintf(fp, "abs(");
18401e04c3fSmrg
18501e04c3fSmrg   print_src(&instr->src[src].src, state);
18601e04c3fSmrg
18701e04c3fSmrg   bool print_swizzle = false;
18801e04c3fSmrg   nir_component_mask_t used_channels = 0;
18901e04c3fSmrg
19001e04c3fSmrg   for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++) {
19101e04c3fSmrg      if (!nir_alu_instr_channel_used(instr, src, i))
19201e04c3fSmrg         continue;
19301e04c3fSmrg
19401e04c3fSmrg      used_channels++;
19501e04c3fSmrg
19601e04c3fSmrg      if (instr->src[src].swizzle[i] != i) {
19701e04c3fSmrg         print_swizzle = true;
19801e04c3fSmrg         break;
19901e04c3fSmrg      }
20001e04c3fSmrg   }
20101e04c3fSmrg
20201e04c3fSmrg   unsigned live_channels = nir_src_num_components(instr->src[src].src);
20301e04c3fSmrg
20401e04c3fSmrg   if (print_swizzle || used_channels != live_channels) {
20501e04c3fSmrg      fprintf(fp, ".");
20601e04c3fSmrg      for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++) {
20701e04c3fSmrg         if (!nir_alu_instr_channel_used(instr, src, i))
20801e04c3fSmrg            continue;
20901e04c3fSmrg
2107ec681f3Smrg         fprintf(fp, "%c", comp_mask_string(live_channels)[instr->src[src].swizzle[i]]);
21101e04c3fSmrg      }
21201e04c3fSmrg   }
21301e04c3fSmrg
21401e04c3fSmrg   if (instr->src[src].abs)
21501e04c3fSmrg      fprintf(fp, ")");
21601e04c3fSmrg}
21701e04c3fSmrg
21801e04c3fSmrgstatic void
21901e04c3fSmrgprint_alu_dest(nir_alu_dest *dest, print_state *state)
22001e04c3fSmrg{
22101e04c3fSmrg   FILE *fp = state->fp;
22201e04c3fSmrg   /* we're going to print the saturate modifier later, after the opcode */
22301e04c3fSmrg
22401e04c3fSmrg   print_dest(&dest->dest, state);
22501e04c3fSmrg
22601e04c3fSmrg   if (!dest->dest.is_ssa &&
22701e04c3fSmrg       dest->write_mask != (1 << dest->dest.reg.reg->num_components) - 1) {
2287ec681f3Smrg      unsigned live_channels = dest->dest.reg.reg->num_components;
22901e04c3fSmrg      fprintf(fp, ".");
23001e04c3fSmrg      for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++)
23101e04c3fSmrg         if ((dest->write_mask >> i) & 1)
2327ec681f3Smrg            fprintf(fp, "%c", comp_mask_string(live_channels)[i]);
23301e04c3fSmrg   }
23401e04c3fSmrg}
23501e04c3fSmrg
23601e04c3fSmrgstatic void
23701e04c3fSmrgprint_alu_instr(nir_alu_instr *instr, print_state *state)
23801e04c3fSmrg{
23901e04c3fSmrg   FILE *fp = state->fp;
24001e04c3fSmrg
24101e04c3fSmrg   print_alu_dest(&instr->dest, state);
24201e04c3fSmrg
24301e04c3fSmrg   fprintf(fp, " = %s", nir_op_infos[instr->op].name);
24401e04c3fSmrg   if (instr->exact)
24501e04c3fSmrg      fprintf(fp, "!");
24601e04c3fSmrg   if (instr->dest.saturate)
24701e04c3fSmrg      fprintf(fp, ".sat");
2487ec681f3Smrg   if (instr->no_signed_wrap)
2497ec681f3Smrg      fprintf(fp, ".nsw");
2507ec681f3Smrg   if (instr->no_unsigned_wrap)
2517ec681f3Smrg      fprintf(fp, ".nuw");
25201e04c3fSmrg   fprintf(fp, " ");
25301e04c3fSmrg
25401e04c3fSmrg   for (unsigned i = 0; i < nir_op_infos[instr->op].num_inputs; i++) {
25501e04c3fSmrg      if (i != 0)
25601e04c3fSmrg         fprintf(fp, ", ");
25701e04c3fSmrg
25801e04c3fSmrg      print_alu_src(instr, i, state);
25901e04c3fSmrg   }
26001e04c3fSmrg}
26101e04c3fSmrg
26201e04c3fSmrgstatic const char *
26301e04c3fSmrgget_var_name(nir_variable *var, print_state *state)
26401e04c3fSmrg{
26501e04c3fSmrg   if (state->ht == NULL)
26601e04c3fSmrg      return var->name ? var->name : "unnamed";
26701e04c3fSmrg
26801e04c3fSmrg   assert(state->syms);
26901e04c3fSmrg
27001e04c3fSmrg   struct hash_entry *entry = _mesa_hash_table_search(state->ht, var);
27101e04c3fSmrg   if (entry)
27201e04c3fSmrg      return entry->data;
27301e04c3fSmrg
27401e04c3fSmrg   char *name;
27501e04c3fSmrg   if (var->name == NULL) {
27601e04c3fSmrg      name = ralloc_asprintf(state->syms, "@%u", state->index++);
27701e04c3fSmrg   } else {
27801e04c3fSmrg      struct set_entry *set_entry = _mesa_set_search(state->syms, var->name);
27901e04c3fSmrg      if (set_entry != NULL) {
28001e04c3fSmrg         /* we have a collision with another name, append an @ + a unique
28101e04c3fSmrg          * index */
28201e04c3fSmrg         name = ralloc_asprintf(state->syms, "%s@%u", var->name,
28301e04c3fSmrg                                state->index++);
28401e04c3fSmrg      } else {
28501e04c3fSmrg         /* Mark this one as seen */
28601e04c3fSmrg         _mesa_set_add(state->syms, var->name);
28701e04c3fSmrg         name = var->name;
28801e04c3fSmrg      }
28901e04c3fSmrg   }
29001e04c3fSmrg
29101e04c3fSmrg   _mesa_hash_table_insert(state->ht, var, name);
29201e04c3fSmrg
29301e04c3fSmrg   return name;
29401e04c3fSmrg}
29501e04c3fSmrg
2967ec681f3Smrgstatic const char *
2977ec681f3Smrgget_constant_sampler_addressing_mode(enum cl_sampler_addressing_mode mode)
2987ec681f3Smrg{
2997ec681f3Smrg   switch (mode) {
3007ec681f3Smrg   case SAMPLER_ADDRESSING_MODE_NONE: return "none";
3017ec681f3Smrg   case SAMPLER_ADDRESSING_MODE_CLAMP_TO_EDGE: return "clamp_to_edge";
3027ec681f3Smrg   case SAMPLER_ADDRESSING_MODE_CLAMP: return "clamp";
3037ec681f3Smrg   case SAMPLER_ADDRESSING_MODE_REPEAT: return "repeat";
3047ec681f3Smrg   case SAMPLER_ADDRESSING_MODE_REPEAT_MIRRORED: return "repeat_mirrored";
3057ec681f3Smrg   default: unreachable("Invalid addressing mode");
3067ec681f3Smrg   }
3077ec681f3Smrg}
3087ec681f3Smrg
3097ec681f3Smrgstatic const char *
3107ec681f3Smrgget_constant_sampler_filter_mode(enum cl_sampler_filter_mode mode)
3117ec681f3Smrg{
3127ec681f3Smrg   switch (mode) {
3137ec681f3Smrg   case SAMPLER_FILTER_MODE_NEAREST: return "nearest";
3147ec681f3Smrg   case SAMPLER_FILTER_MODE_LINEAR: return "linear";
3157ec681f3Smrg   default: unreachable("Invalid filter mode");
3167ec681f3Smrg   }
3177ec681f3Smrg}
3187ec681f3Smrg
31901e04c3fSmrgstatic void
32001e04c3fSmrgprint_constant(nir_constant *c, const struct glsl_type *type, print_state *state)
32101e04c3fSmrg{
32201e04c3fSmrg   FILE *fp = state->fp;
32301e04c3fSmrg   const unsigned rows = glsl_get_vector_elements(type);
32401e04c3fSmrg   const unsigned cols = glsl_get_matrix_columns(type);
3257ec681f3Smrg   unsigned i;
32601e04c3fSmrg
32701e04c3fSmrg   switch (glsl_get_base_type(type)) {
3287e102996Smaya   case GLSL_TYPE_BOOL:
3297e102996Smaya      /* Only float base types can be matrices. */
3307e102996Smaya      assert(cols == 1);
3317e102996Smaya
3327e102996Smaya      for (i = 0; i < rows; i++) {
3337e102996Smaya         if (i > 0) fprintf(fp, ", ");
3347ec681f3Smrg         fprintf(fp, "%s", c->values[i].b ? "true" : "false");
3357e102996Smaya      }
3367e102996Smaya      break;
3377e102996Smaya
33801e04c3fSmrg   case GLSL_TYPE_UINT8:
33901e04c3fSmrg   case GLSL_TYPE_INT8:
34001e04c3fSmrg      /* Only float base types can be matrices. */
34101e04c3fSmrg      assert(cols == 1);
34201e04c3fSmrg
34301e04c3fSmrg      for (i = 0; i < rows; i++) {
34401e04c3fSmrg         if (i > 0) fprintf(fp, ", ");
3457ec681f3Smrg         fprintf(fp, "0x%02x", c->values[i].u8);
34601e04c3fSmrg      }
34701e04c3fSmrg      break;
34801e04c3fSmrg
34901e04c3fSmrg   case GLSL_TYPE_UINT16:
35001e04c3fSmrg   case GLSL_TYPE_INT16:
35101e04c3fSmrg      /* Only float base types can be matrices. */
35201e04c3fSmrg      assert(cols == 1);
35301e04c3fSmrg
35401e04c3fSmrg      for (i = 0; i < rows; i++) {
35501e04c3fSmrg         if (i > 0) fprintf(fp, ", ");
3567ec681f3Smrg         fprintf(fp, "0x%04x", c->values[i].u16);
35701e04c3fSmrg      }
35801e04c3fSmrg      break;
35901e04c3fSmrg
36001e04c3fSmrg   case GLSL_TYPE_UINT:
36101e04c3fSmrg   case GLSL_TYPE_INT:
36201e04c3fSmrg      /* Only float base types can be matrices. */
36301e04c3fSmrg      assert(cols == 1);
36401e04c3fSmrg
36501e04c3fSmrg      for (i = 0; i < rows; i++) {
36601e04c3fSmrg         if (i > 0) fprintf(fp, ", ");
3677ec681f3Smrg         fprintf(fp, "0x%08x", c->values[i].u32);
36801e04c3fSmrg      }
36901e04c3fSmrg      break;
37001e04c3fSmrg
37101e04c3fSmrg   case GLSL_TYPE_FLOAT16:
37201e04c3fSmrg   case GLSL_TYPE_FLOAT:
37301e04c3fSmrg   case GLSL_TYPE_DOUBLE:
3747ec681f3Smrg      if (cols > 1) {
3757ec681f3Smrg         for (i = 0; i < cols; i++) {
3767ec681f3Smrg            if (i > 0) fprintf(fp, ", ");
3777ec681f3Smrg            print_constant(c->elements[i], glsl_get_column_type(type), state);
3787ec681f3Smrg         }
3797ec681f3Smrg      } else {
3807ec681f3Smrg         switch (glsl_get_base_type(type)) {
3817ec681f3Smrg         case GLSL_TYPE_FLOAT16:
3827ec681f3Smrg            for (i = 0; i < rows; i++) {
3837ec681f3Smrg               if (i > 0) fprintf(fp, ", ");
3847ec681f3Smrg               fprintf(fp, "%f", _mesa_half_to_float(c->values[i].u16));
3857ec681f3Smrg            }
3867ec681f3Smrg            break;
3877ec681f3Smrg
3887ec681f3Smrg         case GLSL_TYPE_FLOAT:
3897ec681f3Smrg            for (i = 0; i < rows; i++) {
3907ec681f3Smrg               if (i > 0) fprintf(fp, ", ");
3917ec681f3Smrg               fprintf(fp, "%f", c->values[i].f32);
3927ec681f3Smrg            }
3937ec681f3Smrg            break;
3947ec681f3Smrg
3957ec681f3Smrg         case GLSL_TYPE_DOUBLE:
3967ec681f3Smrg            for (i = 0; i < rows; i++) {
3977ec681f3Smrg               if (i > 0) fprintf(fp, ", ");
3987ec681f3Smrg               fprintf(fp, "%f", c->values[i].f64);
3997ec681f3Smrg            }
4007ec681f3Smrg            break;
4017ec681f3Smrg
4027ec681f3Smrg         default:
4037ec681f3Smrg            unreachable("Cannot get here from the first level switch");
40401e04c3fSmrg         }
40501e04c3fSmrg      }
40601e04c3fSmrg      break;
40701e04c3fSmrg
40801e04c3fSmrg   case GLSL_TYPE_UINT64:
40901e04c3fSmrg   case GLSL_TYPE_INT64:
41001e04c3fSmrg      /* Only float base types can be matrices. */
41101e04c3fSmrg      assert(cols == 1);
41201e04c3fSmrg
41301e04c3fSmrg      for (i = 0; i < cols; i++) {
41401e04c3fSmrg         if (i > 0) fprintf(fp, ", ");
4157ec681f3Smrg         fprintf(fp, "0x%08" PRIx64, c->values[i].u64);
41601e04c3fSmrg      }
41701e04c3fSmrg      break;
41801e04c3fSmrg
41901e04c3fSmrg   case GLSL_TYPE_STRUCT:
4207ec681f3Smrg   case GLSL_TYPE_INTERFACE:
42101e04c3fSmrg      for (i = 0; i < c->num_elements; i++) {
42201e04c3fSmrg         if (i > 0) fprintf(fp, ", ");
42301e04c3fSmrg         fprintf(fp, "{ ");
42401e04c3fSmrg         print_constant(c->elements[i], glsl_get_struct_field(type, i), state);
42501e04c3fSmrg         fprintf(fp, " }");
42601e04c3fSmrg      }
42701e04c3fSmrg      break;
42801e04c3fSmrg
42901e04c3fSmrg   case GLSL_TYPE_ARRAY:
43001e04c3fSmrg      for (i = 0; i < c->num_elements; i++) {
43101e04c3fSmrg         if (i > 0) fprintf(fp, ", ");
43201e04c3fSmrg         fprintf(fp, "{ ");
43301e04c3fSmrg         print_constant(c->elements[i], glsl_get_array_element(type), state);
43401e04c3fSmrg         fprintf(fp, " }");
43501e04c3fSmrg      }
43601e04c3fSmrg      break;
43701e04c3fSmrg
43801e04c3fSmrg   default:
43901e04c3fSmrg      unreachable("not reached");
44001e04c3fSmrg   }
44101e04c3fSmrg}
44201e04c3fSmrg
44301e04c3fSmrgstatic const char *
44401e04c3fSmrgget_variable_mode_str(nir_variable_mode mode, bool want_local_global_mode)
44501e04c3fSmrg{
44601e04c3fSmrg   switch (mode) {
44701e04c3fSmrg   case nir_var_shader_in:
44801e04c3fSmrg      return "shader_in";
44901e04c3fSmrg   case nir_var_shader_out:
45001e04c3fSmrg      return "shader_out";
45101e04c3fSmrg   case nir_var_uniform:
45201e04c3fSmrg      return "uniform";
4537e102996Smaya   case nir_var_mem_ubo:
4547e102996Smaya      return "ubo";
45501e04c3fSmrg   case nir_var_system_value:
45601e04c3fSmrg      return "system";
4577e102996Smaya   case nir_var_mem_ssbo:
4587e102996Smaya      return "ssbo";
4597e102996Smaya   case nir_var_mem_shared:
46001e04c3fSmrg      return "shared";
4617e102996Smaya   case nir_var_mem_global:
4627e102996Smaya      return "global";
4637ec681f3Smrg   case nir_var_mem_push_const:
4647ec681f3Smrg      return "push_const";
4657ec681f3Smrg   case nir_var_mem_constant:
4667ec681f3Smrg      return "constant";
4677e102996Smaya   case nir_var_shader_temp:
4687e102996Smaya      return want_local_global_mode ? "shader_temp" : "";
4697e102996Smaya   case nir_var_function_temp:
4707e102996Smaya      return want_local_global_mode ? "function_temp" : "";
4717ec681f3Smrg   case nir_var_shader_call_data:
4727ec681f3Smrg      return "shader_call_data";
4737ec681f3Smrg   case nir_var_ray_hit_attrib:
4747ec681f3Smrg      return "ray_hit_attrib";
47501e04c3fSmrg   default:
47601e04c3fSmrg      return "";
47701e04c3fSmrg   }
47801e04c3fSmrg}
47901e04c3fSmrg
48001e04c3fSmrgstatic void
48101e04c3fSmrgprint_var_decl(nir_variable *var, print_state *state)
48201e04c3fSmrg{
48301e04c3fSmrg   FILE *fp = state->fp;
48401e04c3fSmrg
48501e04c3fSmrg   fprintf(fp, "decl_var ");
48601e04c3fSmrg
48701e04c3fSmrg   const char *const cent = (var->data.centroid) ? "centroid " : "";
48801e04c3fSmrg   const char *const samp = (var->data.sample) ? "sample " : "";
48901e04c3fSmrg   const char *const patch = (var->data.patch) ? "patch " : "";
49001e04c3fSmrg   const char *const inv = (var->data.invariant) ? "invariant " : "";
4917ec681f3Smrg   const char *const per_view = (var->data.per_view) ? "per_view " : "";
4927ec681f3Smrg   const char *const per_primitive = (var->data.per_primitive) ? "per_primitive " : "";
4937ec681f3Smrg   fprintf(fp, "%s%s%s%s%s%s%s %s ",
4947ec681f3Smrg           cent, samp, patch, inv, per_view, per_primitive,
4957ec681f3Smrg           get_variable_mode_str(var->data.mode, false),
49601e04c3fSmrg           glsl_interp_mode_name(var->data.interpolation));
49701e04c3fSmrg
4987ec681f3Smrg   enum gl_access_qualifier access = var->data.access;
49901e04c3fSmrg   const char *const coher = (access & ACCESS_COHERENT) ? "coherent " : "";
50001e04c3fSmrg   const char *const volat = (access & ACCESS_VOLATILE) ? "volatile " : "";
50101e04c3fSmrg   const char *const restr = (access & ACCESS_RESTRICT) ? "restrict " : "";
50201e04c3fSmrg   const char *const ronly = (access & ACCESS_NON_WRITEABLE) ? "readonly " : "";
50301e04c3fSmrg   const char *const wonly = (access & ACCESS_NON_READABLE) ? "writeonly " : "";
5047ec681f3Smrg   const char *const reorder = (access & ACCESS_CAN_REORDER) ? "reorderable " : "";
5057ec681f3Smrg   fprintf(fp, "%s%s%s%s%s%s", coher, volat, restr, ronly, wonly, reorder);
5067ec681f3Smrg
5077ec681f3Smrg   if (glsl_get_base_type(glsl_without_array(var->type)) == GLSL_TYPE_IMAGE) {
5087ec681f3Smrg      fprintf(fp, "%s ", util_format_short_name(var->data.image.format));
5097ec681f3Smrg   }
5107ec681f3Smrg
5117ec681f3Smrg   if (var->data.precision) {
5127ec681f3Smrg      const char *precisions[] = {
5137ec681f3Smrg         "",
5147ec681f3Smrg         "highp",
5157ec681f3Smrg         "mediump",
5167ec681f3Smrg         "lowp",
5177ec681f3Smrg      };
5187ec681f3Smrg      fprintf(fp, "%s ", precisions[var->data.precision]);
5197e102996Smaya   }
5207e102996Smaya
52101e04c3fSmrg   fprintf(fp, "%s %s", glsl_get_type_name(var->type),
52201e04c3fSmrg           get_var_name(var, state));
52301e04c3fSmrg
52401e04c3fSmrg   if (var->data.mode == nir_var_shader_in ||
52501e04c3fSmrg       var->data.mode == nir_var_shader_out ||
52601e04c3fSmrg       var->data.mode == nir_var_uniform ||
5277e102996Smaya       var->data.mode == nir_var_mem_ubo ||
5287e102996Smaya       var->data.mode == nir_var_mem_ssbo) {
52901e04c3fSmrg      const char *loc = NULL;
53001e04c3fSmrg      char buf[4];
53101e04c3fSmrg
53201e04c3fSmrg      switch (state->shader->info.stage) {
53301e04c3fSmrg      case MESA_SHADER_VERTEX:
53401e04c3fSmrg         if (var->data.mode == nir_var_shader_in)
53501e04c3fSmrg            loc = gl_vert_attrib_name(var->data.location);
53601e04c3fSmrg         else if (var->data.mode == nir_var_shader_out)
5377ec681f3Smrg            loc = gl_varying_slot_name_for_stage(var->data.location,
5387ec681f3Smrg                                                 state->shader->info.stage);
53901e04c3fSmrg         break;
54001e04c3fSmrg      case MESA_SHADER_GEOMETRY:
54101e04c3fSmrg         if ((var->data.mode == nir_var_shader_in) ||
5427ec681f3Smrg             (var->data.mode == nir_var_shader_out)) {
5437ec681f3Smrg            loc = gl_varying_slot_name_for_stage(var->data.location,
5447ec681f3Smrg                                                 state->shader->info.stage);
5457ec681f3Smrg         }
54601e04c3fSmrg         break;
54701e04c3fSmrg      case MESA_SHADER_FRAGMENT:
5487ec681f3Smrg         if (var->data.mode == nir_var_shader_in) {
5497ec681f3Smrg            loc = gl_varying_slot_name_for_stage(var->data.location,
5507ec681f3Smrg                                                 state->shader->info.stage);
5517ec681f3Smrg         } else if (var->data.mode == nir_var_shader_out) {
55201e04c3fSmrg            loc = gl_frag_result_name(var->data.location);
5537ec681f3Smrg         }
55401e04c3fSmrg         break;
55501e04c3fSmrg      case MESA_SHADER_TESS_CTRL:
55601e04c3fSmrg      case MESA_SHADER_TESS_EVAL:
55701e04c3fSmrg      case MESA_SHADER_COMPUTE:
5587e102996Smaya      case MESA_SHADER_KERNEL:
55901e04c3fSmrg      default:
56001e04c3fSmrg         /* TODO */
56101e04c3fSmrg         break;
56201e04c3fSmrg      }
56301e04c3fSmrg
56401e04c3fSmrg      if (!loc) {
5657ec681f3Smrg         if (var->data.location == ~0) {
5667ec681f3Smrg            loc = "~0";
5677ec681f3Smrg         } else {
5687ec681f3Smrg            snprintf(buf, sizeof(buf), "%u", var->data.location);
5697ec681f3Smrg            loc = buf;
5707ec681f3Smrg         }
57101e04c3fSmrg      }
57201e04c3fSmrg
57301e04c3fSmrg      /* For shader I/O vars that have been split to components or packed,
57401e04c3fSmrg       * print the fractional location within the input/output.
57501e04c3fSmrg       */
57601e04c3fSmrg      unsigned int num_components =
57701e04c3fSmrg         glsl_get_components(glsl_without_array(var->type));
57801e04c3fSmrg      const char *components = NULL;
5797ec681f3Smrg      char components_local[18] = {'.' /* the rest is 0-filled */};
58001e04c3fSmrg      switch (var->data.mode) {
58101e04c3fSmrg      case nir_var_shader_in:
58201e04c3fSmrg      case nir_var_shader_out:
5837ec681f3Smrg         if (num_components < 16 && num_components != 0) {
5847ec681f3Smrg            const char *xyzw = comp_mask_string(num_components);
58501e04c3fSmrg            for (int i = 0; i < num_components; i++)
58601e04c3fSmrg               components_local[i + 1] = xyzw[i + var->data.location_frac];
58701e04c3fSmrg
58801e04c3fSmrg            components = components_local;
58901e04c3fSmrg         }
59001e04c3fSmrg         break;
59101e04c3fSmrg      default:
59201e04c3fSmrg         break;
59301e04c3fSmrg      }
59401e04c3fSmrg
59501e04c3fSmrg      fprintf(fp, " (%s%s, %u, %u)%s", loc,
59601e04c3fSmrg              components ? components : "",
59701e04c3fSmrg              var->data.driver_location, var->data.binding,
59801e04c3fSmrg              var->data.compact ? " compact" : "");
59901e04c3fSmrg   }
60001e04c3fSmrg
60101e04c3fSmrg   if (var->constant_initializer) {
60201e04c3fSmrg      fprintf(fp, " = { ");
60301e04c3fSmrg      print_constant(var->constant_initializer, var->type, state);
60401e04c3fSmrg      fprintf(fp, " }");
60501e04c3fSmrg   }
6067ec681f3Smrg   if (glsl_type_is_sampler(var->type) && var->data.sampler.is_inline_sampler) {
6077ec681f3Smrg      fprintf(fp, " = { %s, %s, %s }",
6087ec681f3Smrg              get_constant_sampler_addressing_mode(var->data.sampler.addressing_mode),
6097ec681f3Smrg              var->data.sampler.normalized_coordinates ? "true" : "false",
6107ec681f3Smrg              get_constant_sampler_filter_mode(var->data.sampler.filter_mode));
6117ec681f3Smrg   }
6127ec681f3Smrg   if (var->pointer_initializer)
6137ec681f3Smrg      fprintf(fp, " = &%s", get_var_name(var->pointer_initializer, state));
61401e04c3fSmrg
61501e04c3fSmrg   fprintf(fp, "\n");
61601e04c3fSmrg   print_annotation(state, var);
61701e04c3fSmrg}
61801e04c3fSmrg
61901e04c3fSmrgstatic void
6207e102996Smayaprint_deref_link(const nir_deref_instr *instr, bool whole_chain, print_state *state)
62101e04c3fSmrg{
62201e04c3fSmrg   FILE *fp = state->fp;
62301e04c3fSmrg
62401e04c3fSmrg   if (instr->deref_type == nir_deref_type_var) {
62501e04c3fSmrg      fprintf(fp, "%s", get_var_name(instr->var, state));
62601e04c3fSmrg      return;
62701e04c3fSmrg   } else if (instr->deref_type == nir_deref_type_cast) {
62801e04c3fSmrg      fprintf(fp, "(%s *)", glsl_get_type_name(instr->type));
62901e04c3fSmrg      print_src(&instr->parent, state);
63001e04c3fSmrg      return;
63101e04c3fSmrg   }
63201e04c3fSmrg
63301e04c3fSmrg   assert(instr->parent.is_ssa);
63401e04c3fSmrg   nir_deref_instr *parent =
63501e04c3fSmrg      nir_instr_as_deref(instr->parent.ssa->parent_instr);
63601e04c3fSmrg
63701e04c3fSmrg   /* Is the parent we're going to print a bare cast? */
63801e04c3fSmrg   const bool is_parent_cast =
63901e04c3fSmrg      whole_chain && parent->deref_type == nir_deref_type_cast;
64001e04c3fSmrg
64101e04c3fSmrg   /* If we're not printing the whole chain, the parent we print will be a SSA
64201e04c3fSmrg    * value that represents a pointer.  The only deref type that naturally
64301e04c3fSmrg    * gives a pointer is a cast.
64401e04c3fSmrg    */
64501e04c3fSmrg   const bool is_parent_pointer =
64601e04c3fSmrg      !whole_chain || parent->deref_type == nir_deref_type_cast;
64701e04c3fSmrg
64801e04c3fSmrg   /* Struct derefs have a nice syntax that works on pointers, arrays derefs
64901e04c3fSmrg    * do not.
65001e04c3fSmrg    */
65101e04c3fSmrg   const bool need_deref =
65201e04c3fSmrg      is_parent_pointer && instr->deref_type != nir_deref_type_struct;
65301e04c3fSmrg
65401e04c3fSmrg   /* Cast need extra parens and so * dereferences */
65501e04c3fSmrg   if (is_parent_cast || need_deref)
65601e04c3fSmrg      fprintf(fp, "(");
65701e04c3fSmrg
65801e04c3fSmrg   if (need_deref)
65901e04c3fSmrg      fprintf(fp, "*");
66001e04c3fSmrg
66101e04c3fSmrg   if (whole_chain) {
66201e04c3fSmrg      print_deref_link(parent, whole_chain, state);
66301e04c3fSmrg   } else {
66401e04c3fSmrg      print_src(&instr->parent, state);
66501e04c3fSmrg   }
66601e04c3fSmrg
66701e04c3fSmrg   if (is_parent_cast || need_deref)
66801e04c3fSmrg      fprintf(fp, ")");
66901e04c3fSmrg
67001e04c3fSmrg   switch (instr->deref_type) {
67101e04c3fSmrg   case nir_deref_type_struct:
67201e04c3fSmrg      fprintf(fp, "%s%s", is_parent_pointer ? "->" : ".",
67301e04c3fSmrg              glsl_get_struct_elem_name(parent->type, instr->strct.index));
67401e04c3fSmrg      break;
67501e04c3fSmrg
6767e102996Smaya   case nir_deref_type_array:
6777e102996Smaya   case nir_deref_type_ptr_as_array: {
6787e102996Smaya      if (nir_src_is_const(instr->arr.index)) {
6797ec681f3Smrg         fprintf(fp, "[%"PRId64"]", nir_src_as_int(instr->arr.index));
68001e04c3fSmrg      } else {
68101e04c3fSmrg         fprintf(fp, "[");
68201e04c3fSmrg         print_src(&instr->arr.index, state);
68301e04c3fSmrg         fprintf(fp, "]");
68401e04c3fSmrg      }
68501e04c3fSmrg      break;
68601e04c3fSmrg   }
68701e04c3fSmrg
68801e04c3fSmrg   case nir_deref_type_array_wildcard:
68901e04c3fSmrg      fprintf(fp, "[*]");
69001e04c3fSmrg      break;
69101e04c3fSmrg
69201e04c3fSmrg   default:
69301e04c3fSmrg      unreachable("Invalid deref instruction type");
69401e04c3fSmrg   }
69501e04c3fSmrg}
69601e04c3fSmrg
69701e04c3fSmrgstatic void
69801e04c3fSmrgprint_deref_instr(nir_deref_instr *instr, print_state *state)
69901e04c3fSmrg{
70001e04c3fSmrg   FILE *fp = state->fp;
70101e04c3fSmrg
70201e04c3fSmrg   print_dest(&instr->dest, state);
70301e04c3fSmrg
70401e04c3fSmrg   switch (instr->deref_type) {
70501e04c3fSmrg   case nir_deref_type_var:
70601e04c3fSmrg      fprintf(fp, " = deref_var ");
70701e04c3fSmrg      break;
70801e04c3fSmrg   case nir_deref_type_array:
70901e04c3fSmrg   case nir_deref_type_array_wildcard:
71001e04c3fSmrg      fprintf(fp, " = deref_array ");
71101e04c3fSmrg      break;
71201e04c3fSmrg   case nir_deref_type_struct:
71301e04c3fSmrg      fprintf(fp, " = deref_struct ");
71401e04c3fSmrg      break;
71501e04c3fSmrg   case nir_deref_type_cast:
71601e04c3fSmrg      fprintf(fp, " = deref_cast ");
71701e04c3fSmrg      break;
7187e102996Smaya   case nir_deref_type_ptr_as_array:
7197e102996Smaya      fprintf(fp, " = deref_ptr_as_array ");
7207e102996Smaya      break;
72101e04c3fSmrg   default:
72201e04c3fSmrg      unreachable("Invalid deref instruction type");
72301e04c3fSmrg   }
72401e04c3fSmrg
72501e04c3fSmrg   /* Only casts naturally return a pointer type */
72601e04c3fSmrg   if (instr->deref_type != nir_deref_type_cast)
72701e04c3fSmrg      fprintf(fp, "&");
72801e04c3fSmrg
72901e04c3fSmrg   print_deref_link(instr, false, state);
73001e04c3fSmrg
7317ec681f3Smrg   fprintf(fp, " (");
7327ec681f3Smrg   unsigned modes = instr->modes;
7337ec681f3Smrg   while (modes) {
7347ec681f3Smrg      int m = u_bit_scan(&modes);
7357ec681f3Smrg      fprintf(fp, "%s%s", get_variable_mode_str(1 << m, true),
7367ec681f3Smrg                          modes ? "|" : "");
7377ec681f3Smrg   }
7387ec681f3Smrg   fprintf(fp, " %s) ", glsl_get_type_name(instr->type));
73901e04c3fSmrg
74001e04c3fSmrg   if (instr->deref_type != nir_deref_type_var &&
74101e04c3fSmrg       instr->deref_type != nir_deref_type_cast) {
74201e04c3fSmrg      /* Print the entire chain as a comment */
74301e04c3fSmrg      fprintf(fp, "/* &");
74401e04c3fSmrg      print_deref_link(instr, true, state);
74501e04c3fSmrg      fprintf(fp, " */");
74601e04c3fSmrg   }
7477ec681f3Smrg
7487ec681f3Smrg   if (instr->deref_type == nir_deref_type_cast) {
7497ec681f3Smrg      fprintf(fp, " /* ptr_stride=%u, align_mul=%u, align_offset=%u */",
7507ec681f3Smrg              instr->cast.ptr_stride,
7517ec681f3Smrg              instr->cast.align_mul, instr->cast.align_offset);
7527ec681f3Smrg   }
75301e04c3fSmrg}
75401e04c3fSmrg
7557e102996Smayastatic const char *
7567e102996Smayavulkan_descriptor_type_name(VkDescriptorType type)
7577e102996Smaya{
7587e102996Smaya   switch (type) {
7597e102996Smaya   case VK_DESCRIPTOR_TYPE_SAMPLER: return "sampler";
7607e102996Smaya   case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: return "texture+sampler";
7617e102996Smaya   case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: return "texture";
7627e102996Smaya   case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: return "image";
7637e102996Smaya   case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: return "texture-buffer";
7647e102996Smaya   case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: return "image-buffer";
7657e102996Smaya   case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: return "UBO";
7667e102996Smaya   case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: return "SSBO";
7677e102996Smaya   case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: return "UBO";
7687e102996Smaya   case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: return "SSBO";
7697e102996Smaya   case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: return "input-att";
7707e102996Smaya   case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT: return "inline-UBO";
7717ec681f3Smrg   case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: return "accel-struct";
7727e102996Smaya   default: return "unknown";
7737e102996Smaya   }
7747e102996Smaya}
7757e102996Smaya
7767ec681f3Smrgstatic void
7777ec681f3Smrgprint_alu_type(nir_alu_type type, print_state *state)
7787ec681f3Smrg{
7797ec681f3Smrg   FILE *fp = state->fp;
7807ec681f3Smrg   unsigned size = nir_alu_type_get_type_size(type);
7817ec681f3Smrg   const char *name;
7827ec681f3Smrg
7837ec681f3Smrg   switch (nir_alu_type_get_base_type(type)) {
7847ec681f3Smrg   case nir_type_int: name = "int"; break;
7857ec681f3Smrg   case nir_type_uint: name = "uint"; break;
7867ec681f3Smrg   case nir_type_bool: name = "bool"; break;
7877ec681f3Smrg   case nir_type_float: name = "float"; break;
7887ec681f3Smrg   default: name = "invalid";
7897ec681f3Smrg   }
7907ec681f3Smrg   if (size)
7917ec681f3Smrg      fprintf(fp, "%s%u", name, size);
7927ec681f3Smrg   else
7937ec681f3Smrg      fprintf(fp, "%s", name);
7947ec681f3Smrg}
7957ec681f3Smrg
79601e04c3fSmrgstatic void
79701e04c3fSmrgprint_intrinsic_instr(nir_intrinsic_instr *instr, print_state *state)
79801e04c3fSmrg{
79901e04c3fSmrg   const nir_intrinsic_info *info = &nir_intrinsic_infos[instr->intrinsic];
80001e04c3fSmrg   unsigned num_srcs = info->num_srcs;
80101e04c3fSmrg   FILE *fp = state->fp;
80201e04c3fSmrg
80301e04c3fSmrg   if (info->has_dest) {
80401e04c3fSmrg      print_dest(&instr->dest, state);
80501e04c3fSmrg      fprintf(fp, " = ");
80601e04c3fSmrg   }
80701e04c3fSmrg
80801e04c3fSmrg   fprintf(fp, "intrinsic %s (", info->name);
80901e04c3fSmrg
81001e04c3fSmrg   for (unsigned i = 0; i < num_srcs; i++) {
81101e04c3fSmrg      if (i != 0)
81201e04c3fSmrg         fprintf(fp, ", ");
81301e04c3fSmrg
81401e04c3fSmrg      print_src(&instr->src[i], state);
81501e04c3fSmrg   }
81601e04c3fSmrg
81701e04c3fSmrg   fprintf(fp, ") (");
81801e04c3fSmrg
81901e04c3fSmrg   for (unsigned i = 0; i < info->num_indices; i++) {
82001e04c3fSmrg      if (i != 0)
82101e04c3fSmrg         fprintf(fp, ", ");
82201e04c3fSmrg
82301e04c3fSmrg      fprintf(fp, "%d", instr->const_index[i]);
82401e04c3fSmrg   }
82501e04c3fSmrg
82601e04c3fSmrg   fprintf(fp, ")");
82701e04c3fSmrg
8287ec681f3Smrg   for (unsigned i = 0; i < info->num_indices; i++) {
8297ec681f3Smrg      unsigned idx = info->indices[i];
83001e04c3fSmrg      fprintf(fp, " /*");
8317ec681f3Smrg      switch (idx) {
8327ec681f3Smrg      case NIR_INTRINSIC_WRITE_MASK: {
83301e04c3fSmrg         /* special case wrmask to show it as a writemask.. */
83401e04c3fSmrg         unsigned wrmask = nir_intrinsic_write_mask(instr);
83501e04c3fSmrg         fprintf(fp, " wrmask=");
8367ec681f3Smrg         for (unsigned i = 0; i < instr->num_components; i++)
83701e04c3fSmrg            if ((wrmask >> i) & 1)
8387ec681f3Smrg               fprintf(fp, "%c", comp_mask_string(instr->num_components)[i]);
8397ec681f3Smrg         break;
8407ec681f3Smrg      }
8417ec681f3Smrg
8427ec681f3Smrg      case NIR_INTRINSIC_REDUCTION_OP: {
84301e04c3fSmrg         nir_op reduction_op = nir_intrinsic_reduction_op(instr);
84401e04c3fSmrg         fprintf(fp, " reduction_op=%s", nir_op_infos[reduction_op].name);
8457ec681f3Smrg         break;
8467ec681f3Smrg      }
8477ec681f3Smrg
8487ec681f3Smrg      case NIR_INTRINSIC_IMAGE_DIM: {
84901e04c3fSmrg         static const char *dim_name[] = {
85001e04c3fSmrg            [GLSL_SAMPLER_DIM_1D] = "1D",
85101e04c3fSmrg            [GLSL_SAMPLER_DIM_2D] = "2D",
85201e04c3fSmrg            [GLSL_SAMPLER_DIM_3D] = "3D",
85301e04c3fSmrg            [GLSL_SAMPLER_DIM_CUBE] = "Cube",
85401e04c3fSmrg            [GLSL_SAMPLER_DIM_RECT] = "Rect",
85501e04c3fSmrg            [GLSL_SAMPLER_DIM_BUF] = "Buf",
85601e04c3fSmrg            [GLSL_SAMPLER_DIM_MS] = "2D-MSAA",
85701e04c3fSmrg            [GLSL_SAMPLER_DIM_SUBPASS] = "Subpass",
85801e04c3fSmrg            [GLSL_SAMPLER_DIM_SUBPASS_MS] = "Subpass-MSAA",
85901e04c3fSmrg         };
86001e04c3fSmrg         enum glsl_sampler_dim dim = nir_intrinsic_image_dim(instr);
8617e102996Smaya         assert(dim < ARRAY_SIZE(dim_name) && dim_name[dim]);
86201e04c3fSmrg         fprintf(fp, " image_dim=%s", dim_name[dim]);
8637ec681f3Smrg         break;
8647ec681f3Smrg      }
8657ec681f3Smrg
8667ec681f3Smrg      case NIR_INTRINSIC_IMAGE_ARRAY: {
8677e102996Smaya         bool array = nir_intrinsic_image_array(instr);
8687e102996Smaya         fprintf(fp, " image_array=%s", array ? "true" : "false");
8697ec681f3Smrg         break;
8707ec681f3Smrg      }
8717ec681f3Smrg
8727ec681f3Smrg      case NIR_INTRINSIC_FORMAT: {
8737ec681f3Smrg         enum pipe_format format = nir_intrinsic_format(instr);
8747ec681f3Smrg         fprintf(fp, " format=%s ", util_format_short_name(format));
8757ec681f3Smrg         break;
8767ec681f3Smrg      }
8777ec681f3Smrg
8787ec681f3Smrg      case NIR_INTRINSIC_DESC_TYPE: {
8797e102996Smaya         VkDescriptorType desc_type = nir_intrinsic_desc_type(instr);
8807e102996Smaya         fprintf(fp, " desc_type=%s", vulkan_descriptor_type_name(desc_type));
8817ec681f3Smrg         break;
8827ec681f3Smrg      }
8837ec681f3Smrg
8847ec681f3Smrg      case NIR_INTRINSIC_SRC_TYPE: {
8857ec681f3Smrg         fprintf(fp, " src_type=");
8867ec681f3Smrg         print_alu_type(nir_intrinsic_src_type(instr), state);
8877ec681f3Smrg         break;
8887ec681f3Smrg      }
8897ec681f3Smrg
8907ec681f3Smrg      case NIR_INTRINSIC_DEST_TYPE: {
8917ec681f3Smrg         fprintf(fp, " dest_type=");
8927ec681f3Smrg         print_alu_type(nir_intrinsic_dest_type(instr), state);
8937ec681f3Smrg         break;
8947ec681f3Smrg      }
8957ec681f3Smrg
8967ec681f3Smrg      case NIR_INTRINSIC_SWIZZLE_MASK: {
8977ec681f3Smrg         fprintf(fp, " swizzle_mask=");
8987ec681f3Smrg         unsigned mask = nir_intrinsic_swizzle_mask(instr);
8997ec681f3Smrg         if (instr->intrinsic == nir_intrinsic_quad_swizzle_amd) {
9007ec681f3Smrg            for (unsigned i = 0; i < 4; i++)
9017ec681f3Smrg               fprintf(fp, "%d", (mask >> (i * 2) & 3));
9027ec681f3Smrg         } else if (instr->intrinsic == nir_intrinsic_masked_swizzle_amd) {
9037ec681f3Smrg            fprintf(fp, "((id & %d) | %d) ^ %d", mask & 0x1F,
9047ec681f3Smrg                                                (mask >> 5) & 0x1F,
9057ec681f3Smrg                                                (mask >> 10) & 0x1F);
9067ec681f3Smrg         } else {
9077ec681f3Smrg            fprintf(fp, "%d", mask);
9087ec681f3Smrg         }
9097ec681f3Smrg         break;
9107ec681f3Smrg      }
9117ec681f3Smrg
9127ec681f3Smrg      case NIR_INTRINSIC_MEMORY_SEMANTICS: {
9137ec681f3Smrg         nir_memory_semantics semantics = nir_intrinsic_memory_semantics(instr);
9147ec681f3Smrg         fprintf(fp, " mem_semantics=");
9157ec681f3Smrg         switch (semantics & (NIR_MEMORY_ACQUIRE | NIR_MEMORY_RELEASE)) {
9167ec681f3Smrg         case 0:                  fprintf(fp, "NONE");    break;
9177ec681f3Smrg         case NIR_MEMORY_ACQUIRE: fprintf(fp, "ACQ");     break;
9187ec681f3Smrg         case NIR_MEMORY_RELEASE: fprintf(fp, "REL");     break;
9197ec681f3Smrg         default:                 fprintf(fp, "ACQ|REL"); break;
9207ec681f3Smrg         }
9217ec681f3Smrg         if (semantics & (NIR_MEMORY_MAKE_AVAILABLE)) fprintf(fp, "|AVAILABLE");
9227ec681f3Smrg         if (semantics & (NIR_MEMORY_MAKE_VISIBLE))   fprintf(fp, "|VISIBLE");
9237ec681f3Smrg         break;
9247ec681f3Smrg      }
9257ec681f3Smrg
9267ec681f3Smrg      case NIR_INTRINSIC_MEMORY_MODES: {
9277ec681f3Smrg         fprintf(fp, " mem_modes=");
9287ec681f3Smrg         unsigned int modes = nir_intrinsic_memory_modes(instr);
9297ec681f3Smrg         while (modes) {
9307ec681f3Smrg            nir_variable_mode m = u_bit_scan(&modes);
9317ec681f3Smrg            fprintf(fp, "%s%s", get_variable_mode_str(1 << m, true), modes ? "|" : "");
9327ec681f3Smrg         }
9337ec681f3Smrg         break;
9347ec681f3Smrg      }
9357ec681f3Smrg
9367ec681f3Smrg      case NIR_INTRINSIC_EXECUTION_SCOPE:
9377ec681f3Smrg      case NIR_INTRINSIC_MEMORY_SCOPE: {
9387ec681f3Smrg         fprintf(fp, " %s=", nir_intrinsic_index_names[idx]);
9397ec681f3Smrg         nir_scope scope =
9407ec681f3Smrg            idx == NIR_INTRINSIC_MEMORY_SCOPE ? nir_intrinsic_memory_scope(instr)
9417ec681f3Smrg                                              : nir_intrinsic_execution_scope(instr);
9427ec681f3Smrg         switch (scope) {
9437ec681f3Smrg         case NIR_SCOPE_NONE:         fprintf(fp, "NONE");         break;
9447ec681f3Smrg         case NIR_SCOPE_DEVICE:       fprintf(fp, "DEVICE");       break;
9457ec681f3Smrg         case NIR_SCOPE_QUEUE_FAMILY: fprintf(fp, "QUEUE_FAMILY"); break;
9467ec681f3Smrg         case NIR_SCOPE_WORKGROUP:    fprintf(fp, "WORKGROUP");    break;
9477ec681f3Smrg         case NIR_SCOPE_SHADER_CALL:  fprintf(fp, "SHADER_CALL");  break;
9487ec681f3Smrg         case NIR_SCOPE_SUBGROUP:     fprintf(fp, "SUBGROUP");     break;
9497ec681f3Smrg         case NIR_SCOPE_INVOCATION:   fprintf(fp, "INVOCATION");   break;
9507ec681f3Smrg         }
9517ec681f3Smrg         break;
9527ec681f3Smrg      }
9537ec681f3Smrg
9547ec681f3Smrg      case NIR_INTRINSIC_IO_SEMANTICS:
9557ec681f3Smrg         fprintf(fp, " location=%u slots=%u",
9567ec681f3Smrg                 nir_intrinsic_io_semantics(instr).location,
9577ec681f3Smrg                 nir_intrinsic_io_semantics(instr).num_slots);
9587ec681f3Smrg         if (state->shader) {
9597ec681f3Smrg            if (state->shader->info.stage == MESA_SHADER_FRAGMENT &&
9607ec681f3Smrg                instr->intrinsic == nir_intrinsic_store_output &&
9617ec681f3Smrg                nir_intrinsic_io_semantics(instr).dual_source_blend_index) {
9627ec681f3Smrg               fprintf(fp, " dualsrc=1");
9637ec681f3Smrg            }
9647ec681f3Smrg            if (state->shader->info.stage == MESA_SHADER_FRAGMENT &&
9657ec681f3Smrg                instr->intrinsic == nir_intrinsic_load_output &&
9667ec681f3Smrg                nir_intrinsic_io_semantics(instr).fb_fetch_output) {
9677ec681f3Smrg               fprintf(fp, " fbfetch=1");
9687ec681f3Smrg            }
9697ec681f3Smrg            if (instr->intrinsic == nir_intrinsic_store_output &&
9707ec681f3Smrg                nir_intrinsic_io_semantics(instr).per_view) {
9717ec681f3Smrg               fprintf(fp, " perview=1");
9727ec681f3Smrg            }
9737ec681f3Smrg            if (state->shader->info.stage == MESA_SHADER_GEOMETRY &&
9747ec681f3Smrg                instr->intrinsic == nir_intrinsic_store_output) {
9757ec681f3Smrg               unsigned gs_streams = nir_intrinsic_io_semantics(instr).gs_streams;
9767ec681f3Smrg               fprintf(fp, " gs_streams(");
9777ec681f3Smrg               for (unsigned i = 0; i < 4; i++) {
9787ec681f3Smrg                  fprintf(fp, "%s%c=%u", i ? " " : "", "xyzw"[i],
9797ec681f3Smrg                          (gs_streams >> (i * 2)) & 0x3);
9807ec681f3Smrg               }
9817ec681f3Smrg               fprintf(fp, ")");
9827ec681f3Smrg            }
9837ec681f3Smrg            if (nir_intrinsic_io_semantics(instr).medium_precision) {
9847ec681f3Smrg               fprintf(fp, " mediump");
9857ec681f3Smrg            }
9867ec681f3Smrg            if (nir_intrinsic_io_semantics(instr).high_16bits) {
9877ec681f3Smrg               fprintf(fp, " high_16bits");
9887ec681f3Smrg            }
9897ec681f3Smrg         }
9907ec681f3Smrg         break;
9917ec681f3Smrg
9927ec681f3Smrg      case NIR_INTRINSIC_ROUNDING_MODE: {
9937ec681f3Smrg         fprintf(fp, " rounding_mode=");
9947ec681f3Smrg         switch (nir_intrinsic_rounding_mode(instr)) {
9957ec681f3Smrg         case nir_rounding_mode_undef: fprintf(fp, "undef");   break;
9967ec681f3Smrg         case nir_rounding_mode_rtne:  fprintf(fp, "rtne");    break;
9977ec681f3Smrg         case nir_rounding_mode_ru:    fprintf(fp, "ru");      break;
9987ec681f3Smrg         case nir_rounding_mode_rd:    fprintf(fp, "rd");      break;
9997ec681f3Smrg         case nir_rounding_mode_rtz:   fprintf(fp, "rtz");     break;
10007ec681f3Smrg         default:                      fprintf(fp, "unkown");  break;
10017ec681f3Smrg         }
10027ec681f3Smrg         break;
10037ec681f3Smrg      }
10047ec681f3Smrg
10057ec681f3Smrg      default: {
100601e04c3fSmrg         unsigned off = info->index_map[idx] - 1;
10077ec681f3Smrg         fprintf(fp, " %s=%d", nir_intrinsic_index_names[idx], instr->const_index[off]);
10087ec681f3Smrg         break;
10097ec681f3Smrg      }
101001e04c3fSmrg      }
101101e04c3fSmrg      fprintf(fp, " */");
101201e04c3fSmrg   }
101301e04c3fSmrg
101401e04c3fSmrg   if (!state->shader)
101501e04c3fSmrg      return;
101601e04c3fSmrg
10177ec681f3Smrg   nir_variable_mode var_mode;
101801e04c3fSmrg   switch (instr->intrinsic) {
101901e04c3fSmrg   case nir_intrinsic_load_uniform:
10207ec681f3Smrg      var_mode = nir_var_uniform;
102101e04c3fSmrg      break;
102201e04c3fSmrg   case nir_intrinsic_load_input:
10237e102996Smaya   case nir_intrinsic_load_interpolated_input:
102401e04c3fSmrg   case nir_intrinsic_load_per_vertex_input:
10257ec681f3Smrg      var_mode = nir_var_shader_in;
102601e04c3fSmrg      break;
102701e04c3fSmrg   case nir_intrinsic_load_output:
102801e04c3fSmrg   case nir_intrinsic_store_output:
102901e04c3fSmrg   case nir_intrinsic_store_per_vertex_output:
10307ec681f3Smrg      var_mode = nir_var_shader_out;
103101e04c3fSmrg      break;
103201e04c3fSmrg   default:
103301e04c3fSmrg      return;
103401e04c3fSmrg   }
103501e04c3fSmrg
10367ec681f3Smrg   nir_foreach_variable_with_modes(var, state->shader, var_mode) {
103701e04c3fSmrg      if ((var->data.driver_location == nir_intrinsic_base(instr)) &&
103801e04c3fSmrg          (instr->intrinsic == nir_intrinsic_load_uniform ||
10397e102996Smaya           (nir_intrinsic_component(instr) >= var->data.location_frac  &&
10407e102996Smaya            nir_intrinsic_component(instr) <
10417e102996Smaya            (var->data.location_frac + glsl_get_components(var->type)))) &&
10427e102996Smaya           var->name) {
104301e04c3fSmrg         fprintf(fp, "\t/* %s */", var->name);
104401e04c3fSmrg         break;
104501e04c3fSmrg      }
104601e04c3fSmrg   }
104701e04c3fSmrg}
104801e04c3fSmrg
104901e04c3fSmrgstatic void
105001e04c3fSmrgprint_tex_instr(nir_tex_instr *instr, print_state *state)
105101e04c3fSmrg{
105201e04c3fSmrg   FILE *fp = state->fp;
105301e04c3fSmrg
105401e04c3fSmrg   print_dest(&instr->dest, state);
105501e04c3fSmrg
10567ec681f3Smrg   fprintf(fp, " = (");
10577ec681f3Smrg   print_alu_type(instr->dest_type, state);
10587ec681f3Smrg   fprintf(fp, ")");
105901e04c3fSmrg
106001e04c3fSmrg   switch (instr->op) {
106101e04c3fSmrg   case nir_texop_tex:
106201e04c3fSmrg      fprintf(fp, "tex ");
106301e04c3fSmrg      break;
106401e04c3fSmrg   case nir_texop_txb:
106501e04c3fSmrg      fprintf(fp, "txb ");
106601e04c3fSmrg      break;
106701e04c3fSmrg   case nir_texop_txl:
106801e04c3fSmrg      fprintf(fp, "txl ");
106901e04c3fSmrg      break;
107001e04c3fSmrg   case nir_texop_txd:
107101e04c3fSmrg      fprintf(fp, "txd ");
107201e04c3fSmrg      break;
107301e04c3fSmrg   case nir_texop_txf:
107401e04c3fSmrg      fprintf(fp, "txf ");
107501e04c3fSmrg      break;
107601e04c3fSmrg   case nir_texop_txf_ms:
107701e04c3fSmrg      fprintf(fp, "txf_ms ");
107801e04c3fSmrg      break;
10797e102996Smaya   case nir_texop_txf_ms_fb:
10807e102996Smaya      fprintf(fp, "txf_ms_fb ");
10817e102996Smaya      break;
10827ec681f3Smrg   case nir_texop_txf_ms_mcs_intel:
10837ec681f3Smrg      fprintf(fp, "txf_ms_mcs_intel ");
108401e04c3fSmrg      break;
108501e04c3fSmrg   case nir_texop_txs:
108601e04c3fSmrg      fprintf(fp, "txs ");
108701e04c3fSmrg      break;
108801e04c3fSmrg   case nir_texop_lod:
108901e04c3fSmrg      fprintf(fp, "lod ");
109001e04c3fSmrg      break;
109101e04c3fSmrg   case nir_texop_tg4:
109201e04c3fSmrg      fprintf(fp, "tg4 ");
109301e04c3fSmrg      break;
109401e04c3fSmrg   case nir_texop_query_levels:
109501e04c3fSmrg      fprintf(fp, "query_levels ");
109601e04c3fSmrg      break;
109701e04c3fSmrg   case nir_texop_texture_samples:
109801e04c3fSmrg      fprintf(fp, "texture_samples ");
109901e04c3fSmrg      break;
110001e04c3fSmrg   case nir_texop_samples_identical:
110101e04c3fSmrg      fprintf(fp, "samples_identical ");
110201e04c3fSmrg      break;
11037ec681f3Smrg   case nir_texop_tex_prefetch:
11047ec681f3Smrg      fprintf(fp, "tex (pre-dispatchable) ");
11057ec681f3Smrg      break;
11067ec681f3Smrg   case nir_texop_fragment_fetch_amd:
11077ec681f3Smrg      fprintf(fp, "fragment_fetch_amd ");
11087ec681f3Smrg      break;
11097ec681f3Smrg   case nir_texop_fragment_mask_fetch_amd:
11107ec681f3Smrg      fprintf(fp, "fragment_mask_fetch_amd ");
11117ec681f3Smrg      break;
111201e04c3fSmrg   default:
111301e04c3fSmrg      unreachable("Invalid texture operation");
111401e04c3fSmrg      break;
111501e04c3fSmrg   }
111601e04c3fSmrg
111701e04c3fSmrg   bool has_texture_deref = false, has_sampler_deref = false;
111801e04c3fSmrg   for (unsigned i = 0; i < instr->num_srcs; i++) {
11197e102996Smaya      if (i > 0) {
11207e102996Smaya         fprintf(fp, ", ");
11217e102996Smaya      }
112201e04c3fSmrg
11237e102996Smaya      print_src(&instr->src[i].src, state);
112401e04c3fSmrg      fprintf(fp, " ");
112501e04c3fSmrg
112601e04c3fSmrg      switch(instr->src[i].src_type) {
11277ec681f3Smrg      case nir_tex_src_backend1:
11287ec681f3Smrg         fprintf(fp, "(backend1)");
11297ec681f3Smrg         break;
11307ec681f3Smrg      case nir_tex_src_backend2:
11317ec681f3Smrg         fprintf(fp, "(backend2)");
11327ec681f3Smrg         break;
113301e04c3fSmrg      case nir_tex_src_coord:
113401e04c3fSmrg         fprintf(fp, "(coord)");
113501e04c3fSmrg         break;
113601e04c3fSmrg      case nir_tex_src_projector:
113701e04c3fSmrg         fprintf(fp, "(projector)");
113801e04c3fSmrg         break;
113901e04c3fSmrg      case nir_tex_src_comparator:
114001e04c3fSmrg         fprintf(fp, "(comparator)");
114101e04c3fSmrg         break;
114201e04c3fSmrg      case nir_tex_src_offset:
114301e04c3fSmrg         fprintf(fp, "(offset)");
114401e04c3fSmrg         break;
114501e04c3fSmrg      case nir_tex_src_bias:
114601e04c3fSmrg         fprintf(fp, "(bias)");
114701e04c3fSmrg         break;
114801e04c3fSmrg      case nir_tex_src_lod:
114901e04c3fSmrg         fprintf(fp, "(lod)");
115001e04c3fSmrg         break;
11517e102996Smaya      case nir_tex_src_min_lod:
11527e102996Smaya         fprintf(fp, "(min_lod)");
11537e102996Smaya         break;
115401e04c3fSmrg      case nir_tex_src_ms_index:
115501e04c3fSmrg         fprintf(fp, "(ms_index)");
115601e04c3fSmrg         break;
11577ec681f3Smrg      case nir_tex_src_ms_mcs_intel:
11587ec681f3Smrg         fprintf(fp, "(ms_mcs_intel)");
115901e04c3fSmrg         break;
116001e04c3fSmrg      case nir_tex_src_ddx:
116101e04c3fSmrg         fprintf(fp, "(ddx)");
116201e04c3fSmrg         break;
116301e04c3fSmrg      case nir_tex_src_ddy:
116401e04c3fSmrg         fprintf(fp, "(ddy)");
116501e04c3fSmrg         break;
116601e04c3fSmrg      case nir_tex_src_texture_deref:
116701e04c3fSmrg         has_texture_deref = true;
116801e04c3fSmrg         fprintf(fp, "(texture_deref)");
116901e04c3fSmrg         break;
117001e04c3fSmrg      case nir_tex_src_sampler_deref:
117101e04c3fSmrg         has_sampler_deref = true;
117201e04c3fSmrg         fprintf(fp, "(sampler_deref)");
117301e04c3fSmrg         break;
117401e04c3fSmrg      case nir_tex_src_texture_offset:
117501e04c3fSmrg         fprintf(fp, "(texture_offset)");
117601e04c3fSmrg         break;
117701e04c3fSmrg      case nir_tex_src_sampler_offset:
117801e04c3fSmrg         fprintf(fp, "(sampler_offset)");
117901e04c3fSmrg         break;
11807e102996Smaya      case nir_tex_src_texture_handle:
11817e102996Smaya         fprintf(fp, "(texture_handle)");
11827e102996Smaya         break;
11837e102996Smaya      case nir_tex_src_sampler_handle:
11847e102996Smaya         fprintf(fp, "(sampler_handle)");
11857e102996Smaya         break;
118601e04c3fSmrg      case nir_tex_src_plane:
118701e04c3fSmrg         fprintf(fp, "(plane)");
118801e04c3fSmrg         break;
118901e04c3fSmrg
119001e04c3fSmrg      default:
119101e04c3fSmrg         unreachable("Invalid texture source type");
119201e04c3fSmrg         break;
119301e04c3fSmrg      }
119401e04c3fSmrg   }
119501e04c3fSmrg
119601e04c3fSmrg   if (instr->op == nir_texop_tg4) {
11977e102996Smaya      fprintf(fp, ", %u (gather_component)", instr->component);
119801e04c3fSmrg   }
119901e04c3fSmrg
12007e102996Smaya   if (nir_tex_instr_has_explicit_tg4_offsets(instr)) {
12017e102996Smaya      fprintf(fp, ", { (%i, %i)", instr->tg4_offsets[0][0], instr->tg4_offsets[0][1]);
12027e102996Smaya      for (unsigned i = 1; i < 4; ++i)
12037e102996Smaya         fprintf(fp, ", (%i, %i)", instr->tg4_offsets[i][0],
12047e102996Smaya                 instr->tg4_offsets[i][1]);
12057e102996Smaya      fprintf(fp, " } (offsets)");
120601e04c3fSmrg   }
120701e04c3fSmrg
12087e102996Smaya   if (instr->op != nir_texop_txf_ms_fb) {
12097e102996Smaya      if (!has_texture_deref) {
12107e102996Smaya         fprintf(fp, ", %u (texture)", instr->texture_index);
12117e102996Smaya      }
12127e102996Smaya
12137e102996Smaya      if (!has_sampler_deref) {
12147e102996Smaya         fprintf(fp, ", %u (sampler)", instr->sampler_index);
12157e102996Smaya      }
121601e04c3fSmrg   }
12177ec681f3Smrg
12187ec681f3Smrg   if (instr->texture_non_uniform) {
12197ec681f3Smrg      fprintf(fp, ", texture non-uniform");
12207ec681f3Smrg   }
12217ec681f3Smrg
12227ec681f3Smrg   if (instr->sampler_non_uniform) {
12237ec681f3Smrg      fprintf(fp, ", sampler non-uniform");
12247ec681f3Smrg   }
12257ec681f3Smrg
12267ec681f3Smrg   if (instr->is_sparse) {
12277ec681f3Smrg      fprintf(fp, ", sparse");
12287ec681f3Smrg   }
122901e04c3fSmrg}
123001e04c3fSmrg
123101e04c3fSmrgstatic void
123201e04c3fSmrgprint_call_instr(nir_call_instr *instr, print_state *state)
123301e04c3fSmrg{
123401e04c3fSmrg   FILE *fp = state->fp;
123501e04c3fSmrg
123601e04c3fSmrg   fprintf(fp, "call %s ", instr->callee->name);
123701e04c3fSmrg
123801e04c3fSmrg   for (unsigned i = 0; i < instr->num_params; i++) {
123901e04c3fSmrg      if (i != 0)
124001e04c3fSmrg         fprintf(fp, ", ");
124101e04c3fSmrg
124201e04c3fSmrg      print_src(&instr->params[i], state);
124301e04c3fSmrg   }
124401e04c3fSmrg}
124501e04c3fSmrg
124601e04c3fSmrgstatic void
124701e04c3fSmrgprint_load_const_instr(nir_load_const_instr *instr, print_state *state)
124801e04c3fSmrg{
124901e04c3fSmrg   FILE *fp = state->fp;
125001e04c3fSmrg
125101e04c3fSmrg   print_ssa_def(&instr->def, state);
125201e04c3fSmrg
125301e04c3fSmrg   fprintf(fp, " = load_const (");
125401e04c3fSmrg
125501e04c3fSmrg   for (unsigned i = 0; i < instr->def.num_components; i++) {
125601e04c3fSmrg      if (i != 0)
125701e04c3fSmrg         fprintf(fp, ", ");
125801e04c3fSmrg
125901e04c3fSmrg      /*
126001e04c3fSmrg       * we don't really know the type of the constant (if it will be used as a
126101e04c3fSmrg       * float or an int), so just print the raw constant in hex for fidelity
126201e04c3fSmrg       * and then print the float in a comment for readability.
126301e04c3fSmrg       */
126401e04c3fSmrg
126501e04c3fSmrg      switch (instr->def.bit_size) {
126601e04c3fSmrg      case 64:
12677ec681f3Smrg         fprintf(fp, "0x%016" PRIx64 " /* %f */", instr->value[i].u64,
12687e102996Smaya                 instr->value[i].f64);
126901e04c3fSmrg         break;
127001e04c3fSmrg      case 32:
12717e102996Smaya         fprintf(fp, "0x%08x /* %f */", instr->value[i].u32, instr->value[i].f32);
127201e04c3fSmrg         break;
127301e04c3fSmrg      case 16:
12747e102996Smaya         fprintf(fp, "0x%04x /* %f */", instr->value[i].u16,
12757e102996Smaya                 _mesa_half_to_float(instr->value[i].u16));
127601e04c3fSmrg         break;
127701e04c3fSmrg      case 8:
12787e102996Smaya         fprintf(fp, "0x%02x", instr->value[i].u8);
12797e102996Smaya         break;
12807e102996Smaya      case 1:
12817e102996Smaya         fprintf(fp, "%s", instr->value[i].b ? "true" : "false");
128201e04c3fSmrg         break;
128301e04c3fSmrg      }
128401e04c3fSmrg   }
128501e04c3fSmrg
128601e04c3fSmrg   fprintf(fp, ")");
128701e04c3fSmrg}
128801e04c3fSmrg
128901e04c3fSmrgstatic void
129001e04c3fSmrgprint_jump_instr(nir_jump_instr *instr, print_state *state)
129101e04c3fSmrg{
129201e04c3fSmrg   FILE *fp = state->fp;
129301e04c3fSmrg
129401e04c3fSmrg   switch (instr->type) {
129501e04c3fSmrg   case nir_jump_break:
129601e04c3fSmrg      fprintf(fp, "break");
129701e04c3fSmrg      break;
129801e04c3fSmrg
129901e04c3fSmrg   case nir_jump_continue:
130001e04c3fSmrg      fprintf(fp, "continue");
130101e04c3fSmrg      break;
130201e04c3fSmrg
130301e04c3fSmrg   case nir_jump_return:
130401e04c3fSmrg      fprintf(fp, "return");
130501e04c3fSmrg      break;
13067ec681f3Smrg
13077ec681f3Smrg   case nir_jump_halt:
13087ec681f3Smrg      fprintf(fp, "halt");
13097ec681f3Smrg      break;
13107ec681f3Smrg
13117ec681f3Smrg   case nir_jump_goto:
13127ec681f3Smrg      fprintf(fp, "goto block_%u",
13137ec681f3Smrg              instr->target ? instr->target->index : -1);
13147ec681f3Smrg      break;
13157ec681f3Smrg
13167ec681f3Smrg   case nir_jump_goto_if:
13177ec681f3Smrg      fprintf(fp, "goto block_%u if ",
13187ec681f3Smrg              instr->target ? instr->target->index : -1);
13197ec681f3Smrg      print_src(&instr->condition, state);
13207ec681f3Smrg      fprintf(fp, " else block_%u",
13217ec681f3Smrg              instr->else_target ? instr->else_target->index : -1);
13227ec681f3Smrg      break;
132301e04c3fSmrg   }
132401e04c3fSmrg}
132501e04c3fSmrg
132601e04c3fSmrgstatic void
132701e04c3fSmrgprint_ssa_undef_instr(nir_ssa_undef_instr* instr, print_state *state)
132801e04c3fSmrg{
132901e04c3fSmrg   FILE *fp = state->fp;
133001e04c3fSmrg   print_ssa_def(&instr->def, state);
133101e04c3fSmrg   fprintf(fp, " = undefined");
133201e04c3fSmrg}
133301e04c3fSmrg
133401e04c3fSmrgstatic void
133501e04c3fSmrgprint_phi_instr(nir_phi_instr *instr, print_state *state)
133601e04c3fSmrg{
133701e04c3fSmrg   FILE *fp = state->fp;
133801e04c3fSmrg   print_dest(&instr->dest, state);
133901e04c3fSmrg   fprintf(fp, " = phi ");
134001e04c3fSmrg   nir_foreach_phi_src(src, instr) {
134101e04c3fSmrg      if (&src->node != exec_list_get_head(&instr->srcs))
134201e04c3fSmrg         fprintf(fp, ", ");
134301e04c3fSmrg
134401e04c3fSmrg      fprintf(fp, "block_%u: ", src->pred->index);
134501e04c3fSmrg      print_src(&src->src, state);
134601e04c3fSmrg   }
134701e04c3fSmrg}
134801e04c3fSmrg
134901e04c3fSmrgstatic void
135001e04c3fSmrgprint_parallel_copy_instr(nir_parallel_copy_instr *instr, print_state *state)
135101e04c3fSmrg{
135201e04c3fSmrg   FILE *fp = state->fp;
135301e04c3fSmrg   nir_foreach_parallel_copy_entry(entry, instr) {
135401e04c3fSmrg      if (&entry->node != exec_list_get_head(&instr->entries))
135501e04c3fSmrg         fprintf(fp, "; ");
135601e04c3fSmrg
135701e04c3fSmrg      print_dest(&entry->dest, state);
135801e04c3fSmrg      fprintf(fp, " = ");
135901e04c3fSmrg      print_src(&entry->src, state);
136001e04c3fSmrg   }
136101e04c3fSmrg}
136201e04c3fSmrg
136301e04c3fSmrgstatic void
136401e04c3fSmrgprint_instr(const nir_instr *instr, print_state *state, unsigned tabs)
136501e04c3fSmrg{
136601e04c3fSmrg   FILE *fp = state->fp;
136701e04c3fSmrg   print_tabs(tabs, fp);
136801e04c3fSmrg
136901e04c3fSmrg   switch (instr->type) {
137001e04c3fSmrg   case nir_instr_type_alu:
137101e04c3fSmrg      print_alu_instr(nir_instr_as_alu(instr), state);
137201e04c3fSmrg      break;
137301e04c3fSmrg
137401e04c3fSmrg   case nir_instr_type_deref:
137501e04c3fSmrg      print_deref_instr(nir_instr_as_deref(instr), state);
137601e04c3fSmrg      break;
137701e04c3fSmrg
137801e04c3fSmrg   case nir_instr_type_call:
137901e04c3fSmrg      print_call_instr(nir_instr_as_call(instr), state);
138001e04c3fSmrg      break;
138101e04c3fSmrg
138201e04c3fSmrg   case nir_instr_type_intrinsic:
138301e04c3fSmrg      print_intrinsic_instr(nir_instr_as_intrinsic(instr), state);
138401e04c3fSmrg      break;
138501e04c3fSmrg
138601e04c3fSmrg   case nir_instr_type_tex:
138701e04c3fSmrg      print_tex_instr(nir_instr_as_tex(instr), state);
138801e04c3fSmrg      break;
138901e04c3fSmrg
139001e04c3fSmrg   case nir_instr_type_load_const:
139101e04c3fSmrg      print_load_const_instr(nir_instr_as_load_const(instr), state);
139201e04c3fSmrg      break;
139301e04c3fSmrg
139401e04c3fSmrg   case nir_instr_type_jump:
139501e04c3fSmrg      print_jump_instr(nir_instr_as_jump(instr), state);
139601e04c3fSmrg      break;
139701e04c3fSmrg
139801e04c3fSmrg   case nir_instr_type_ssa_undef:
139901e04c3fSmrg      print_ssa_undef_instr(nir_instr_as_ssa_undef(instr), state);
140001e04c3fSmrg      break;
140101e04c3fSmrg
140201e04c3fSmrg   case nir_instr_type_phi:
140301e04c3fSmrg      print_phi_instr(nir_instr_as_phi(instr), state);
140401e04c3fSmrg      break;
140501e04c3fSmrg
140601e04c3fSmrg   case nir_instr_type_parallel_copy:
140701e04c3fSmrg      print_parallel_copy_instr(nir_instr_as_parallel_copy(instr), state);
140801e04c3fSmrg      break;
140901e04c3fSmrg
141001e04c3fSmrg   default:
141101e04c3fSmrg      unreachable("Invalid instruction type");
141201e04c3fSmrg      break;
141301e04c3fSmrg   }
141401e04c3fSmrg}
141501e04c3fSmrg
141601e04c3fSmrgstatic void print_cf_node(nir_cf_node *node, print_state *state,
141701e04c3fSmrg                          unsigned tabs);
141801e04c3fSmrg
141901e04c3fSmrgstatic void
142001e04c3fSmrgprint_block(nir_block *block, print_state *state, unsigned tabs)
142101e04c3fSmrg{
142201e04c3fSmrg   FILE *fp = state->fp;
142301e04c3fSmrg
142401e04c3fSmrg   print_tabs(tabs, fp);
142501e04c3fSmrg   fprintf(fp, "block block_%u:\n", block->index);
142601e04c3fSmrg
14277ec681f3Smrg   nir_block **preds = nir_block_get_predecessors_sorted(block, NULL);
142801e04c3fSmrg
142901e04c3fSmrg   print_tabs(tabs, fp);
143001e04c3fSmrg   fprintf(fp, "/* preds: ");
143101e04c3fSmrg   for (unsigned i = 0; i < block->predecessors->entries; i++) {
143201e04c3fSmrg      fprintf(fp, "block_%u ", preds[i]->index);
143301e04c3fSmrg   }
143401e04c3fSmrg   fprintf(fp, "*/\n");
143501e04c3fSmrg
14367ec681f3Smrg   ralloc_free(preds);
143701e04c3fSmrg
143801e04c3fSmrg   nir_foreach_instr(instr, block) {
143901e04c3fSmrg      print_instr(instr, state, tabs);
144001e04c3fSmrg      fprintf(fp, "\n");
144101e04c3fSmrg      print_annotation(state, instr);
144201e04c3fSmrg   }
144301e04c3fSmrg
144401e04c3fSmrg   print_tabs(tabs, fp);
144501e04c3fSmrg   fprintf(fp, "/* succs: ");
144601e04c3fSmrg   for (unsigned i = 0; i < 2; i++)
144701e04c3fSmrg      if (block->successors[i]) {
144801e04c3fSmrg         fprintf(fp, "block_%u ", block->successors[i]->index);
144901e04c3fSmrg      }
145001e04c3fSmrg   fprintf(fp, "*/\n");
145101e04c3fSmrg}
145201e04c3fSmrg
145301e04c3fSmrgstatic void
145401e04c3fSmrgprint_if(nir_if *if_stmt, print_state *state, unsigned tabs)
145501e04c3fSmrg{
145601e04c3fSmrg   FILE *fp = state->fp;
145701e04c3fSmrg
145801e04c3fSmrg   print_tabs(tabs, fp);
145901e04c3fSmrg   fprintf(fp, "if ");
146001e04c3fSmrg   print_src(&if_stmt->condition, state);
146101e04c3fSmrg   fprintf(fp, " {\n");
146201e04c3fSmrg   foreach_list_typed(nir_cf_node, node, node, &if_stmt->then_list) {
146301e04c3fSmrg      print_cf_node(node, state, tabs + 1);
146401e04c3fSmrg   }
146501e04c3fSmrg   print_tabs(tabs, fp);
146601e04c3fSmrg   fprintf(fp, "} else {\n");
146701e04c3fSmrg   foreach_list_typed(nir_cf_node, node, node, &if_stmt->else_list) {
146801e04c3fSmrg      print_cf_node(node, state, tabs + 1);
146901e04c3fSmrg   }
147001e04c3fSmrg   print_tabs(tabs, fp);
147101e04c3fSmrg   fprintf(fp, "}\n");
147201e04c3fSmrg}
147301e04c3fSmrg
147401e04c3fSmrgstatic void
147501e04c3fSmrgprint_loop(nir_loop *loop, print_state *state, unsigned tabs)
147601e04c3fSmrg{
147701e04c3fSmrg   FILE *fp = state->fp;
147801e04c3fSmrg
147901e04c3fSmrg   print_tabs(tabs, fp);
148001e04c3fSmrg   fprintf(fp, "loop {\n");
148101e04c3fSmrg   foreach_list_typed(nir_cf_node, node, node, &loop->body) {
148201e04c3fSmrg      print_cf_node(node, state, tabs + 1);
148301e04c3fSmrg   }
148401e04c3fSmrg   print_tabs(tabs, fp);
148501e04c3fSmrg   fprintf(fp, "}\n");
148601e04c3fSmrg}
148701e04c3fSmrg
148801e04c3fSmrgstatic void
148901e04c3fSmrgprint_cf_node(nir_cf_node *node, print_state *state, unsigned int tabs)
149001e04c3fSmrg{
149101e04c3fSmrg   switch (node->type) {
149201e04c3fSmrg   case nir_cf_node_block:
149301e04c3fSmrg      print_block(nir_cf_node_as_block(node), state, tabs);
149401e04c3fSmrg      break;
149501e04c3fSmrg
149601e04c3fSmrg   case nir_cf_node_if:
149701e04c3fSmrg      print_if(nir_cf_node_as_if(node), state, tabs);
149801e04c3fSmrg      break;
149901e04c3fSmrg
150001e04c3fSmrg   case nir_cf_node_loop:
150101e04c3fSmrg      print_loop(nir_cf_node_as_loop(node), state, tabs);
150201e04c3fSmrg      break;
150301e04c3fSmrg
150401e04c3fSmrg   default:
150501e04c3fSmrg      unreachable("Invalid CFG node type");
150601e04c3fSmrg   }
150701e04c3fSmrg}
150801e04c3fSmrg
150901e04c3fSmrgstatic void
151001e04c3fSmrgprint_function_impl(nir_function_impl *impl, print_state *state)
151101e04c3fSmrg{
151201e04c3fSmrg   FILE *fp = state->fp;
151301e04c3fSmrg
151401e04c3fSmrg   fprintf(fp, "\nimpl %s ", impl->function->name);
151501e04c3fSmrg
151601e04c3fSmrg   fprintf(fp, "{\n");
151701e04c3fSmrg
15187ec681f3Smrg   nir_foreach_function_temp_variable(var, impl) {
151901e04c3fSmrg      fprintf(fp, "\t");
152001e04c3fSmrg      print_var_decl(var, state);
152101e04c3fSmrg   }
152201e04c3fSmrg
152301e04c3fSmrg   foreach_list_typed(nir_register, reg, node, &impl->registers) {
152401e04c3fSmrg      fprintf(fp, "\t");
152501e04c3fSmrg      print_register_decl(reg, state);
152601e04c3fSmrg   }
152701e04c3fSmrg
152801e04c3fSmrg   nir_index_blocks(impl);
152901e04c3fSmrg
153001e04c3fSmrg   foreach_list_typed(nir_cf_node, node, node, &impl->body) {
153101e04c3fSmrg      print_cf_node(node, state, 1);
153201e04c3fSmrg   }
153301e04c3fSmrg
153401e04c3fSmrg   fprintf(fp, "\tblock block_%u:\n}\n\n", impl->end_block->index);
153501e04c3fSmrg}
153601e04c3fSmrg
153701e04c3fSmrgstatic void
153801e04c3fSmrgprint_function(nir_function *function, print_state *state)
153901e04c3fSmrg{
154001e04c3fSmrg   FILE *fp = state->fp;
154101e04c3fSmrg
154201e04c3fSmrg   fprintf(fp, "decl_function %s (%d params)", function->name,
154301e04c3fSmrg           function->num_params);
154401e04c3fSmrg
154501e04c3fSmrg   fprintf(fp, "\n");
154601e04c3fSmrg
154701e04c3fSmrg   if (function->impl != NULL) {
154801e04c3fSmrg      print_function_impl(function->impl, state);
154901e04c3fSmrg      return;
155001e04c3fSmrg   }
155101e04c3fSmrg}
155201e04c3fSmrg
155301e04c3fSmrgstatic void
155401e04c3fSmrginit_print_state(print_state *state, nir_shader *shader, FILE *fp)
155501e04c3fSmrg{
155601e04c3fSmrg   state->fp = fp;
155701e04c3fSmrg   state->shader = shader;
15587e102996Smaya   state->ht = _mesa_pointer_hash_table_create(NULL);
15597ec681f3Smrg   state->syms = _mesa_set_create(NULL, _mesa_hash_string,
156001e04c3fSmrg                                  _mesa_key_string_equal);
156101e04c3fSmrg   state->index = 0;
156201e04c3fSmrg}
156301e04c3fSmrg
156401e04c3fSmrgstatic void
156501e04c3fSmrgdestroy_print_state(print_state *state)
156601e04c3fSmrg{
156701e04c3fSmrg   _mesa_hash_table_destroy(state->ht, NULL);
156801e04c3fSmrg   _mesa_set_destroy(state->syms, NULL);
156901e04c3fSmrg}
157001e04c3fSmrg
15717ec681f3Smrgstatic const char *
15727ec681f3Smrgprimitive_name(unsigned primitive)
15737ec681f3Smrg{
15747ec681f3Smrg#define PRIM(X) case GL_ ## X : return #X
15757ec681f3Smrg   switch (primitive) {
15767ec681f3Smrg   PRIM(POINTS);
15777ec681f3Smrg   PRIM(LINES);
15787ec681f3Smrg   PRIM(LINE_LOOP);
15797ec681f3Smrg   PRIM(LINE_STRIP);
15807ec681f3Smrg   PRIM(TRIANGLES);
15817ec681f3Smrg   PRIM(TRIANGLE_STRIP);
15827ec681f3Smrg   PRIM(TRIANGLE_FAN);
15837ec681f3Smrg   PRIM(QUADS);
15847ec681f3Smrg   PRIM(QUAD_STRIP);
15857ec681f3Smrg   PRIM(POLYGON);
15867ec681f3Smrg   default:
15877ec681f3Smrg      return "UNKNOWN";
15887ec681f3Smrg   }
15897ec681f3Smrg}
15907ec681f3Smrg
15917ec681f3Smrg
159201e04c3fSmrgvoid
159301e04c3fSmrgnir_print_shader_annotated(nir_shader *shader, FILE *fp,
159401e04c3fSmrg                           struct hash_table *annotations)
159501e04c3fSmrg{
159601e04c3fSmrg   print_state state;
159701e04c3fSmrg   init_print_state(&state, shader, fp);
159801e04c3fSmrg
159901e04c3fSmrg   state.annotations = annotations;
160001e04c3fSmrg
160101e04c3fSmrg   fprintf(fp, "shader: %s\n", gl_shader_stage_name(shader->info.stage));
160201e04c3fSmrg
160301e04c3fSmrg   if (shader->info.name)
160401e04c3fSmrg      fprintf(fp, "name: %s\n", shader->info.name);
160501e04c3fSmrg
160601e04c3fSmrg   if (shader->info.label)
160701e04c3fSmrg      fprintf(fp, "label: %s\n", shader->info.label);
160801e04c3fSmrg
16097ec681f3Smrg   if (gl_shader_stage_uses_workgroup(shader->info.stage)) {
16107ec681f3Smrg      fprintf(fp, "workgroup-size: %u, %u, %u%s\n",
16117ec681f3Smrg              shader->info.workgroup_size[0],
16127ec681f3Smrg              shader->info.workgroup_size[1],
16137ec681f3Smrg              shader->info.workgroup_size[2],
16147ec681f3Smrg              shader->info.workgroup_size_variable ? " (variable)" : "");
16157ec681f3Smrg      fprintf(fp, "shared-size: %u\n", shader->info.shared_size);
161601e04c3fSmrg   }
161701e04c3fSmrg
161801e04c3fSmrg   fprintf(fp, "inputs: %u\n", shader->num_inputs);
161901e04c3fSmrg   fprintf(fp, "outputs: %u\n", shader->num_outputs);
162001e04c3fSmrg   fprintf(fp, "uniforms: %u\n", shader->num_uniforms);
16217ec681f3Smrg   if (shader->info.num_ubos)
16227ec681f3Smrg      fprintf(fp, "ubos: %u\n", shader->info.num_ubos);
16237ec681f3Smrg   fprintf(fp, "shared: %u\n", shader->info.shared_size);
16247e102996Smaya   if (shader->scratch_size)
16257e102996Smaya      fprintf(fp, "scratch: %u\n", shader->scratch_size);
16267ec681f3Smrg   if (shader->constant_data_size)
16277ec681f3Smrg      fprintf(fp, "constants: %u\n", shader->constant_data_size);
16287ec681f3Smrg
16297ec681f3Smrg   if (shader->info.stage == MESA_SHADER_GEOMETRY) {
16307ec681f3Smrg      fprintf(fp, "invocations: %u\n", shader->info.gs.invocations);
16317ec681f3Smrg      fprintf(fp, "vertices in: %u\n", shader->info.gs.vertices_in);
16327ec681f3Smrg      fprintf(fp, "vertices out: %u\n", shader->info.gs.vertices_out);
16337ec681f3Smrg      fprintf(fp, "input primitive: %s\n", primitive_name(shader->info.gs.input_primitive));
16347ec681f3Smrg      fprintf(fp, "output primitive: %s\n", primitive_name(shader->info.gs.output_primitive));
16357ec681f3Smrg      fprintf(fp, "active_stream_mask: 0x%x\n", shader->info.gs.active_stream_mask);
16367ec681f3Smrg      fprintf(fp, "uses_end_primitive: %u\n", shader->info.gs.uses_end_primitive);
163701e04c3fSmrg   }
163801e04c3fSmrg
16397ec681f3Smrg   nir_foreach_variable_in_shader(var, shader)
164001e04c3fSmrg      print_var_decl(var, &state);
164101e04c3fSmrg
164201e04c3fSmrg   foreach_list_typed(nir_function, func, node, &shader->functions) {
164301e04c3fSmrg      print_function(func, &state);
164401e04c3fSmrg   }
164501e04c3fSmrg
164601e04c3fSmrg   destroy_print_state(&state);
164701e04c3fSmrg}
164801e04c3fSmrg
164901e04c3fSmrgvoid
165001e04c3fSmrgnir_print_shader(nir_shader *shader, FILE *fp)
165101e04c3fSmrg{
165201e04c3fSmrg   nir_print_shader_annotated(shader, fp, NULL);
16537e102996Smaya   fflush(fp);
165401e04c3fSmrg}
165501e04c3fSmrg
16567ec681f3Smrgchar *
16577ec681f3Smrgnir_shader_as_str_annotated(nir_shader *nir, struct hash_table *annotations, void *mem_ctx)
16587ec681f3Smrg{
16597ec681f3Smrg   char *stream_data = NULL;
16607ec681f3Smrg   size_t stream_size = 0;
16617ec681f3Smrg   struct u_memstream mem;
16627ec681f3Smrg   if (u_memstream_open(&mem, &stream_data, &stream_size)) {
16637ec681f3Smrg      FILE *const stream = u_memstream_get(&mem);
16647ec681f3Smrg      nir_print_shader_annotated(nir, stream, annotations);
16657ec681f3Smrg      u_memstream_close(&mem);
16667ec681f3Smrg   }
16677ec681f3Smrg
16687ec681f3Smrg   char *str = ralloc_size(mem_ctx, stream_size + 1);
16697ec681f3Smrg   memcpy(str, stream_data, stream_size);
16707ec681f3Smrg   str[stream_size] = '\0';
16717ec681f3Smrg
16727ec681f3Smrg   free(stream_data);
16737ec681f3Smrg
16747ec681f3Smrg   return str;
16757ec681f3Smrg}
16767ec681f3Smrg
16777ec681f3Smrgchar *
16787ec681f3Smrgnir_shader_as_str(nir_shader *nir, void *mem_ctx)
16797ec681f3Smrg{
16807ec681f3Smrg   return nir_shader_as_str_annotated(nir, NULL, mem_ctx);
16817ec681f3Smrg}
16827ec681f3Smrg
168301e04c3fSmrgvoid
168401e04c3fSmrgnir_print_instr(const nir_instr *instr, FILE *fp)
168501e04c3fSmrg{
168601e04c3fSmrg   print_state state = {
168701e04c3fSmrg      .fp = fp,
168801e04c3fSmrg   };
16897ec681f3Smrg   if (instr->block) {
16907ec681f3Smrg      nir_function_impl *impl = nir_cf_node_get_function(&instr->block->cf_node);
16917ec681f3Smrg      state.shader = impl->function->shader;
16927ec681f3Smrg   }
16937ec681f3Smrg
169401e04c3fSmrg   print_instr(instr, &state, 0);
169501e04c3fSmrg
169601e04c3fSmrg}
16977e102996Smaya
16987e102996Smayavoid
16997e102996Smayanir_print_deref(const nir_deref_instr *deref, FILE *fp)
17007e102996Smaya{
17017e102996Smaya   print_state state = {
17027e102996Smaya      .fp = fp,
17037e102996Smaya   };
17047e102996Smaya   print_deref_link(deref, true, &state);
17057e102996Smaya}
17067ec681f3Smrg
17077ec681f3Smrgvoid nir_log_shader_annotated_tagged(enum mesa_log_level level, const char *tag,
17087ec681f3Smrg                                     nir_shader *shader, struct hash_table *annotations)
17097ec681f3Smrg{
17107ec681f3Smrg   char *str = nir_shader_as_str_annotated(shader, annotations, NULL);
17117ec681f3Smrg   _mesa_log_multiline(level, tag, str);
17127ec681f3Smrg   ralloc_free(str);
17137ec681f3Smrg}
1714