tgsi/mesa: handle KERNEL case
[mesa.git] / src / gallium / auxiliary / nir / tgsi_to_nir.c
index 1195d522239b792af4b4f2741c4e8780ed3c3d1d..ddc97973b03522fa2d0c0bb4c1332a2885a57a13 100644 (file)
@@ -28,8 +28,6 @@
 #include "compiler/nir/nir.h"
 #include "compiler/nir/nir_control_flow.h"
 #include "compiler/nir/nir_builder.h"
-#include "compiler/glsl/gl_nir.h"
-#include "compiler/glsl/list.h"
 #include "compiler/shader_enums.h"
 
 #include "tgsi_to_nir.h"
@@ -102,7 +100,6 @@ struct ttn_compile {
    /* How many TGSI_FILE_IMMEDIATE vec4s have been parsed so far. */
    unsigned next_imm;
 
-   bool cap_scalar;
    bool cap_face_is_sysval;
    bool cap_position_is_sysval;
    bool cap_point_is_sysval;
@@ -136,6 +133,7 @@ tgsi_varying_semantic_to_slot(unsigned semantic, unsigned index)
    case TGSI_SEMANTIC_PSIZE:
       return VARYING_SLOT_PSIZ;
    case TGSI_SEMANTIC_GENERIC:
+      assert(index < 32);
       return VARYING_SLOT_VAR0 + index;
    case TGSI_SEMANTIC_FACE:
       return VARYING_SLOT_FACE;
@@ -151,6 +149,7 @@ tgsi_varying_semantic_to_slot(unsigned semantic, unsigned index)
    case TGSI_SEMANTIC_CLIPVERTEX:
       return VARYING_SLOT_CLIP_VERTEX;
    case TGSI_SEMANTIC_TEXCOORD:
+      assert(index < 8);
       return VARYING_SLOT_TEX0 + index;
    case TGSI_SEMANTIC_PCOORD:
       return VARYING_SLOT_PNTC;
@@ -158,6 +157,10 @@ tgsi_varying_semantic_to_slot(unsigned semantic, unsigned index)
       return VARYING_SLOT_VIEWPORT;
    case TGSI_SEMANTIC_LAYER:
       return VARYING_SLOT_LAYER;
+   case TGSI_SEMANTIC_TESSINNER:
+      return VARYING_SLOT_TESS_LEVEL_INNER;
+   case TGSI_SEMANTIC_TESSOUTER:
+      return VARYING_SLOT_TESS_LEVEL_OUTER;
    default:
       fprintf(stderr, "Bad TGSI semantic: %d/%d\n", semantic, index);
       abort();
@@ -214,7 +217,7 @@ ttn_translate_interp_mode(unsigned tgsi_interp)
    case TGSI_INTERPOLATE_PERSPECTIVE:
       return INTERP_MODE_SMOOTH;
    case TGSI_INTERPOLATE_COLOR:
-      return INTERP_MODE_SMOOTH;
+      return INTERP_MODE_NONE;
    default:
       unreachable("bad TGSI interpolation mode");
    }
@@ -393,6 +396,9 @@ ttn_emit_declaration(struct ttn_compile *c)
             var->data.index = 0;
             var->data.interpolation =
                ttn_translate_interp_mode(decl->Interp.Interpolate);
