nir: Rework conversion opcodes
[mesa.git] / src / compiler / glsl / glsl_to_nir.cpp
index 0b74b7e5aa3c1eb1b980dce45dcbf6cb87009455..f0557f985bf4b21aa1930b2f449aa9ad789efe22 100644 (file)
@@ -129,6 +129,19 @@ private:
 
 } /* end of anonymous namespace */
 
+static void
+nir_remap_attributes(nir_shader *shader)
+{
+   nir_foreach_variable(var, &shader->inputs) {
+      var->data.location += _mesa_bitcount_64(shader->info->double_inputs_read &
+                                              BITFIELD64_MASK(var->data.location));
+   }
+
+   /* Once the remap is done, reset double_inputs_read, so later it will have
+    * which location/slots are doubles */
+   shader->info->double_inputs_read = 0;
+}
+
 nir_shader *
 glsl_to_nir(const struct gl_shader_program *shader_prog,
             gl_shader_stage stage,
@@ -144,15 +157,18 @@ glsl_to_nir(const struct gl_shader_program *shader_prog,
    v2.run(sh->ir);
    visit_exec_list(sh->ir, &v1);
 
+   nir_lower_constant_initializers(shader, (nir_variable_mode)~0);
+
+   /* Remap the locations to slots so those requiring two slots will occupy
+    * two locations. For instance, if we have in the IR code a dvec3 attr0 in
+    * location 0 and vec4 attr1 in location 1, in NIR attr0 will use
+    * locations/slots 0 and 1, and attr1 will use location/slot 2 */
+   if (shader->stage == MESA_SHADER_VERTEX)
+      nir_remap_attributes(shader);
+
    shader->info->name = ralloc_asprintf(shader, "GLSL%d", shader_prog->Name);
    if (shader_prog->Label)
       shader->info->label = ralloc_strdup(shader, shader_prog->Label);
-   shader->info->num_textures = util_last_bit(sh->Program->SamplersUsed);
-   shader->info->num_ubos = sh->NumUniformBlocks;
-   shader->info->num_ssbos = sh->NumShaderStorageBlocks;
-   shader->info->clip_distance_array_size = sh->Program->ClipDistanceArraySize;
-   shader->info->cull_distance_array_size = sh->Program->CullDistanceArraySize;
-   shader->info->separate_shader = shader_prog->SeparateShader;
    shader->info->has_transform_feedback_varyings =
       shader_prog->TransformFeedback.NumVarying > 0;
 
@@ -205,17 +221,21 @@ constant_copy(ir_constant *ir, void *mem_ctx)
    ret->num_elements = 0;
    switch (ir->type->base_type) {
    case GLSL_TYPE_UINT:
-      for (unsigned c = 0; c < cols; c++) {
-         for (unsigned r = 0; r < rows; r++)
-            ret->values[c].u32[r] = ir->value.u[c * rows + r];
-      }
+      /* Only float base types can be matrices. */
+      assert(cols == 1);
+
+      for (unsigned r = 0; r < rows; r++)
+         ret->values[0].u32[r] = ir->value.u[r];
+
       break;
 
    case GLSL_TYPE_INT:
-      for (unsigned c = 0; c < cols; c++) {
-         for (unsigned r = 0; r < rows; r++)
-            ret->values[c].i32[r] = ir->value.i[c * rows + r];
-      }
+      /* Only float base types can be matrices. */
+      assert(cols == 1);
+
+      for (unsigned r = 0; r < rows; r++)
+         ret->values[0].i32[r] = ir->value.i[r];
+
       break;
 
    case GLSL_TYPE_FLOAT:
@@ -232,13 +252,29 @@ constant_copy(ir_constant *ir, void *mem_ctx)
       }
       break;
 
+   case GLSL_TYPE_UINT64:
+      /* Only float base types can be matrices. */
+      assert(cols == 1);
+
+      for (unsigned r = 0; r < rows; r++)
+         ret->values[0].u64[r] = ir->value.u64[r];
+      break;
+
+   case GLSL_TYPE_INT64:
+      /* Only float base types can be matrices. */
+      assert(cols == 1);
+
+      for (unsigned r = 0; r < rows; r++)
+         ret->values[0].i64[r] = ir->value.i64[r];
+      break;
+
    case GLSL_TYPE_BOOL:
-      for (unsigned c = 0; c < cols; c++) {
-         for (unsigned r = 0; r < rows; r++) {
-            ret->values[c].u32[r] = ir->value.b[c * rows + r] ?
-                                    NIR_TRUE : NIR_FALSE;
-         }
-      }
+      /* Only float base types can be matrices. */
+      assert(cols == 1);
+
+      for (unsigned r = 0; r < rows; r++)
+         ret->values[0].u32[r] = ir->value.b[r] ? NIR_TRUE : NIR_FALSE;
+
       break;
 
    case GLSL_TYPE_STRUCT:
@@ -282,6 +318,7 @@ nir_visitor::visit(ir_variable *ir)
    var->data.patch = ir->data.patch;
    var->data.invariant = ir->data.invariant;
    var->data.location = ir->data.location;
+   var->data.compact = false;
 
    switch(ir->data.mode) {
    case ir_var_auto:
@@ -312,11 +349,30 @@ nir_visitor::visit(ir_variable *ir)
          var->data.mode = nir_var_system_value;
       } else {
          var->data.mode = nir_var_shader_in;
+
+         if (shader->stage == MESA_SHADER_TESS_EVAL &&
+             (ir->data.location == VARYING_SLOT_TESS_LEVEL_INNER ||
+              ir->data.location == VARYING_SLOT_TESS_LEVEL_OUTER)) {
+            var->data.compact = ir->type->without_array()->is_scalar();
+         }
+      }
+
+      /* Mark all the locations that require two slots */
+      if (glsl_type_is_dual_slot(glsl_without_array(var->type))) {
+         for (uint i = 0; i < glsl_count_attribute_slots(var->type, true); i++) {
+            uint64_t bitfield = BITFIELD64_BIT(var->data.location + i);
+            shader->info->double_inputs_read |= bitfield;
+         }
       }
       break;
 
    case ir_var_shader_out:
       var->data.mode = nir_var_shader_out;
+      if (shader->stage == MESA_SHADER_TESS_CTRL &&
+          (ir->data.location == VARYING_SLOT_TESS_LEVEL_INNER ||
+           ir->data.location == VARYING_SLOT_TESS_LEVEL_OUTER)) {
+         var->data.compact = ir->type->without_array()->is_scalar();
+      }
       break;
 
    case ir_var_uniform:
@@ -338,11 +394,6 @@ nir_visitor::visit(ir_variable *ir)
    var->data.interpolation = ir->data.interpolation;
    var->data.origin_upper_left = ir->data.origin_upper_left;
    var->data.pixel_center_integer = ir->data.pixel_center_integer;
-   var->data.explicit_location = ir->data.explicit_location;
-   var->data.explicit_index = ir->data.explicit_index;
-   var->data.explicit_binding = ir->data.explicit_binding;
-   var->data.has_initializer = ir->data.has_initializer;
-   var->data.compact = false;
    var->data.location_frac = ir->data.location_frac;
 
    switch (ir->data.depth_layout) {
@@ -374,7 +425,6 @@ nir_visitor::visit(ir_variable *ir)
    var->data.image._volatile = ir->data.image_volatile;
    var->data.image.restrict_flag = ir->data.image_restrict;
    var->data.image.format = ir->data.image_format;
-   var->data.max_array_access = ir->data.max_array_access;
    var->data.fb_fetch_output = ir->data.fb_fetch_output;
 
    var->num_state_slots = ir->get_num_state_slots();
@@ -470,31 +520,19 @@ nir_visitor::visit(ir_function_signature *ir)
 void
 nir_visitor::visit(ir_loop *ir)
 {
-   nir_loop *loop = nir_loop_create(this->shader);
-   nir_builder_cf_insert(&b, &loop->cf_node);
-
-   b.cursor = nir_after_cf_list(&loop->body);
+   nir_push_loop(&b);
    visit_exec_list(&ir->body_instructions, this);
-   b.cursor = nir_after_cf_node(&loop->cf_node);
+   nir_pop_loop(&b, NULL);
 }
 
 void
 nir_visitor::visit(ir_if *ir)
 {
-   nir_src condition =
-      nir_src_for_ssa(evaluate_rvalue(ir->condition));
-
-   nir_if *if_stmt = nir_if_create(this->shader);
-   if_stmt->condition = condition;
-   nir_builder_cf_insert(&b, &if_stmt->cf_node);
-
-   b.cursor = nir_after_cf_list(&if_stmt->then_list);
+   nir_push_if(&b, evaluate_rvalue(ir->condition));
    visit_exec_list(&ir->then_instructions, this);
-
-   b.cursor = nir_after_cf_list(&if_stmt->else_list);
+   nir_push_else(&b, NULL);
    visit_exec_list(&ir->else_instructions, this);
-
-   b.cursor = nir_after_cf_node(&if_stmt->cf_node);
+   nir_pop_if(&b, NULL);
 }
 
 void
@@ -827,10 +865,11 @@ nir_visitor::visit(ir_call *ir)
 
          /* Set the intrinsic destination. */
          if (ir->return_deref) {
-            const nir_intrinsic_info *info =
-                    &nir_intrinsic_infos[instr->intrinsic];
+            unsigned num_components = ir->return_deref->type->vector_elements;
+            if (instr->intrinsic == nir_intrinsic_image_size)
+               instr->num_components = num_components;
             nir_ssa_dest_init(&instr->instr, &instr->dest,
-                              info->dest_components, 32, NULL);
+                              num_components, 32, NULL);
          }
 
          if (op == nir_intrinsic_image_size ||
@@ -1143,11 +1182,9 @@ nir_visitor::visit(ir_assignment *ir)
       copy->variables[1] = evaluate_deref(&copy->instr, ir->rhs);
 
       if (ir->condition) {
-         nir_if *if_stmt = nir_if_create(this->shader);
-         if_stmt->condition = nir_src_for_ssa(evaluate_rvalue(ir->condition));
-         nir_builder_cf_insert(&b, &if_stmt->cf_node);
-         nir_instr_insert_after_cf_list(&if_stmt->then_list, &copy->instr);
-         b.cursor = nir_after_cf_node(&if_stmt->cf_node);
+         nir_push_if(&b, evaluate_rvalue(ir->condition));
+         nir_builder_instr_insert(&b, &copy->instr);
+         nir_pop_if(&b, NULL);
       } else {
          nir_builder_instr_insert(&b, &copy->instr);
       }
@@ -1178,16 +1215,13 @@ nir_visitor::visit(ir_assignment *ir)
       nir_intrinsic_instr_create(this->shader, nir_intrinsic_store_var);
    store->num_components = ir->lhs->type->vector_elements;
    nir_intrinsic_set_write_mask(store, ir->write_mask);
-   nir_deref *store_deref = nir_copy_deref(store, &lhs_deref->deref);
-   store->variables[0] = nir_deref_as_var(store_deref);
+   store->variables[0] = nir_deref_var_clone(lhs_deref, store);
    store->src[0] = nir_src_for_ssa(src);
 
    if (ir->condition) {
-      nir_if *if_stmt = nir_if_create(this->shader);
-      if_stmt->condition = nir_src_for_ssa(evaluate_rvalue(ir->condition));
-      nir_builder_cf_insert(&b, &if_stmt->cf_node);
-      nir_instr_insert_after_cf_list(&if_stmt->then_list, &store->instr);
-      b.cursor = nir_after_cf_node(&if_stmt->cf_node);
+      nir_push_if(&b, evaluate_rvalue(ir->condition));
+      nir_builder_instr_insert(&b, &store->instr);
+      nir_pop_if(&b, NULL);
    } else {
       nir_builder_instr_insert(&b, &store->instr);
    }
@@ -1274,6 +1308,12 @@ type_is_float(glsl_base_type type)
    return type == GLSL_TYPE_FLOAT || type == GLSL_TYPE_DOUBLE;
 }
 
+static bool
+type_is_signed(glsl_base_type type)
+{
+   return type == GLSL_TYPE_INT || type == GLSL_TYPE_INT64;
+}
+
 void
 nir_visitor::visit(ir_expression *ir)
 {
@@ -1416,38 +1456,67 @@ nir_visitor::visit(ir_expression *ir)
    case ir_unop_exp2: result = nir_fexp2(&b, srcs[0]); break;
    case ir_unop_log2: result = nir_flog2(&b, srcs[0]); break;
    case ir_unop_i2f:
-      result = supports_ints ? nir_i2f(&b, srcs[0]) : nir_fmov(&b, srcs[0]);
+      result = supports_ints ? nir_i2f32(&b, srcs[0]) : nir_fmov(&b, srcs[0]);
       break;
    case ir_unop_u2f:
-      result = supports_ints ? nir_u2f(&b, srcs[0]) : nir_fmov(&b, srcs[0]);
+      result = supports_ints ? nir_u2f32(&b, srcs[0]) : nir_fmov(&b, srcs[0]);
       break;
    case ir_unop_b2f:
       result = supports_ints ? nir_b2f(&b, srcs[0]) : nir_fmov(&b, srcs[0]);
       break;
-   case ir_unop_f2i:  result = nir_f2i(&b, srcs[0]);   break;
-   case ir_unop_f2u:  result = nir_f2u(&b, srcs[0]);   break;
-   case ir_unop_f2b:  result = nir_f2b(&b, srcs[0]);   break;
-   case ir_unop_i2b:  result = nir_i2b(&b, srcs[0]);   break;
-   case ir_unop_b2i:  result = nir_b2i(&b, srcs[0]);   break;
-   case ir_unop_d2f:  result = nir_d2f(&b, srcs[0]);   break;
-   case ir_unop_f2d:  result = nir_f2d(&b, srcs[0]);   break;
-   case ir_unop_d2i:  result = nir_d2i(&b, srcs[0]);   break;
-   case ir_unop_d2u:  result = nir_d2u(&b, srcs[0]);   break;
-   case ir_unop_d2b:  result = nir_d2b(&b, srcs[0]);   break;
+   case ir_unop_f2i:
+   case ir_unop_f2u:
+   case ir_unop_f2b:
+   case ir_unop_i2b:
+   case ir_unop_b2i:
+   case ir_unop_b2i64:
+   case ir_unop_d2f:
+   case ir_unop_f2d:
+   case ir_unop_d2i:
+   case ir_unop_d2u:
+   case ir_unop_d2b:
    case ir_unop_i2d:
-      assert(supports_ints);
-      result = nir_i2d(&b, srcs[0]);
-      break;
    case ir_unop_u2d:
-      assert(supports_ints);
-      result = nir_u2d(&b, srcs[0]);
-      break;
+   case ir_unop_i642i:
+   case ir_unop_i642u:
+   case ir_unop_i642f:
+   case ir_unop_i642b:
+   case ir_unop_i642d:
+   case ir_unop_u642i:
+   case ir_unop_u642u:
+   case ir_unop_u642f:
+   case ir_unop_u642d:
+   case ir_unop_i2i64:
+   case ir_unop_u2i64:
+   case ir_unop_f2i64:
+   case ir_unop_d2i64:
+   case ir_unop_i2u64:
+   case ir_unop_u2u64:
+   case ir_unop_f2u64:
+   case ir_unop_d2u64:
    case ir_unop_i2u:
    case ir_unop_u2i:
+   case ir_unop_i642u64:
+   case ir_unop_u642i64: {
+      nir_alu_type src_type = nir_get_nir_type_for_glsl_base_type(types[0]);
+      nir_alu_type dst_type = nir_get_nir_type_for_glsl_base_type(out_type);
+      result = nir_build_alu(&b, nir_type_conversion_op(src_type, dst_type),
+                                 srcs[0], NULL, NULL, NULL);
+      /* b2i and b2f don't have fixed bit-size versions so the builder will
+       * just assume 32 and we have to fix it up here.
+       */
+      result->bit_size = nir_alu_type_get_type_size(dst_type);
+      break;
+   }
+
    case ir_unop_bitcast_i2f:
    case ir_unop_bitcast_f2i:
    case ir_unop_bitcast_u2f:
    case ir_unop_bitcast_f2u:
+   case ir_unop_bitcast_i642d:
+   case ir_unop_bitcast_d2i64:
+   case ir_unop_bitcast_u642d:
+   case ir_unop_bitcast_d2u64:
    case ir_unop_subroutine_to_int:
       /* no-op */
       result = nir_imov(&b, srcs[0]);
@@ -1496,10 +1565,14 @@ nir_visitor::visit(ir_expression *ir)
       result = nir_unpack_half_2x16(&b, srcs[0]);
       break;
    case ir_unop_pack_double_2x32:
-      result = nir_pack_double_2x32(&b, srcs[0]);
+   case ir_unop_pack_int_2x32:
+   case ir_unop_pack_uint_2x32:
+      result = nir_pack_64_2x32(&b, srcs[0]);
       break;
    case ir_unop_unpack_double_2x32:
-      result = nir_unpack_double_2x32(&b, srcs[0]);
+   case ir_unop_unpack_int_2x32:
+   case ir_unop_unpack_uint_2x32:
+      result = nir_unpack_64_2x32(&b, srcs[0]);
       break;
    case ir_unop_bitfield_reverse:
       result = nir_bitfield_reverse(&b, srcs[0]);
@@ -1591,7 +1664,7 @@ nir_visitor::visit(ir_expression *ir)
    case ir_binop_div:
       if (type_is_float(out_type))
          result = nir_fdiv(&b, srcs[0], srcs[1]);
-      else if (out_type == GLSL_TYPE_INT)
+      else if (type_is_signed(out_type))
          result = nir_idiv(&b, srcs[0], srcs[1]);
       else
          result = nir_udiv(&b, srcs[0], srcs[1]);
@@ -1603,7 +1676,7 @@ nir_visitor::visit(ir_expression *ir)
    case ir_binop_min:
       if (type_is_float(out_type))
          result = nir_fmin(&b, srcs[0], srcs[1]);
-      else if (out_type == GLSL_TYPE_INT)
+      else if (type_is_signed(out_type))
          result = nir_imin(&b, srcs[0], srcs[1]);
       else
          result = nir_umin(&b, srcs[0], srcs[1]);
@@ -1611,7 +1684,7 @@ nir_visitor::visit(ir_expression *ir)
    case ir_binop_max:
       if (type_is_float(out_type))
          result = nir_fmax(&b, srcs[0], srcs[1]);
-      else if (out_type == GLSL_TYPE_INT)
+      else if (type_is_signed(out_type))
          result = nir_imax(&b, srcs[0], srcs[1]);
       else
          result = nir_umax(&b, srcs[0], srcs[1]);
@@ -1634,8 +1707,8 @@ nir_visitor::visit(ir_expression *ir)
       break;
    case ir_binop_lshift: result = nir_ishl(&b, srcs[0], srcs[1]); break;
    case ir_binop_rshift:
-      result = (out_type == GLSL_TYPE_INT) ? nir_ishr(&b, srcs[0], srcs[1])
-                                           : nir_ushr(&b, srcs[0], srcs[1]);
+      result = (type_is_signed(out_type)) ? nir_ishr(&b, srcs[0], srcs[1])
+                                          : nir_ushr(&b, srcs[0], srcs[1]);
       break;
    case ir_binop_imul_high:
       result = (out_type == GLSL_TYPE_INT) ? nir_imul_high(&b, srcs[0], srcs[1])
@@ -1647,7 +1720,7 @@ nir_visitor::visit(ir_expression *ir)
       if (supports_ints) {
          if (type_is_float(types[0]))
             result = nir_flt(&b, srcs[0], srcs[1]);
-         else if (types[0] == GLSL_TYPE_INT)
+         else if (type_is_signed(types[0]))
             result = nir_ilt(&b, srcs[0], srcs[1]);
          else
             result = nir_ult(&b, srcs[0], srcs[1]);
@@ -1659,7 +1732,7 @@ nir_visitor::visit(ir_expression *ir)
       if (supports_ints) {
          if (type_is_float(types[0]))
             result = nir_flt(&b, srcs[1], srcs[0]);
-         else if (types[0] == GLSL_TYPE_INT)
+         else if (type_is_signed(types[0]))
             result = nir_ilt(&b, srcs[1], srcs[0]);
          else
             result = nir_ult(&b, srcs[1], srcs[0]);
@@ -1671,7 +1744,7 @@ nir_visitor::visit(ir_expression *ir)
       if (supports_ints) {
          if (type_is_float(types[0]))
             result = nir_fge(&b, srcs[1], srcs[0]);
-         else if (types[0] == GLSL_TYPE_INT)
+         else if (type_is_signed(types[0]))
             result = nir_ige(&b, srcs[1], srcs[0]);
          else
             result = nir_uge(&b, srcs[1], srcs[0]);
@@ -1683,7 +1756,7 @@ nir_visitor::visit(ir_expression *ir)
       if (supports_ints) {
          if (type_is_float(types[0]))
             result = nir_fge(&b, srcs[0], srcs[1]);
-         else if (types[0] == GLSL_TYPE_INT)
+         else if (type_is_signed(types[0]))
             result = nir_ige(&b, srcs[0], srcs[1]);
          else
             result = nir_uge(&b, srcs[0], srcs[1]);
@@ -1897,7 +1970,7 @@ nir_visitor::visit(ir_texture *ir)
 
    if (ir->projector != NULL)
       num_srcs++;
-   if (ir->shadow_comparitor != NULL)
+   if (ir->shadow_comparator != NULL)
       num_srcs++;
    if (ir->offset != NULL)
       num_srcs++;
@@ -1945,10 +2018,10 @@ nir_visitor::visit(ir_texture *ir)
       src_number++;
    }
 
-   if (ir->shadow_comparitor != NULL) {
+   if (ir->shadow_comparator != NULL) {
       instr->src[src_number].src =
-         nir_src_for_ssa(evaluate_rvalue(ir->shadow_comparitor));
-      instr->src[src_number].src_type = nir_tex_src_comparitor;
+         nir_src_for_ssa(evaluate_rvalue(ir->shadow_comparator));
+      instr->src[src_number].src_type = nir_tex_src_comparator;
       src_number++;
    }