X-Git-Url: https://git.libre-soc.org/?p=mesa.git;a=blobdiff_plain;f=src%2Fcompiler%2Fnir%2Fnir_print.c;h=7931a88cb20e40da814dfac5f9188ca9b7424432;hp=af105557123836b0e908666e7b65304575442e36;hb=13b3c401a417c6d1a409c0b85cd97a093696c96a;hpb=3ca0029a0dc7b2ed2c61de72ef16e7ad1831c101 diff --git a/src/compiler/nir/nir_print.c b/src/compiler/nir/nir_print.c index af105557123..7931a88cb20 100644 --- a/src/compiler/nir/nir_print.c +++ b/src/compiler/nir/nir_print.c @@ -27,14 +27,12 @@ #include "nir.h" #include "compiler/shader_enums.h" +#include "util/half_float.h" +#include "vulkan/vulkan_core.h" #include #include #include /* for PRIx64 macro */ -#if defined(_WIN32) && !defined(snprintf) -#define snprintf _snprintf -#endif - static void print_tabs(unsigned num_tabs, FILE *fp) { @@ -64,6 +62,8 @@ typedef struct { static void print_annotation(print_state *state, void *obj) { + FILE *fp = state->fp; + if (!state->annotations) return; @@ -74,7 +74,7 @@ print_annotation(print_state *state, void *obj) const char *note = entry->data; _mesa_hash_table_remove(state->annotations, entry); - fprintf(stderr, "%s\n\n", note); + fprintf(fp, "%s\n\n", note); } static void @@ -83,21 +83,19 @@ print_register(nir_register *reg, print_state *state) FILE *fp = state->fp; if (reg->name != NULL) fprintf(fp, "/* %s */ ", reg->name); - if (reg->is_global) - fprintf(fp, "gr%u", reg->index); - else - fprintf(fp, "r%u", reg->index); + fprintf(fp, "r%u", reg->index); } -static const char *sizes[] = { "error", "vec1", "vec2", "vec3", "vec4" }; +static const char *sizes[] = { "error", "vec1", "vec2", "vec3", "vec4", + "error", "error", "error", "vec8", + "error", "error", "error", "error", + "error", "error", "error", "vec16"}; static void print_register_decl(nir_register *reg, print_state *state) { FILE *fp = state->fp; fprintf(fp, "decl_reg %s %u ", sizes[reg->num_components], reg->bit_size); - if (reg->is_packed) - fprintf(fp, "(packed) "); print_register(reg, state); if (reg->num_array_elems != 0) fprintf(fp, "[%u]", reg->num_array_elems); @@ -123,10 +121,10 @@ print_ssa_use(nir_ssa_def *def, print_state *state) fprintf(fp, "ssa_%u", def->index); } -static void print_src(nir_src *src, print_state *state); +static void print_src(const nir_src *src, print_state *state); static void -print_reg_src(nir_reg_src *src, print_state *state) +print_reg_src(const nir_reg_src *src, print_state *state) { FILE *fp = state->fp; print_register(src->reg, state); @@ -156,7 +154,7 @@ print_reg_dest(nir_reg_dest *dest, print_state *state) } static void -print_src(nir_src *src, print_state *state) +print_src(const nir_src *src, print_state *state) { if (src->is_ssa) print_ssa_use(src->ssa, state); @@ -173,6 +171,12 @@ print_dest(nir_dest *dest, print_state *state) print_reg_dest(&dest->reg, state); } +static const char * +comp_mask_string(unsigned num_components) +{ + return (num_components > 4) ? "abcdefghijklmnop" : "xyzw"; +} + static void print_alu_src(nir_alu_instr *instr, unsigned src, print_state *state) { @@ -186,9 +190,9 @@ print_alu_src(nir_alu_instr *instr, unsigned src, print_state *state) print_src(&instr->src[src].src, state); bool print_swizzle = false; - unsigned used_channels = 0; + nir_component_mask_t used_channels = 0; - for (unsigned i = 0; i < 4; i++) { + for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++) { if (!nir_alu_instr_channel_used(instr, src, i)) continue; @@ -200,17 +204,15 @@ print_alu_src(nir_alu_instr *instr, unsigned src, print_state *state) } } - unsigned live_channels = instr->src[src].src.is_ssa - ? instr->src[src].src.ssa->num_components - : instr->src[src].src.reg.reg->num_components; + unsigned live_channels = nir_src_num_components(instr->src[src].src); if (print_swizzle || used_channels != live_channels) { fprintf(fp, "."); - for (unsigned i = 0; i < 4; i++) { + for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++) { if (!nir_alu_instr_channel_used(instr, src, i)) continue; - fprintf(fp, "%c", "xyzw"[instr->src[src].swizzle[i]]); + fprintf(fp, "%c", comp_mask_string(live_channels)[instr->src[src].swizzle[i]]); } } @@ -228,10 +230,11 @@ print_alu_dest(nir_alu_dest *dest, print_state *state) if (!dest->dest.is_ssa && dest->write_mask != (1 << dest->dest.reg.reg->num_components) - 1) { + unsigned live_channels = dest->dest.reg.reg->num_components; fprintf(fp, "."); - for (unsigned i = 0; i < 4; i++) + for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++) if ((dest->write_mask >> i) & 1) - fprintf(fp, "%c", "xyzw"[i]); + fprintf(fp, "%c", comp_mask_string(live_channels)[i]); } } @@ -247,6 +250,10 @@ print_alu_instr(nir_alu_instr *instr, print_state *state) fprintf(fp, "!"); if (instr->dest.saturate) fprintf(fp, ".sat"); + if (instr->no_signed_wrap) + fprintf(fp, ".nsw"); + if (instr->no_unsigned_wrap) + fprintf(fp, ".nuw"); fprintf(fp, " "); for (unsigned i = 0; i < nir_op_infos[instr->op].num_inputs; i++) { @@ -261,7 +268,7 @@ static const char * get_var_name(nir_variable *var, print_state *state) { if (state->ht == NULL) - return var->name; + return var->name ? var->name : "unnamed"; assert(state->syms); @@ -297,35 +304,85 @@ print_constant(nir_constant *c, const struct glsl_type *type, print_state *state FILE *fp = state->fp; const unsigned rows = glsl_get_vector_elements(type); const unsigned cols = glsl_get_matrix_columns(type); - unsigned i, j; + unsigned i; switch (glsl_get_base_type(type)) { - case GLSL_TYPE_UINT: - case GLSL_TYPE_INT: case GLSL_TYPE_BOOL: /* Only float base types can be matrices. */ assert(cols == 1); for (i = 0; i < rows; i++) { if (i > 0) fprintf(fp, ", "); - fprintf(fp, "0x%08x", c->values[0].u32[i]); + fprintf(fp, "%s", c->values[i].b ? "true" : "false"); } break; - case GLSL_TYPE_FLOAT: - for (i = 0; i < cols; i++) { - for (j = 0; j < rows; j++) { - if (i + j > 0) fprintf(fp, ", "); - fprintf(fp, "%f", c->values[i].f32[j]); - } + case GLSL_TYPE_UINT8: + case GLSL_TYPE_INT8: + /* Only float base types can be matrices. */ + assert(cols == 1); + + for (i = 0; i < rows; i++) { + if (i > 0) fprintf(fp, ", "); + fprintf(fp, "0x%02x", c->values[i].u8); + } + break; + + case GLSL_TYPE_UINT16: + case GLSL_TYPE_INT16: + /* Only float base types can be matrices. */ + assert(cols == 1); + + for (i = 0; i < rows; i++) { + if (i > 0) fprintf(fp, ", "); + fprintf(fp, "0x%04x", c->values[i].u16); + } + break; + + case GLSL_TYPE_UINT: + case GLSL_TYPE_INT: + /* Only float base types can be matrices. */ + assert(cols == 1); + + for (i = 0; i < rows; i++) { + if (i > 0) fprintf(fp, ", "); + fprintf(fp, "0x%08x", c->values[i].u32); } break; + case GLSL_TYPE_FLOAT16: + case GLSL_TYPE_FLOAT: case GLSL_TYPE_DOUBLE: - for (i = 0; i < cols; i++) { - for (j = 0; j < rows; j++) { - if (i + j > 0) fprintf(fp, ", "); - fprintf(fp, "%f", c->values[i].f64[j]); + if (cols > 1) { + for (i = 0; i < cols; i++) { + if (i > 0) fprintf(fp, ", "); + print_constant(c->elements[i], glsl_get_column_type(type), state); + } + } else { + switch (glsl_get_base_type(type)) { + case GLSL_TYPE_FLOAT16: + for (i = 0; i < rows; i++) { + if (i > 0) fprintf(fp, ", "); + fprintf(fp, "%f", _mesa_half_to_float(c->values[i].u16)); + } + break; + + case GLSL_TYPE_FLOAT: + for (i = 0; i < rows; i++) { + if (i > 0) fprintf(fp, ", "); + fprintf(fp, "%f", c->values[i].f32); + } + break; + + case GLSL_TYPE_DOUBLE: + for (i = 0; i < rows; i++) { + if (i > 0) fprintf(fp, ", "); + fprintf(fp, "%f", c->values[i].f64); + } + break; + + default: + unreachable("Cannot get here from the first level switch"); } } break; @@ -337,11 +394,12 @@ print_constant(nir_constant *c, const struct glsl_type *type, print_state *state for (i = 0; i < cols; i++) { if (i > 0) fprintf(fp, ", "); - fprintf(fp, "0x%08" PRIx64, c->values[0].u64[i]); + fprintf(fp, "0x%08" PRIx64, c->values[i].u64); } break; case GLSL_TYPE_STRUCT: + case GLSL_TYPE_INTERFACE: for (i = 0; i < c->num_elements; i++) { if (i > 0) fprintf(fp, ", "); fprintf(fp, "{ "); @@ -365,7 +423,7 @@ print_constant(nir_constant *c, const struct glsl_type *type, print_state *state } static const char * -get_variable_mode_str(nir_variable_mode mode) +get_variable_mode_str(nir_variable_mode mode, bool want_local_global_mode) { switch (mode) { case nir_var_shader_in: @@ -374,15 +432,20 @@ get_variable_mode_str(nir_variable_mode mode) return "shader_out"; case nir_var_uniform: return "uniform"; - case nir_var_shader_storage: - return "shader_storage"; + case nir_var_mem_ubo: + return "ubo"; case nir_var_system_value: return "system"; - case nir_var_shared: + case nir_var_mem_ssbo: + return "ssbo"; + case nir_var_mem_shared: return "shared"; - case nir_var_param: - case nir_var_global: - case nir_var_local: + case nir_var_mem_global: + return "global"; + case nir_var_shader_temp: + return want_local_global_mode ? "shader_temp" : ""; + case nir_var_function_temp: + return want_local_global_mode ? "function_temp" : ""; default: return ""; } @@ -399,16 +462,34 @@ print_var_decl(nir_variable *var, print_state *state) const char *const samp = (var->data.sample) ? "sample " : ""; const char *const patch = (var->data.patch) ? "patch " : ""; const char *const inv = (var->data.invariant) ? "invariant " : ""; - fprintf(fp, "%s%s%s%s%s %s ", - cent, samp, patch, inv, get_variable_mode_str(var->data.mode), + const char *const per_view = (var->data.per_view) ? "per_view " : ""; + fprintf(fp, "%s%s%s%s%s%s %s ", + cent, samp, patch, inv, per_view, + get_variable_mode_str(var->data.mode, false), glsl_interp_mode_name(var->data.interpolation)); - const char *const coher = (var->data.image.coherent) ? "coherent " : ""; - const char *const volat = (var->data.image._volatile) ? "volatile " : ""; - const char *const restr = (var->data.image.restrict_flag) ? "restrict " : ""; - const char *const ronly = (var->data.image.read_only) ? "readonly " : ""; - const char *const wonly = (var->data.image.write_only) ? "writeonly " : ""; - fprintf(fp, "%s%s%s%s%s", coher, volat, restr, ronly, wonly); + enum gl_access_qualifier access = var->data.access; + const char *const coher = (access & ACCESS_COHERENT) ? "coherent " : ""; + const char *const volat = (access & ACCESS_VOLATILE) ? "volatile " : ""; + const char *const restr = (access & ACCESS_RESTRICT) ? "restrict " : ""; + const char *const ronly = (access & ACCESS_NON_WRITEABLE) ? "readonly " : ""; + const char *const wonly = (access & ACCESS_NON_READABLE) ? "writeonly " : ""; + const char *const reorder = (access & ACCESS_CAN_REORDER) ? "reorderable " : ""; + fprintf(fp, "%s%s%s%s%s%s", coher, volat, restr, ronly, wonly, reorder); + + if (glsl_get_base_type(glsl_without_array(var->type)) == GLSL_TYPE_IMAGE) { + fprintf(fp, "%s ", util_format_short_name(var->data.image.format)); + } + + if (var->data.precision) { + const char *precisions[] = { + "", + "highp", + "mediump", + "lowp", + }; + fprintf(fp, "%s ", precisions[var->data.precision]); + } fprintf(fp, "%s %s", glsl_get_type_name(var->type), get_var_name(var, state)); @@ -416,11 +497,12 @@ print_var_decl(nir_variable *var, print_state *state) if (var->data.mode == nir_var_shader_in || var->data.mode == nir_var_shader_out || var->data.mode == nir_var_uniform || - var->data.mode == nir_var_shader_storage) { + var->data.mode == nir_var_mem_ubo || + var->data.mode == nir_var_mem_ssbo) { const char *loc = NULL; char buf[4]; - switch (state->shader->stage) { + switch (state->shader->info.stage) { case MESA_SHADER_VERTEX: if (var->data.mode == nir_var_shader_in) loc = gl_vert_attrib_name(var->data.location); @@ -441,17 +523,46 @@ print_var_decl(nir_variable *var, print_state *state) case MESA_SHADER_TESS_CTRL: case MESA_SHADER_TESS_EVAL: case MESA_SHADER_COMPUTE: + case MESA_SHADER_KERNEL: default: /* TODO */ break; } if (!loc) { - snprintf(buf, sizeof(buf), "%u", var->data.location); - loc = buf; + if (var->data.location == ~0) { + loc = "~0"; + } else { + snprintf(buf, sizeof(buf), "%u", var->data.location); + loc = buf; + } } - fprintf(fp, " (%s, %u, %u)%s", loc, var->data.driver_location, var->data.binding, + /* For shader I/O vars that have been split to components or packed, + * print the fractional location within the input/output. + */ + unsigned int num_components = + glsl_get_components(glsl_without_array(var->type)); + const char *components = NULL; + char components_local[18] = {'.' /* the rest is 0-filled */}; + switch (var->data.mode) { + case nir_var_shader_in: + case nir_var_shader_out: + if (num_components < 16 && num_components != 0) { + const char *xyzw = comp_mask_string(num_components); + for (int i = 0; i < num_components; i++) + components_local[i + 1] = xyzw[i + var->data.location_frac]; + + components = components_local; + } + break; + default: + break; + } + + fprintf(fp, " (%s%s, %u, %u)%s", loc, + components ? components : "", + var->data.driver_location, var->data.binding, var->data.compact ? " compact" : ""); } @@ -460,92 +571,180 @@ print_var_decl(nir_variable *var, print_state *state) print_constant(var->constant_initializer, var->type, state); fprintf(fp, " }"); } + if (var->pointer_initializer) + fprintf(fp, " = &%s", get_var_name(var->pointer_initializer, state)); fprintf(fp, "\n"); print_annotation(state, var); } static void -print_var(nir_variable *var, print_state *state) +print_deref_link(const nir_deref_instr *instr, bool whole_chain, print_state *state) { FILE *fp = state->fp; - fprintf(fp, "%s", get_var_name(var, state)); -} -static void -print_arg(nir_variable *var, print_state *state) -{ - FILE *fp = state->fp; - fprintf(fp, "%s %s", glsl_get_type_name(var->type), - get_var_name(var, state)); -} + if (instr->deref_type == nir_deref_type_var) { + fprintf(fp, "%s", get_var_name(instr->var, state)); + return; + } else if (instr->deref_type == nir_deref_type_cast) { + fprintf(fp, "(%s *)", glsl_get_type_name(instr->type)); + print_src(&instr->parent, state); + return; + } -static void -print_deref_var(nir_deref_var *deref, print_state *state) -{ - print_var(deref->var, state); + assert(instr->parent.is_ssa); + nir_deref_instr *parent = + nir_instr_as_deref(instr->parent.ssa->parent_instr); + + /* Is the parent we're going to print a bare cast? */ + const bool is_parent_cast = + whole_chain && parent->deref_type == nir_deref_type_cast; + + /* If we're not printing the whole chain, the parent we print will be a SSA + * value that represents a pointer. The only deref type that naturally + * gives a pointer is a cast. + */ + const bool is_parent_pointer = + !whole_chain || parent->deref_type == nir_deref_type_cast; + + /* Struct derefs have a nice syntax that works on pointers, arrays derefs + * do not. + */ + const bool need_deref = + is_parent_pointer && instr->deref_type != nir_deref_type_struct; + + /* Cast need extra parens and so * dereferences */ + if (is_parent_cast || need_deref) + fprintf(fp, "("); + + if (need_deref) + fprintf(fp, "*"); + + if (whole_chain) { + print_deref_link(parent, whole_chain, state); + } else { + print_src(&instr->parent, state); + } + + if (is_parent_cast || need_deref) + fprintf(fp, ")"); + + switch (instr->deref_type) { + case nir_deref_type_struct: + fprintf(fp, "%s%s", is_parent_pointer ? "->" : ".", + glsl_get_struct_elem_name(parent->type, instr->strct.index)); + break; + + case nir_deref_type_array: + case nir_deref_type_ptr_as_array: { + if (nir_src_is_const(instr->arr.index)) { + fprintf(fp, "[%"PRId64"]", nir_src_as_int(instr->arr.index)); + } else { + fprintf(fp, "["); + print_src(&instr->arr.index, state); + fprintf(fp, "]"); + } + break; + } + + case nir_deref_type_array_wildcard: + fprintf(fp, "[*]"); + break; + + default: + unreachable("Invalid deref instruction type"); + } } static void -print_deref_array(nir_deref_array *deref, print_state *state) +print_deref_instr(nir_deref_instr *instr, print_state *state) { FILE *fp = state->fp; - fprintf(fp, "["); - switch (deref->deref_array_type) { - case nir_deref_array_type_direct: - fprintf(fp, "%u", deref->base_offset); + + print_dest(&instr->dest, state); + + switch (instr->deref_type) { + case nir_deref_type_var: + fprintf(fp, " = deref_var "); break; - case nir_deref_array_type_indirect: - if (deref->base_offset != 0) - fprintf(fp, "%u + ", deref->base_offset); - print_src(&deref->indirect, state); + case nir_deref_type_array: + case nir_deref_type_array_wildcard: + fprintf(fp, " = deref_array "); break; - case nir_deref_array_type_wildcard: - fprintf(fp, "*"); + case nir_deref_type_struct: + fprintf(fp, " = deref_struct "); + break; + case nir_deref_type_cast: + fprintf(fp, " = deref_cast "); break; + case nir_deref_type_ptr_as_array: + fprintf(fp, " = deref_ptr_as_array "); + break; + default: + unreachable("Invalid deref instruction type"); + } + + /* Only casts naturally return a pointer type */ + if (instr->deref_type != nir_deref_type_cast) + fprintf(fp, "&"); + + print_deref_link(instr, false, state); + + fprintf(fp, " (%s %s) ", + get_variable_mode_str(instr->mode, true), + glsl_get_type_name(instr->type)); + + if (instr->deref_type != nir_deref_type_var && + instr->deref_type != nir_deref_type_cast) { + /* Print the entire chain as a comment */ + fprintf(fp, "/* &"); + print_deref_link(instr, true, state); + fprintf(fp, " */"); + } + + if (instr->deref_type == nir_deref_type_cast) { + fprintf(fp, " /* ptr_stride=%u */", instr->cast.ptr_stride); } - fprintf(fp, "]"); } -static void -print_deref_struct(nir_deref_struct *deref, const struct glsl_type *parent_type, - print_state *state) +static const char * +vulkan_descriptor_type_name(VkDescriptorType type) { - FILE *fp = state->fp; - fprintf(fp, ".%s", glsl_get_struct_elem_name(parent_type, deref->index)); + switch (type) { + case VK_DESCRIPTOR_TYPE_SAMPLER: return "sampler"; + case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: return "texture+sampler"; + case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: return "texture"; + case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: return "image"; + case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: return "texture-buffer"; + case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: return "image-buffer"; + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: return "UBO"; + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: return "SSBO"; + case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: return "UBO"; + case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: return "SSBO"; + case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: return "input-att"; + case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT: return "inline-UBO"; + default: return "unknown"; + } } static void -print_deref(nir_deref_var *deref, print_state *state) +print_alu_type(nir_alu_type type, print_state *state) { - nir_deref *tail = &deref->deref; - nir_deref *pretail = NULL; - while (tail != NULL) { - switch (tail->deref_type) { - case nir_deref_type_var: - assert(pretail == NULL); - assert(tail == &deref->deref); - print_deref_var(deref, state); - break; - - case nir_deref_type_array: - assert(pretail != NULL); - print_deref_array(nir_deref_as_array(tail), state); - break; - - case nir_deref_type_struct: - assert(pretail != NULL); - print_deref_struct(nir_deref_as_struct(tail), - pretail->type, state); - break; - - default: - unreachable("Invalid deref type"); - } - - pretail = tail; - tail = pretail->child; + FILE *fp = state->fp; + unsigned size = nir_alu_type_get_type_size(type); + const char *name; + + switch (nir_alu_type_get_base_type(type)) { + case nir_type_int: name = "int"; break; + case nir_type_uint: name = "uint"; break; + case nir_type_bool: name = "bool"; break; + case nir_type_float: name = "float"; break; + default: name = "invalid"; } + if (size) + fprintf(fp, "%s%u", name, size); + else + fprintf(fp, "%s", name); } static void @@ -571,15 +770,6 @@ print_intrinsic_instr(nir_intrinsic_instr *instr, print_state *state) fprintf(fp, ") ("); - for (unsigned i = 0; i < info->num_variables; i++) { - if (i != 0) - fprintf(fp, ", "); - - print_deref(instr->variables[i], state); - } - - fprintf(fp, ") ("); - for (unsigned i = 0; i < info->num_indices; i++) { if (i != 0) fprintf(fp, ", "); @@ -599,22 +789,146 @@ print_intrinsic_instr(nir_intrinsic_instr *instr, print_state *state) [NIR_INTRINSIC_BINDING] = "binding", [NIR_INTRINSIC_COMPONENT] = "component", [NIR_INTRINSIC_INTERP_MODE] = "interp_mode", + [NIR_INTRINSIC_REDUCTION_OP] = "reduction_op", + [NIR_INTRINSIC_CLUSTER_SIZE] = "cluster_size", + [NIR_INTRINSIC_PARAM_IDX] = "param_idx", + [NIR_INTRINSIC_IMAGE_DIM] = "image_dim", + [NIR_INTRINSIC_IMAGE_ARRAY] = "image_array", + [NIR_INTRINSIC_ACCESS] = "access", + [NIR_INTRINSIC_SRC_ACCESS] = "src-access", + [NIR_INTRINSIC_DST_ACCESS] = "dst-access", + [NIR_INTRINSIC_FORMAT] = "format", + [NIR_INTRINSIC_ALIGN_MUL] = "align_mul", + [NIR_INTRINSIC_ALIGN_OFFSET] = "align_offset", + [NIR_INTRINSIC_DESC_TYPE] = "desc_type", + [NIR_INTRINSIC_TYPE] = "type", + [NIR_INTRINSIC_SWIZZLE_MASK] = "swizzle_mask", + [NIR_INTRINSIC_DRIVER_LOCATION] = "driver_location", + [NIR_INTRINSIC_MEMORY_SEMANTICS] = "mem_semantics", + [NIR_INTRINSIC_MEMORY_MODES] = "mem_modes", + [NIR_INTRINSIC_MEMORY_SCOPE] = "mem_scope", + [NIR_INTRINSIC_EXECUTION_SCOPE] = "exec_scope", }; for (unsigned idx = 1; idx < NIR_INTRINSIC_NUM_INDEX_FLAGS; idx++) { if (!info->index_map[idx]) continue; fprintf(fp, " /*"); - if (idx == NIR_INTRINSIC_WRMASK) { + switch (idx) { + case NIR_INTRINSIC_WRMASK: { /* special case wrmask to show it as a writemask.. */ unsigned wrmask = nir_intrinsic_write_mask(instr); fprintf(fp, " wrmask="); - for (unsigned i = 0; i < 4; i++) + for (unsigned i = 0; i < instr->num_components; i++) if ((wrmask >> i) & 1) - fprintf(fp, "%c", "xyzw"[i]); - } else { + fprintf(fp, "%c", comp_mask_string(instr->num_components)[i]); + break; + } + + case NIR_INTRINSIC_REDUCTION_OP: { + nir_op reduction_op = nir_intrinsic_reduction_op(instr); + fprintf(fp, " reduction_op=%s", nir_op_infos[reduction_op].name); + break; + } + + case NIR_INTRINSIC_IMAGE_DIM: { + static const char *dim_name[] = { + [GLSL_SAMPLER_DIM_1D] = "1D", + [GLSL_SAMPLER_DIM_2D] = "2D", + [GLSL_SAMPLER_DIM_3D] = "3D", + [GLSL_SAMPLER_DIM_CUBE] = "Cube", + [GLSL_SAMPLER_DIM_RECT] = "Rect", + [GLSL_SAMPLER_DIM_BUF] = "Buf", + [GLSL_SAMPLER_DIM_MS] = "2D-MSAA", + [GLSL_SAMPLER_DIM_SUBPASS] = "Subpass", + [GLSL_SAMPLER_DIM_SUBPASS_MS] = "Subpass-MSAA", + }; + enum glsl_sampler_dim dim = nir_intrinsic_image_dim(instr); + assert(dim < ARRAY_SIZE(dim_name) && dim_name[dim]); + fprintf(fp, " image_dim=%s", dim_name[dim]); + break; + } + + case NIR_INTRINSIC_IMAGE_ARRAY: { + bool array = nir_intrinsic_image_array(instr); + fprintf(fp, " image_array=%s", array ? "true" : "false"); + break; + } + + case NIR_INTRINSIC_DESC_TYPE: { + VkDescriptorType desc_type = nir_intrinsic_desc_type(instr); + fprintf(fp, " desc_type=%s", vulkan_descriptor_type_name(desc_type)); + break; + } + + case NIR_INTRINSIC_TYPE: { + fprintf(fp, " type="); + print_alu_type(nir_intrinsic_type(instr), state); + break; + } + + case NIR_INTRINSIC_SWIZZLE_MASK: { + fprintf(fp, " swizzle_mask="); + unsigned mask = nir_intrinsic_swizzle_mask(instr); + if (instr->intrinsic == nir_intrinsic_quad_swizzle_amd) { + for (unsigned i = 0; i < 4; i++) + fprintf(fp, "%d", (mask >> (i * 2) & 3)); + } else if (instr->intrinsic == nir_intrinsic_masked_swizzle_amd) { + fprintf(fp, "((id & %d) | %d) ^ %d", mask & 0x1F, + (mask >> 5) & 0x1F, + (mask >> 10) & 0x1F); + } else { + fprintf(fp, "%d", mask); + } + break; + } + + case NIR_INTRINSIC_MEMORY_SEMANTICS: { + nir_memory_semantics semantics = nir_intrinsic_memory_semantics(instr); + fprintf(fp, " mem_semantics="); + switch (semantics & (NIR_MEMORY_ACQUIRE | NIR_MEMORY_RELEASE)) { + case 0: fprintf(fp, "NONE"); break; + case NIR_MEMORY_ACQUIRE: fprintf(fp, "ACQ"); break; + case NIR_MEMORY_RELEASE: fprintf(fp, "REL"); break; + default: fprintf(fp, "ACQ|REL"); break; + } + if (semantics & (NIR_MEMORY_MAKE_AVAILABLE)) fprintf(fp, "|AVAILABLE"); + if (semantics & (NIR_MEMORY_MAKE_VISIBLE)) fprintf(fp, "|VISIBLE"); + break; + } + + case NIR_INTRINSIC_MEMORY_MODES: { + fprintf(fp, " mem_modes="); + unsigned int modes = nir_intrinsic_memory_modes(instr); + while (modes) { + nir_variable_mode m = u_bit_scan(&modes); + fprintf(fp, "%s%s", get_variable_mode_str(1 << m, true), modes ? "|" : ""); + } + break; + } + + case NIR_INTRINSIC_EXECUTION_SCOPE: + case NIR_INTRINSIC_MEMORY_SCOPE: { + fprintf(fp, " %s=", index_name[idx]); + nir_scope scope = + idx == NIR_INTRINSIC_MEMORY_SCOPE ? nir_intrinsic_memory_scope(instr) + : nir_intrinsic_execution_scope(instr); + switch (scope) { + case NIR_SCOPE_NONE: fprintf(fp, "NONE"); break; + case NIR_SCOPE_DEVICE: fprintf(fp, "DEVICE"); break; + case NIR_SCOPE_QUEUE_FAMILY: fprintf(fp, "QUEUE_FAMILY"); break; + case NIR_SCOPE_WORKGROUP: fprintf(fp, "WORKGROUP"); break; + case NIR_SCOPE_SUBGROUP: fprintf(fp, "SUBGROUP"); break; + case NIR_SCOPE_INVOCATION: fprintf(fp, "INVOCATION"); break; + } + break; + } + + default: { unsigned off = info->index_map[idx] - 1; assert(index_name[idx]); /* forgot to update index_name table? */ fprintf(fp, " %s=%d", index_name[idx], instr->const_index[off]); + break; + } } fprintf(fp, " */"); } @@ -622,30 +936,32 @@ print_intrinsic_instr(nir_intrinsic_instr *instr, print_state *state) if (!state->shader) return; - struct exec_list *var_list = NULL; - + nir_variable_mode var_mode; switch (instr->intrinsic) { case nir_intrinsic_load_uniform: - var_list = &state->shader->uniforms; + var_mode = nir_var_uniform; break; case nir_intrinsic_load_input: + case nir_intrinsic_load_interpolated_input: case nir_intrinsic_load_per_vertex_input: - var_list = &state->shader->inputs; + var_mode = nir_var_shader_in; break; case nir_intrinsic_load_output: case nir_intrinsic_store_output: case nir_intrinsic_store_per_vertex_output: - var_list = &state->shader->outputs; + var_mode = nir_var_shader_out; break; default: return; } - nir_foreach_variable(var, var_list) { + nir_foreach_variable_with_modes(var, state->shader, var_mode) { if ((var->data.driver_location == nir_intrinsic_base(instr)) && (instr->intrinsic == nir_intrinsic_load_uniform || - var->data.location_frac == nir_intrinsic_component(instr)) && - var->name) { + (nir_intrinsic_component(instr) >= var->data.location_frac && + nir_intrinsic_component(instr) < + (var->data.location_frac + glsl_get_components(var->type)))) && + var->name) { fprintf(fp, "\t/* %s */", var->name); break; } @@ -659,7 +975,9 @@ print_tex_instr(nir_tex_instr *instr, print_state *state) print_dest(&instr->dest, state); - fprintf(fp, " = "); + fprintf(fp, " = ("); + print_alu_type(instr->dest_type, state); + fprintf(fp, ")"); switch (instr->op) { case nir_texop_tex: @@ -680,6 +998,9 @@ print_tex_instr(nir_tex_instr *instr, print_state *state) case nir_texop_txf_ms: fprintf(fp, "txf_ms "); break; + case nir_texop_txf_ms_fb: + fprintf(fp, "txf_ms_fb "); + break; case nir_texop_txf_ms_mcs: fprintf(fp, "txf_ms_mcs "); break; @@ -701,14 +1022,27 @@ print_tex_instr(nir_tex_instr *instr, print_state *state) case nir_texop_samples_identical: fprintf(fp, "samples_identical "); break; + case nir_texop_tex_prefetch: + fprintf(fp, "tex (pre-dispatchable) "); + break; + case nir_texop_fragment_fetch: + fprintf(fp, "fragment_fetch "); + break; + case nir_texop_fragment_mask_fetch: + fprintf(fp, "fragment_mask_fetch "); + break; default: unreachable("Invalid texture operation"); break; } + bool has_texture_deref = false, has_sampler_deref = false; for (unsigned i = 0; i < instr->num_srcs; i++) { - print_src(&instr->src[i].src, state); + if (i > 0) { + fprintf(fp, ", "); + } + print_src(&instr->src[i].src, state); fprintf(fp, " "); switch(instr->src[i].src_type) { @@ -730,6 +1064,9 @@ print_tex_instr(nir_tex_instr *instr, print_state *state) case nir_tex_src_lod: fprintf(fp, "(lod)"); break; + case nir_tex_src_min_lod: + fprintf(fp, "(min_lod)"); + break; case nir_tex_src_ms_index: fprintf(fp, "(ms_index)"); break; @@ -742,12 +1079,26 @@ print_tex_instr(nir_tex_instr *instr, print_state *state) case nir_tex_src_ddy: fprintf(fp, "(ddy)"); break; + case nir_tex_src_texture_deref: + has_texture_deref = true; + fprintf(fp, "(texture_deref)"); + break; + case nir_tex_src_sampler_deref: + has_sampler_deref = true; + fprintf(fp, "(sampler_deref)"); + break; case nir_tex_src_texture_offset: fprintf(fp, "(texture_offset)"); break; case nir_tex_src_sampler_offset: fprintf(fp, "(sampler_offset)"); break; + case nir_tex_src_texture_handle: + fprintf(fp, "(texture_handle)"); + break; + case nir_tex_src_sampler_handle: + fprintf(fp, "(sampler_handle)"); + break; case nir_tex_src_plane: fprintf(fp, "(plane)"); break; @@ -756,25 +1107,36 @@ print_tex_instr(nir_tex_instr *instr, print_state *state) unreachable("Invalid texture source type"); break; } - - fprintf(fp, ", "); } if (instr->op == nir_texop_tg4) { - fprintf(fp, "%u (gather_component), ", instr->component); + fprintf(fp, ", %u (gather_component)", instr->component); } - if (instr->texture) { - print_deref(instr->texture, state); - fprintf(fp, " (texture)"); - if (instr->sampler) { - print_deref(instr->sampler, state); - fprintf(fp, " (sampler)"); + if (nir_tex_instr_has_explicit_tg4_offsets(instr)) { + fprintf(fp, ", { (%i, %i)", instr->tg4_offsets[0][0], instr->tg4_offsets[0][1]); + for (unsigned i = 1; i < 4; ++i) + fprintf(fp, ", (%i, %i)", instr->tg4_offsets[i][0], + instr->tg4_offsets[i][1]); + fprintf(fp, " } (offsets)"); + } + + if (instr->op != nir_texop_txf_ms_fb) { + if (!has_texture_deref) { + fprintf(fp, ", %u (texture)", instr->texture_index); + } + + if (!has_sampler_deref) { + fprintf(fp, ", %u (sampler)", instr->sampler_index); } - } else { - assert(instr->sampler == NULL); - fprintf(fp, "%u (texture) %u (sampler)", - instr->texture_index, instr->sampler_index); + } + + if (instr->texture_non_uniform) { + fprintf(fp, ", texture non-uniform"); + } + + if (instr->sampler_non_uniform) { + fprintf(fp, ", sampler non-uniform"); } } @@ -789,14 +1151,7 @@ print_call_instr(nir_call_instr *instr, print_state *state) if (i != 0) fprintf(fp, ", "); - print_deref(instr->params[i], state); - } - - if (instr->return_deref != NULL) { - if (instr->num_params != 0) - fprintf(fp, ", "); - fprintf(fp, "returning "); - print_deref(instr->return_deref, state); + print_src(&instr->params[i], state); } } @@ -819,11 +1174,25 @@ print_load_const_instr(nir_load_const_instr *instr, print_state *state) * and then print the float in a comment for readability. */ - if (instr->def.bit_size == 64) - fprintf(fp, "0x%16" PRIx64 " /* %f */", instr->value.u64[i], - instr->value.f64[i]); - else - fprintf(fp, "0x%08x /* %f */", instr->value.u32[i], instr->value.f32[i]); + switch (instr->def.bit_size) { + case 64: + fprintf(fp, "0x%16" PRIx64 " /* %f */", instr->value[i].u64, + instr->value[i].f64); + break; + case 32: + fprintf(fp, "0x%08x /* %f */", instr->value[i].u32, instr->value[i].f32); + break; + case 16: + fprintf(fp, "0x%04x /* %f */", instr->value[i].u16, + _mesa_half_to_float(instr->value[i].u16)); + break; + case 8: + fprintf(fp, "0x%02x", instr->value[i].u8); + break; + case 1: + fprintf(fp, "%s", instr->value[i].b ? "true" : "false"); + break; + } } fprintf(fp, ")"); @@ -897,6 +1266,10 @@ print_instr(const nir_instr *instr, print_state *state, unsigned tabs) print_alu_instr(nir_instr_as_alu(instr), state); break; + case nir_instr_type_deref: + print_deref_instr(nir_instr_as_deref(instr), state); + break; + case nir_instr_type_call: print_call_instr(nir_instr_as_call(instr), state); break; @@ -960,7 +1333,6 @@ print_block(nir_block *block, print_state *state, unsigned tabs) nir_block **preds = malloc(block->predecessors->entries * sizeof(nir_block *)); - struct set_entry *entry; unsigned i = 0; set_foreach(block->predecessors, entry) { preds[i++] = (nir_block *) entry->key; @@ -1056,23 +1428,9 @@ print_function_impl(nir_function_impl *impl, print_state *state) fprintf(fp, "\nimpl %s ", impl->function->name); - for (unsigned i = 0; i < impl->num_params; i++) { - if (i != 0) - fprintf(fp, ", "); - - print_arg(impl->params[i], state); - } - - if (impl->return_var != NULL) { - if (impl->num_params != 0) - fprintf(fp, ", "); - fprintf(fp, "returning "); - print_arg(impl->return_var, state); - } - fprintf(fp, "{\n"); - nir_foreach_variable(var, &impl->locals) { + nir_foreach_function_temp_variable(var, impl) { fprintf(fp, "\t"); print_var_decl(var, state); } @@ -1096,34 +1454,8 @@ print_function(nir_function *function, print_state *state) { FILE *fp = state->fp; - fprintf(fp, "decl_function %s ", function->name); - - for (unsigned i = 0; i < function->num_params; i++) { - if (i != 0) - fprintf(fp, ", "); - - switch (function->params[i].param_type) { - case nir_parameter_in: - fprintf(fp, "in "); - break; - case nir_parameter_out: - fprintf(fp, "out "); - break; - case nir_parameter_inout: - fprintf(fp, "inout "); - break; - default: - unreachable("Invalid parameter type"); - } - - fprintf(fp, "%s", glsl_get_type_name(function->params[i].type)); - } - - if (function->return_type != NULL) { - if (function->num_params != 0) - fprintf(fp, ", "); - fprintf(fp, "returning %s", glsl_get_type_name(function->return_type)); - } + fprintf(fp, "decl_function %s (%d params)", function->name, + function->num_params); fprintf(fp, "\n"); @@ -1138,9 +1470,8 @@ init_print_state(print_state *state, nir_shader *shader, FILE *fp) { state->fp = fp; state->shader = shader; - state->ht = _mesa_hash_table_create(NULL, _mesa_hash_pointer, - _mesa_key_pointer_equal); - state->syms = _mesa_set_create(NULL, _mesa_key_hash_string, + state->ht = _mesa_pointer_hash_table_create(NULL); + state->syms = _mesa_set_create(NULL, _mesa_hash_string, _mesa_key_string_equal); state->index = 0; } @@ -1161,46 +1492,36 @@ nir_print_shader_annotated(nir_shader *shader, FILE *fp, state.annotations = annotations; - fprintf(fp, "shader: %s\n", gl_shader_stage_name(shader->stage)); + fprintf(fp, "shader: %s\n", gl_shader_stage_name(shader->info.stage)); + + if (shader->info.name) + fprintf(fp, "name: %s\n", shader->info.name); - if (shader->info->name) - fprintf(fp, "name: %s\n", shader->info->name); + if (shader->info.label) + fprintf(fp, "label: %s\n", shader->info.label); - if (shader->info->label) - fprintf(fp, "label: %s\n", shader->info->label); + if (gl_shader_stage_is_compute(shader->info.stage)) { + fprintf(fp, "local-size: %u, %u, %u%s\n", + shader->info.cs.local_size[0], + shader->info.cs.local_size[1], + shader->info.cs.local_size[2], + shader->info.cs.local_size_variable ? " (variable)" : ""); + fprintf(fp, "shared-size: %u\n", shader->info.cs.shared_size); + } fprintf(fp, "inputs: %u\n", shader->num_inputs); fprintf(fp, "outputs: %u\n", shader->num_outputs); fprintf(fp, "uniforms: %u\n", shader->num_uniforms); + if (shader->info.num_ubos) + fprintf(fp, "ubos: %u\n", shader->info.num_ubos); fprintf(fp, "shared: %u\n", shader->num_shared); + if (shader->scratch_size) + fprintf(fp, "scratch: %u\n", shader->scratch_size); + if (shader->constant_data_size) + fprintf(fp, "constants: %u\n", shader->constant_data_size); - nir_foreach_variable(var, &shader->uniforms) { - print_var_decl(var, &state); - } - - nir_foreach_variable(var, &shader->inputs) { - print_var_decl(var, &state); - } - - nir_foreach_variable(var, &shader->outputs) { - print_var_decl(var, &state); - } - - nir_foreach_variable(var, &shader->shared) { - print_var_decl(var, &state); - } - - nir_foreach_variable(var, &shader->globals) { - print_var_decl(var, &state); - } - - nir_foreach_variable(var, &shader->system_values) { + nir_foreach_variable_in_shader(var, shader) print_var_decl(var, &state); - } - - foreach_list_typed(nir_register, reg, node, &shader->registers) { - print_register_decl(reg, &state); - } foreach_list_typed(nir_function, func, node, &shader->functions) { print_function(func, &state); @@ -1213,6 +1534,7 @@ void nir_print_shader(nir_shader *shader, FILE *fp) { nir_print_shader_annotated(shader, fp, NULL); + fflush(fp); } void @@ -1224,3 +1546,12 @@ nir_print_instr(const nir_instr *instr, FILE *fp) print_instr(instr, &state, 0); } + +void +nir_print_deref(const nir_deref_instr *deref, FILE *fp) +{ + print_state state = { + .fp = fp, + }; + print_deref_link(deref, true, &state); +}