[Mesa-dev] [counter-RFC 3/3] nir: Add a bit_size to nir_register and nir_ssa_def

Jason Ekstrand jason at jlekstrand.net
Fri May 15 10:26:49 PDT 2015


This really hacky commit adds a bit size to registers and SSA values.  It
also adds rules in the validator to validate that they do the right things.

It's still an open question as to whether or not we want a bit_size in
nir_alu_instr or if we just want to let it inherit from the destination.
I'm inclined to just let it inherit from the destination.  A similar
question needs to be asked about intrinsics.
---
 src/glsl/nir/nir.c          |  2 ++
 src/glsl/nir/nir.h          |  6 ++++++
 src/glsl/nir/nir_validate.c | 43 +++++++++++++++++++++++++++++++++++++++----
 3 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/src/glsl/nir/nir.c b/src/glsl/nir/nir.c
index f03e80a..7df0d37 100644
--- a/src/glsl/nir/nir.c
+++ b/src/glsl/nir/nir.c
@@ -63,6 +63,7 @@ reg_create(void *mem_ctx, struct exec_list *list)
    list_inithead(&reg->if_uses);
 
    reg->num_components = 0;
+   reg->bit_size = 32;
    reg->num_array_elems = 0;
    reg->is_packed = false;
    reg->name = NULL;
@@ -1895,6 +1896,7 @@ nir_ssa_def_init(nir_instr *instr, nir_ssa_def *def,
    list_inithead(&def->uses);
    list_inithead(&def->if_uses);
    def->num_components = num_components;
+   def->bit_size = 32; /* FIXME: Add an input paremeter or guess? */
 
    if (instr->block) {
       nir_function_impl *impl =
diff --git a/src/glsl/nir/nir.h b/src/glsl/nir/nir.h
index 8dfc68d..42b12ec 100644
--- a/src/glsl/nir/nir.h
+++ b/src/glsl/nir/nir.h
@@ -369,6 +369,9 @@ typedef struct {
    unsigned num_components; /** < number of vector components */
    unsigned num_array_elems; /** < size of array (0 for no array) */
 
+   /* The bit-size of each channel; must be one of 8, 16, 32, or 64 */
+   uint8_t bit_size;
+
    /** generic register index. */
    unsigned index;
 
@@ -469,6 +472,9 @@ typedef struct {
    struct list_head if_uses;
 
    uint8_t num_components;
+
+   /* The bit-size of each channel; must be one of 8, 16, 32, or 64 */
+   uint8_t bit_size;
 } nir_ssa_def;
 
 struct nir_src;
diff --git a/src/glsl/nir/nir_validate.c b/src/glsl/nir/nir_validate.c
index da92ed9..6d9cfea 100644
--- a/src/glsl/nir/nir_validate.c
+++ b/src/glsl/nir/nir_validate.c
@@ -176,9 +176,12 @@ validate_alu_src(nir_alu_instr *instr, unsigned index, validate_state *state)
    nir_alu_src *src = &instr->src[index];
 
    unsigned num_components;
-   if (src->src.is_ssa)
+   unsigned src_bit_size;
+   if (src->src.is_ssa) {
+      src_bit_size = src->src.ssa->bit_size;
       num_components = src->src.ssa->num_components;
-   else {
+   } else {
+      src_bit_size = src->src.reg.reg->bit_size;
       if (src->src.reg.reg->is_packed)
          num_components = 4; /* can't check anything */
       else
@@ -191,6 +194,25 @@ validate_alu_src(nir_alu_instr *instr, unsigned index, validate_state *state)
          assert(src->swizzle[i] < num_components);
    }
 
+   nir_alu_type src_type = nir_op_infos[instr->op].input_types[index];
+
+   /* 8-bit float isn't a thing */
+   if ((src_type & NIR_ALU_TYPE_BASE_TYPE_MASK) == nir_type_float)
+      assert(src_bit_size == 16 || src_bit_size == 32 || src_bit_size == 64);
+
+   if (src_type & NIR_ALU_TYPE_SIZE_MASK) {
+      /* This source has an explicit bit size */
+      assert((src_type & NIR_ALU_TYPE_SIZE_MASK) == src_bit_size);
+   } else {
+      /* The output being explicitly sized would be silly */
+      assert(!(nir_op_infos[instr->op].output_type & NIR_ALU_TYPE_SIZE_MASK));
+
+      unsigned dest_bit_size =
+         instr->dest.dest.is_ssa ? instr->dest.dest.ssa.bit_size
+                                 : instr->dest.dest.reg.reg->bit_size;
+      assert(dest_bit_size == src_bit_size);
+   }
+
    validate_src(&src->src, state);
 }
 
@@ -260,8 +282,10 @@ validate_dest(nir_dest *dest, validate_state *state)
 }
 
 static void
-validate_alu_dest(nir_alu_dest *dest, validate_state *state)
+validate_alu_dest(nir_alu_instr *instr, validate_state *state)
 {
+   nir_alu_dest *dest = &instr->dest;
+
    unsigned dest_size =
       dest->dest.is_ssa ? dest->dest.ssa.num_components
                         : dest->dest.reg.reg->num_components;
@@ -279,6 +303,17 @@ validate_alu_dest(nir_alu_dest *dest, validate_state *state)
    assert(nir_op_infos[alu->op].output_type == nir_type_float ||
           !dest->saturate);
 
+   unsigned bit_size = dest->dest.is_ssa ? dest->dest.ssa.bit_size
+                                         : dest->dest.reg.reg->bit_size;
+   nir_alu_type type = nir_op_infos[instr->op].output_type;
+
+   /* 8-bit float isn't a thing */
+   if ((type & NIR_ALU_TYPE_BASE_TYPE_MASK) == nir_type_float)
+      assert(bit_size == 16 || bit_size == 32 || bit_size == 64);
+
+   assert((type & NIR_ALU_TYPE_SIZE_MASK) == 0 ||
+          (type & NIR_ALU_TYPE_SIZE_MASK) == bit_size);
+
    validate_dest(&dest->dest, state);
 }
 
@@ -287,7 +322,7 @@ validate_alu_instr(nir_alu_instr *instr, validate_state *state)
 {
    assert(instr->op < nir_num_opcodes);
 
-   validate_alu_dest(&instr->dest, state);
+   validate_alu_dest(instr, state);
 
    for (unsigned i = 0; i < nir_op_infos[instr->op].num_inputs; i++) {
       validate_alu_src(instr, i, state);
-- 
2.4.0



More information about the mesa-dev mailing list