+            var->data.patch = semantic_name == TGSI_SEMANTIC_TESSINNER ||
+                              semantic_name == TGSI_SEMANTIC_TESSOUTER ||
+                              semantic_name == TGSI_SEMANTIC_PATCH;
 
             if (c->scan->processor == PIPE_SHADER_FRAGMENT) {
                switch (semantic_name) {
@@ -418,6 +424,10 @@ ttn_emit_declaration(struct ttn_compile *c)
                   var->data.location = FRAG_RESULT_DEPTH;
                   var->type = glsl_float_type();
                   break;
+               case TGSI_SEMANTIC_STENCIL:
+                  var->data.location = FRAG_RESULT_STENCIL;
+                  var->type = glsl_int_type();
+                  break;
                default:
                   fprintf(stderr, "Bad TGSI semantic: %d/%d\n",
                           decl->Semantic.Name, decl->Semantic.Index);
@@ -426,6 +436,10 @@ ttn_emit_declaration(struct ttn_compile *c)
             } else {
                var->data.location =
                   tgsi_varying_semantic_to_slot(semantic_name, semantic_index);
+               if (var->data.location == VARYING_SLOT_FOGC ||
+                   var->data.location == VARYING_SLOT_PSIZ) {
+                  var->type = glsl_float_type();
+               }
             }
 
             if (is_array) {
@@ -628,13 +642,30 @@ ttn_src_for_file_and_index(struct ttn_compile *c, unsigned file, unsigned index,
          op = nir_intrinsic_load_work_group_id;
          load = nir_load_work_group_id(b);
          break;
+      case TGSI_SEMANTIC_CS_USER_DATA_AMD:
+         op = nir_intrinsic_load_user_data_amd;
+         load = nir_load_user_data_amd(b);
+         break;
+      case TGSI_SEMANTIC_TESS_DEFAULT_INNER_LEVEL:
+         op = nir_intrinsic_load_tess_level_inner_default;
+         load = nir_load_tess_level_inner_default(b);
+         break;
+      case TGSI_SEMANTIC_TESS_DEFAULT_OUTER_LEVEL:
+         op = nir_intrinsic_load_tess_level_outer_default;
+         load = nir_load_tess_level_outer_default(b);
+         break;
       default:
          unreachable("bad system value");
       }
 
+      if (load->num_components == 2)
+         load = nir_swizzle(b, load, SWIZ(X, Y, Y, Y), 4);
+      else if (load->num_components == 3)
+         load = nir_swizzle(b, load, SWIZ(X, Y, Z, Z), 4);
+
       src = nir_src_for_ssa(load);
       b->shader->info.system_values_read |=
-         (1 << nir_system_value_from_intrinsic(op));
+         (1ull << nir_system_value_from_intrinsic(op));
 
       break;
    }
@@ -1083,7 +1114,11 @@ ttn_kill(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
 static void
 ttn_kill_if(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
 {
+   /* flt must be exact, because NaN shouldn't discard. (apps rely on this) */
+   b->exact = true;
    nir_ssa_def *cmp = nir_bany(b, nir_flt(b, src[0], nir_imm_float(b, 0.0)));
+   b->exact = false;
+
    nir_intrinsic_instr *discard =
       nir_intrinsic_instr_create(b->shader, nir_intrinsic_discard_if);
    discard->src[0] = nir_src_for_ssa(cmp);
@@ -1279,7 +1314,8 @@ get_sampler_var(struct ttn_compile *c, int binding,
                 enum glsl_sampler_dim dim,
                 bool is_shadow,
                 bool is_array,
-                enum glsl_base_type base_type)
+                enum glsl_base_type base_type,
+                nir_texop op)
 {
    nir_variable *var = c->samplers[binding];
    if (!var) {
@@ -1290,6 +1326,14 @@ get_sampler_var(struct ttn_compile *c, int binding,
       var->data.binding = binding;
       var->data.explicit_binding = true;
       c->samplers[binding] = var;
+
+      /* Record textures used */
+      unsigned mask = 1 << binding;
+      c->build.shader->info.textures_used |= mask;
+      if (op == nir_texop_txf ||
+          op == nir_texop_txf_ms ||
+          op == nir_texop_txf_ms_mcs)
+         c->build.shader->info.textures_used_by_txf |= mask;
    }
 
    return var;
@@ -1311,7 +1355,7 @@ get_image_var(struct ttn_compile *c, int binding,
       var = nir_variable_create(c->build.shader, nir_var_uniform, type, "image");
       var->data.binding = binding;
       var->data.explicit_binding = true;
-      var->data.image.access = access;
+      var->data.access = access;
       var->data.image.format = format;
       c->images[binding] = var;
    }
@@ -1376,6 +1420,7 @@ ttn_tex(struct ttn_compile *c, nir_alu_dest dest, nir_ssa_def **src)
       samp = 2;
       break;
    case TGSI_OPCODE_TXL:
+   case TGSI_OPCODE_TEX_LZ:
       op = nir_texop_txl;
       num_srcs = 2;
       break;
@@ -1473,7 +1518,8 @@ ttn_tex(struct ttn_compile *c, nir_alu_dest dest, nir_ssa_def **src)
       get_sampler_var(c, sview, instr->sampler_dim,
                       instr->is_shadow,
                       instr->is_array,
-                      base_type_for_alu_type(instr->dest_type));
+                      base_type_for_alu_type(instr->dest_type),
+                      op);
 
    nir_deref_instr *deref = nir_build_deref_var(b, var);
 
@@ -1510,8 +1556,12 @@ ttn_tex(struct ttn_compile *c, nir_alu_dest dest, nir_ssa_def **src)
       src_number++;
    }
 
-   if (tgsi_inst->Instruction.Opcode == TGSI_OPCODE_TXL) {
-      instr->src[src_number].src = nir_src_for_ssa(ttn_channel(b, src[0], W));
+   if (tgsi_inst->Instruction.Opcode == TGSI_OPCODE_TXL ||
+       tgsi_inst->Instruction.Opcode == TGSI_OPCODE_TEX_LZ) {
+      if (tgsi_inst->Instruction.Opcode == TGSI_OPCODE_TEX_LZ)
+         instr->src[src_number].src = nir_src_for_ssa(nir_imm_int(b, 0));
+      else
+         instr->src[src_number].src = nir_src_for_ssa(ttn_channel(b, src[0], W));
       instr->src[src_number].src_type = nir_tex_src_lod;
       src_number++;
    }
@@ -1633,7 +1683,8 @@ ttn_txq(struct ttn_compile *c, nir_alu_dest dest, nir_ssa_def **src)
       get_sampler_var(c, tex_index, txs->sampler_dim,
                       txs->is_shadow,
                       txs->is_array,
-                      base_type_for_alu_type(txs->dest_type));
+                      base_type_for_alu_type(txs->dest_type),
+                      nir_texop_txs);
 
    nir_deref_instr *deref = nir_build_deref_var(b, var);
 
@@ -1694,6 +1745,9 @@ static GLenum
 get_image_format(struct tgsi_full_instruction *tgsi_inst)
 {
    switch (tgsi_inst->Memory.Format) {
+   case PIPE_FORMAT_NONE:
+      return GL_NONE;
+
    case PIPE_FORMAT_R8_UNORM:
       return GL_R8;
    case PIPE_FORMAT_R8G8_UNORM:
@@ -1865,14 +1919,11 @@ ttn_mem(struct ttn_compile *c, nir_alu_dest dest, nir_ssa_def **src)
                        dim, is_array, base_type, access, format);
       nir_deref_instr *image_deref = nir_build_deref_var(b, image);
       const struct glsl_type *type = image_deref->type;
-      unsigned coord_components = glsl_get_sampler_coordinate_components(type);
 
-      nir_intrinsic_set_access(instr, image_deref->var->data.image.access);
+      nir_intrinsic_set_access(instr, image_deref->var->data.access);
 
       instr->src[0] = nir_src_for_ssa(&image_deref->dest.ssa);
-      instr->src[1] = nir_src_for_ssa(nir_swizzle(b, src[addr_src_index],
-                                                  SWIZ(X, Y, Z, W),
-                                                  coord_components));
+      instr->src[1] = nir_src_for_ssa(src[addr_src_index]);
 
       /* Set the sample argument, which is undefined for single-sample images. */
       if (glsl_get_sampler_dim(type) == GLSL_SAMPLER_DIM_MS) {
@@ -1892,8 +1943,7 @@ ttn_mem(struct ttn_compile *c, nir_alu_dest dest, nir_ssa_def **src)
 
 
    if (tgsi_inst->Instruction.Opcode == TGSI_OPCODE_LOAD) {
-      nir_ssa_dest_init(&instr->instr, &instr->dest,
-                        util_last_bit(tgsi_inst->Dst[0].Register.WriteMask),
+      nir_ssa_dest_init(&instr->instr, &instr->dest, instr->num_components,
                         32, NULL);
       nir_builder_instr_insert(b, &instr->instr);
       ttn_move_dest(b, dest, &instr->dest.ssa);
@@ -1920,6 +1970,7 @@ static const nir_op op_trans[TGSI_OPCODE_LAST] = {
    [TGSI_OPCODE_SLT] = nir_op_slt,
    [TGSI_OPCODE_SGE] = nir_op_sge,
    [TGSI_OPCODE_MAD] = nir_op_ffma,
+   [TGSI_OPCODE_TEX_LZ] = 0,
    [TGSI_OPCODE_LRP] = 0,
    [TGSI_OPCODE_SQRT] = nir_op_fsqrt,
    [TGSI_OPCODE_FRC] = nir_op_ffract,
@@ -2208,6 +2259,7 @@ ttn_emit_instruction(struct ttn_compile *c)
       break;
 
    case TGSI_OPCODE_TEX:
+   case TGSI_OPCODE_TEX_LZ:
    case TGSI_OPCODE_TXP:
    case TGSI_OPCODE_TXL:
    case TGSI_OPCODE_TXB:
@@ -2319,12 +2371,21 @@ ttn_add_output_stores(struct ttn_compile *c)
       src.reg.base_offset = c->output_regs[i].offset;
 
       nir_ssa_def *store_value = nir_ssa_for_src(b, src, 4);
-      if (c->build.shader->info.stage == MESA_SHADER_FRAGMENT &&
-          var->data.location == FRAG_RESULT_DEPTH) {
-         /* TGSI uses TGSI_SEMANTIC_POSITION.z for the depth output, while
-          * NIR uses a single float FRAG_RESULT_DEPTH.
+      if (c->build.shader->info.stage == MESA_SHADER_FRAGMENT) {
+         /* TGSI uses TGSI_SEMANTIC_POSITION.z for the depth output
+          * and TGSI_SEMANTIC_STENCIL.y for the stencil output,
+          * while NIR uses a single-component output.
           */
-         store_value = nir_channel(b, store_value, 2);
+         if (var->data.location == FRAG_RESULT_DEPTH)
+            store_value = nir_channel(b, store_value, 2);
+         else if (var->data.location == FRAG_RESULT_STENCIL)
+            store_value = nir_channel(b, store_value, 1);
+      } else {
+         /* FOGC and PSIZ are scalar values */
+         if (var->data.location == VARYING_SLOT_FOGC ||
+             var->data.location == VARYING_SLOT_PSIZ) {
+            store_value = nir_channel(b, store_value, 0);
+         }
       }
 
       nir_store_deref(b, nir_build_deref_var(b, var), store_value,
@@ -2370,7 +2431,6 @@ static void
 ttn_read_pipe_caps(struct ttn_compile *c,
                    struct pipe_screen *screen)
 {
-   c->cap_scalar = screen->get_shader_param(screen, c->scan->processor, PIPE_SHADER_CAP_SCALAR_ISA);
    c->cap_packed_uniforms = screen->get_param(screen, PIPE_CAP_PACKED_UNIFORMS);
    c->cap_samplers_as_deref = screen->get_param(screen, PIPE_CAP_NIR_SAMPLERS_AS_DEREF);
    c->cap_face_is_sysval = screen->get_param(screen, PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL);
@@ -2421,6 +2481,10 @@ ttn_compile_init(const void *tgsi_tokens,
    s->num_inputs = scan.file_max[TGSI_FILE_INPUT] + 1;
    s->num_uniforms = scan.const_file_max[0] + 1;
    s->num_outputs = scan.file_max[TGSI_FILE_OUTPUT] + 1;
+   s->info.num_ssbos = util_last_bit(scan.shader_buffers_declared);
+   s->info.num_ubos = util_last_bit(scan.const_buffers_declared >> 1);
+   s->info.num_images = util_last_bit(scan.images_declared);
+   s->info.num_textures = util_last_bit(scan.samplers_declared);
 
    for (unsigned i = 0; i < TGSI_PROPERTY_COUNT; i++) {
       unsigned value = scan.properties[i];
@@ -2429,31 +2493,43 @@ ttn_compile_init(const void *tgsi_tokens,
       case TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS:
          break; /* handled in ttn_emit_declaration */
       case TGSI_PROPERTY_FS_COORD_ORIGIN:
-         s->info.fs.origin_upper_left = value == TGSI_FS_COORD_ORIGIN_UPPER_LEFT;
+         if (s->info.stage == MESA_SHADER_FRAGMENT)
+            s->info.fs.origin_upper_left = value == TGSI_FS_COORD_ORIGIN_UPPER_LEFT;
          break;
       case TGSI_PROPERTY_FS_COORD_PIXEL_CENTER:
-         s->info.fs.pixel_center_integer = value == TGSI_FS_COORD_PIXEL_CENTER_INTEGER;
+         if (s->info.stage == MESA_SHADER_FRAGMENT)
+            s->info.fs.pixel_center_integer = value == TGSI_FS_COORD_PIXEL_CENTER_INTEGER;
          break;
       case TGSI_PROPERTY_FS_DEPTH_LAYOUT:
-         s->info.fs.depth_layout = ttn_get_depth_layout(value);
+         if (s->info.stage == MESA_SHADER_FRAGMENT)
+            s->info.fs.depth_layout = ttn_get_depth_layout(value);
          break;
       case TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION:
-         s->info.vs.window_space_position = value;
+         if (s->info.stage == MESA_SHADER_VERTEX)
+            s->info.vs.window_space_position = value;
          break;
       case TGSI_PROPERTY_NEXT_SHADER:
          s->info.next_stage = tgsi_processor_to_shader_stage(value);
          break;
       case TGSI_PROPERTY_VS_BLIT_SGPRS_AMD:
-         s->info.vs.blit_sgprs_amd = value;
+         if (s->info.stage == MESA_SHADER_VERTEX)
+            s->info.vs.blit_sgprs_amd = value;
          break;
       case TGSI_PROPERTY_CS_FIXED_BLOCK_WIDTH:
-         s->info.cs.local_size[0] = value;
+         if (s->info.stage == MESA_SHADER_COMPUTE)
+            s->info.cs.local_size[0] = value;
          break;
       case TGSI_PROPERTY_CS_FIXED_BLOCK_HEIGHT:
-         s->info.cs.local_size[1] = value;
+         if (s->info.stage == MESA_SHADER_COMPUTE)
+            s->info.cs.local_size[1] = value;
          break;
       case TGSI_PROPERTY_CS_FIXED_BLOCK_DEPTH:
-         s->info.cs.local_size[2] = value;
+         if (s->info.stage == MESA_SHADER_COMPUTE)
+            s->info.cs.local_size[2] = value;
+         break;
+      case TGSI_PROPERTY_CS_USER_DATA_COMPONENTS_AMD:
+         if (s->info.stage == MESA_SHADER_COMPUTE)
+            s->info.cs.user_data_components_amd = value;
          break;
       default:
          if (value) {
@@ -2499,7 +2575,7 @@ ttn_compile_init(const void *tgsi_tokens,
 }
 
 static void
-ttn_optimize_nir(nir_shader *nir, bool scalar)
+ttn_optimize_nir(nir_shader *nir)
 {
    bool progress;
    do {
@@ -2507,8 +2583,8 @@ ttn_optimize_nir(nir_shader *nir, bool scalar)
 
       NIR_PASS_V(nir, nir_lower_vars_to_ssa);
 
-      if (scalar) {
-         NIR_PASS_V(nir, nir_lower_alu_to_scalar, NULL);
+      if (nir->options->lower_to_scalar) {
+         NIR_PASS_V(nir, nir_lower_alu_to_scalar, NULL, NULL);
          NIR_PASS_V(nir, nir_lower_phis_to_scalar);
       }
 
@@ -2550,7 +2626,7 @@ ttn_optimize_nir(nir_shader *nir, bool scalar)
  * so we have to do it here too.
  */
 static void
-ttn_finalize_nir(struct ttn_compile *c)
+ttn_finalize_nir(struct ttn_compile *c, struct pipe_screen *screen)
 {
    struct nir_shader *nir = c->build.shader;
 
@@ -2565,13 +2641,16 @@ ttn_finalize_nir(struct ttn_compile *c)
    if (c->cap_packed_uniforms)
       NIR_PASS_V(nir, nir_lower_uniforms_to_ubo, 16);
 
-   if (c->cap_samplers_as_deref)
-      NIR_PASS_V(nir, gl_nir_lower_samplers_as_deref, NULL);
-   else
-      NIR_PASS_V(nir, gl_nir_lower_samplers, NULL);
+   if (!c->cap_samplers_as_deref)
+      NIR_PASS_V(nir, nir_lower_samplers);
+
+   if (screen->finalize_nir) {
+      screen->finalize_nir(screen, nir, true);
+   } else {
+      ttn_optimize_nir(nir);
+      nir_shader_gather_info(nir, c->build.impl);
+   }
 
-   ttn_optimize_nir(nir, c->cap_scalar);
-   nir_shader_gather_info(nir, c->build.impl);
    nir_validate_shader(nir, "TTN: after all optimizations");
 }
 
@@ -2584,7 +2663,7 @@ tgsi_to_nir(const void *tgsi_tokens,
 
    c = ttn_compile_init(tgsi_tokens, NULL, screen);
    s = c->build.shader;
-   ttn_finalize_nir(c);
+   ttn_finalize_nir(c, screen);
    ralloc_free(c);
 
    return s;