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