Module: Mesa
Branch: master
Commit: 588bb6686b38ecb6316269fe20792dea5aab819d
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=588bb6686b38ecb6316269fe20792dea5aab819d

Author: Jason Ekstrand <[email protected]>
Date:   Wed Sep 30 15:19:45 2020 -0500

nir: Add a conversion and rounding intrinsic

This new intrinsic is capable of handling the full range of conversions
from OpenCL including rounding modes and possible saturation.  The
intention is that we'll emit this intrinsic directly from spirv_to_nir
and then lower it to ALU ops later.

Reviewed-by: Jesse Natalie <[email protected]>
Reviewed-by: Daniel Stone <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6945>

---

 src/compiler/nir/nir.h             | 16 ++++++++++++++--
 src/compiler/nir/nir_builder.h     | 24 ++++++++++++++++++++++++
 src/compiler/nir/nir_intrinsics.py | 12 ++++++++++--
 src/compiler/nir/nir_print.c       | 15 +++++++++++++++
 src/compiler/nir/nir_validate.c    | 10 ++++++++++
 5 files changed, 73 insertions(+), 4 deletions(-)

diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index b0a3da53cfb..ad96dbace24 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -1736,12 +1736,12 @@ typedef enum {
    NIR_INTRINSIC_DESC_TYPE,
 
    /**
-    * The nir_alu_type of input data to a store
+    * The nir_alu_type of input data to a store or conversion
     */
    NIR_INTRINSIC_SRC_TYPE,
 
    /**
-    * The nir_alu_type of the data output from a load
+    * The nir_alu_type of the data output from a load or conversion
     */
    NIR_INTRINSIC_DEST_TYPE,
 
@@ -1783,6 +1783,16 @@ typedef enum {
     */
    NIR_INTRINSIC_IO_SEMANTICS,
 
+   /**
+    * The rounding mode of a conversion
+    */
+   NIR_INTRINSIC_ROUNDING_MODE,
+
+   /**
+    * Whether or not to saturate in conversions
+    */
+   NIR_INTRINSIC_SATURATE,
+
    NIR_INTRINSIC_NUM_INDEX_FLAGS,
 
 } nir_intrinsic_index_flag;
@@ -1949,6 +1959,8 @@ INTRINSIC_IDX_ACCESSORS(memory_semantics, 
MEMORY_SEMANTICS, nir_memory_semantics
 INTRINSIC_IDX_ACCESSORS(memory_modes, MEMORY_MODES, nir_variable_mode)
 INTRINSIC_IDX_ACCESSORS(memory_scope, MEMORY_SCOPE, nir_scope)
 INTRINSIC_IDX_ACCESSORS(execution_scope, EXECUTION_SCOPE, nir_scope)
+INTRINSIC_IDX_ACCESSORS(rounding_mode, ROUNDING_MODE, nir_rounding_mode)
+INTRINSIC_IDX_ACCESSORS(saturate, SATURATE, bool)
 
 static inline void
 nir_intrinsic_set_align(nir_intrinsic_instr *intrin,
diff --git a/src/compiler/nir/nir_builder.h b/src/compiler/nir/nir_builder.h
index a70bb3c6dbc..2b340bac700 100644
--- a/src/compiler/nir/nir_builder.h
+++ b/src/compiler/nir/nir_builder.h
@@ -1476,6 +1476,30 @@ nir_load_reloc_const_intel(nir_builder *b, uint32_t id)
    return &load->dest.ssa;
 }
 
+static inline nir_ssa_def *
+nir_convert_alu_types(nir_builder *b, nir_ssa_def *src,
+                      nir_alu_type src_type, nir_alu_type dest_type,
+                      nir_rounding_mode round, bool saturate)
+{
+   assert(nir_alu_type_get_type_size(dest_type) != 0);
+   assert(nir_alu_type_get_type_size(src_type) == 0 ||
+          nir_alu_type_get_type_size(src_type) == src->bit_size);
+   src_type = (nir_alu_type)(src_type | src->bit_size);
+
+   nir_intrinsic_instr *conv =
+      nir_intrinsic_instr_create(b->shader, nir_intrinsic_convert_alu_types);
+   conv->src[0] = nir_src_for_ssa(src);
+   conv->num_components = src->num_components;
+   nir_intrinsic_set_src_type(conv, src_type);
+   nir_intrinsic_set_dest_type(conv, dest_type);
+   nir_intrinsic_set_rounding_mode(conv, round);
+   nir_intrinsic_set_saturate(conv, saturate);
+   nir_ssa_dest_init(&conv->instr, &conv->dest, src->num_components,
+                     nir_alu_type_get_type_size(dest_type), NULL);
+   nir_builder_instr_insert(b, &conv->instr);
+   return &conv->dest.ssa;
+}
+
 #include "nir_builder_opcodes.h"
 
 static inline nir_ssa_def *
diff --git a/src/compiler/nir/nir_intrinsics.py 
b/src/compiler/nir/nir_intrinsics.py
index 257caa66e0f..957eeffcae1 100644
--- a/src/compiler/nir/nir_intrinsics.py
+++ b/src/compiler/nir/nir_intrinsics.py
@@ -124,9 +124,9 @@ ALIGN_MUL = "NIR_INTRINSIC_ALIGN_MUL"
 ALIGN_OFFSET = "NIR_INTRINSIC_ALIGN_OFFSET"
 # The vulkan descriptor type for vulkan_resource_index
 DESC_TYPE = "NIR_INTRINSIC_DESC_TYPE"
-# The nir_alu_type of input data to a store
+# The nir_alu_type of input data to a store or conversion
 SRC_TYPE = "NIR_INTRINSIC_SRC_TYPE"
-# The nir_alu_type of the data output from a load
+# The nir_alu_type of the data output from a load or conversion
 DEST_TYPE = "NIR_INTRINSIC_DEST_TYPE"
 # The swizzle mask for quad_swizzle_amd & masked_swizzle_amd
 SWIZZLE_MASK = "NIR_INTRINSIC_SWIZZLE_MASK"
@@ -141,6 +141,10 @@ MEMORY_SCOPE = "NIR_INTRINSIC_MEMORY_SCOPE"
 # Scope of a control barrier
 EXECUTION_SCOPE = "NIR_INTRINSIC_EXECUTION_SCOPE"
 IO_SEMANTICS = "NIR_INTRINSIC_IO_SEMANTICS"
+# Rounding mode for conversions
+ROUNDING_MODE = "NIR_INTRINSIC_ROUNDING_MODE"
+# Whether or not to saturate in conversions
+SATURATE = "NIR_INTRINSIC_SATURATE"
 
 #
 # Possible flags:
@@ -170,6 +174,10 @@ def intrinsic(name, src_comp=[], dest_comp=-1, indices=[],
 
 intrinsic("nop", flags=[CAN_ELIMINATE])
 
+intrinsic("convert_alu_types", dest_comp=0, src_comp=[0],
+          indices=[SRC_TYPE, DEST_TYPE, ROUNDING_MODE, SATURATE],
+          flags=[CAN_ELIMINATE, CAN_REORDER])
+
 intrinsic("load_param", dest_comp=0, indices=[PARAM_IDX], 
flags=[CAN_ELIMINATE])
 
 intrinsic("load_deref", dest_comp=0, src_comp=[-1],
diff --git a/src/compiler/nir/nir_print.c b/src/compiler/nir/nir_print.c
index 7ff4ef5776e..bca020c5a4c 100644
--- a/src/compiler/nir/nir_print.c
+++ b/src/compiler/nir/nir_print.c
@@ -846,6 +846,8 @@ print_intrinsic_instr(nir_intrinsic_instr *instr, 
print_state *state)
       [NIR_INTRINSIC_MEMORY_SCOPE] = "mem_scope",
       [NIR_INTRINSIC_EXECUTION_SCOPE] = "exec_scope",
       [NIR_INTRINSIC_IO_SEMANTICS] = "io_semantics",
+      [NIR_INTRINSIC_ROUNDING_MODE] = "src_type",
+      [NIR_INTRINSIC_SATURATE] = "src_type",
    };
 
    for (unsigned idx = 1; idx < NIR_INTRINSIC_NUM_INDEX_FLAGS; idx++) {
@@ -1004,6 +1006,19 @@ print_intrinsic_instr(nir_intrinsic_instr *instr, 
print_state *state)
          }
          break;
 
+      case NIR_INTRINSIC_ROUNDING_MODE: {
+         fprintf(fp, " rounding_mode=");
+         switch (nir_intrinsic_rounding_mode(instr)) {
+         case nir_rounding_mode_undef: fprintf(fp, "undef");   break;
+         case nir_rounding_mode_rtne:  fprintf(fp, "rtne");    break;
+         case nir_rounding_mode_ru:    fprintf(fp, "ru");      break;
+         case nir_rounding_mode_rd:    fprintf(fp, "rd");      break;
+         case nir_rounding_mode_rtz:   fprintf(fp, "rtz");     break;
+         default:                      fprintf(fp, "unkown");  break;
+         }
+         break;
+      }
+
       default: {
          unsigned off = info->index_map[idx] - 1;
          assert(index_name[idx]);  /* forgot to update index_name table? */
diff --git a/src/compiler/nir/nir_validate.c b/src/compiler/nir/nir_validate.c
index 57f7e365158..706ddd2b5b9 100644
--- a/src/compiler/nir/nir_validate.c
+++ b/src/compiler/nir/nir_validate.c
@@ -546,6 +546,16 @@ validate_intrinsic_instr(nir_intrinsic_instr *instr, 
validate_state *state)
    unsigned dest_bit_size = 0;
    unsigned src_bit_sizes[NIR_INTRINSIC_MAX_INPUTS] = { 0, };
    switch (instr->intrinsic) {
+   case nir_intrinsic_convert_alu_types: {
+      nir_alu_type src_type = nir_intrinsic_src_type(instr);
+      nir_alu_type dest_type = nir_intrinsic_dest_type(instr);
+      dest_bit_size = nir_alu_type_get_type_size(dest_type);
+      src_bit_sizes[0] = nir_alu_type_get_type_size(src_type);
+      validate_assert(state, dest_bit_size != 0);
+      validate_assert(state, src_bit_sizes[0] != 0);
+      break;
+   }
+
    case nir_intrinsic_load_param: {
       unsigned param_idx = nir_intrinsic_param_idx(instr);
       validate_assert(state, param_idx < state->impl->function->num_params);

_______________________________________________
mesa-commit mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to