nir: add legal bit_sizes to intrinsics
authorKarol Herbst <kherbst@redhat.com>
Thu, 19 Jul 2018 11:04:43 +0000 (13:04 +0200)
committerKarol Herbst <kherbst@redhat.com>
Sun, 20 Jan 2019 23:16:51 +0000 (00:16 +0100)
With OpenCL some system values match the address bits, but in GLSL we also
have some system values being 64 bit like subgroup masks.

With this it is possible to adjust the builder functions so that depending
on the bit_sizes the correct bit_size is used or an additional argument is
added in case of multiple possible values.

v2: validate dest bit_size
v3: generate hex values in python code
    remove useless imports
    rename and move bit_sizes
v4: add 1 to legal bit_sizes for front_face

Signed-off-by: Karol Herbst <kherbst@redhat.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
src/compiler/nir/nir.h
src/compiler/nir/nir_intrinsics.py
src/compiler/nir/nir_intrinsics_c.py
src/compiler/nir/nir_validate.c

index 3e36043205142cca214353f28ce5f615e89cd57d..b805e2900943164913ccbb02e65975410ad9ead9 100644 (file)
@@ -1313,6 +1313,9 @@ typedef struct {
     */
    unsigned dest_components;
 
+   /** bitfield of legal bit sizes */
+   unsigned dest_bit_sizes;
+
    /** the number of constant indices used by the intrinsic */
    unsigned num_indices;
 
index 2d89f8861aeba8dd514b7fb03f8eb9c0d3f9ea0f..a5cc3f7401cea6d99101c887b1b6cb27ad315e91 100644 (file)
@@ -32,7 +32,7 @@ class Intrinsic(object):
    NOTE: this must be kept in sync with nir_intrinsic_info.
    """
    def __init__(self, name, src_components, dest_components,
-                indices, flags, sysval):
+                indices, flags, sysval, bit_sizes):
        """Parameters:
 
        - name: the intrinsic name
@@ -45,6 +45,7 @@ class Intrinsic(object):
        - indices: list of constant indicies
        - flags: list of semantic flags
        - sysval: is this a system-value intrinsic
+       - bit_sizes: allowed dest bit_sizes
        """
        assert isinstance(name, str)
        assert isinstance(src_components, list)
@@ -58,6 +59,8 @@ class Intrinsic(object):
        if flags:
            assert isinstance(flags[0], str)
        assert isinstance(sysval, bool)
+       if bit_sizes:
+           assert isinstance(bit_sizes[0], int)
 
        self.name = name
        self.num_srcs = len(src_components)
@@ -68,6 +71,7 @@ class Intrinsic(object):
        self.indices = indices
        self.flags = flags
        self.sysval = sysval
+       self.bit_sizes = bit_sizes
 
 #
 # Possible indices:
@@ -125,10 +129,10 @@ CAN_REORDER   = "NIR_INTRINSIC_CAN_REORDER"
 INTR_OPCODES = {}
 
 def intrinsic(name, src_comp=[], dest_comp=-1, indices=[],
-              flags=[], sysval=False):
+              flags=[], sysval=False, bit_sizes=[]):
     assert name not in INTR_OPCODES
     INTR_OPCODES[name] = Intrinsic(name, src_comp, dest_comp,
-                                   indices, flags, sysval)
+                                   indices, flags, sysval, bit_sizes)
 
 intrinsic("nop", flags=[CAN_ELIMINATE])
 
@@ -454,12 +458,13 @@ intrinsic("shared_atomic_fmin",  src_comp=[1, 1], dest_comp=1, indices=[BASE])
 intrinsic("shared_atomic_fmax",  src_comp=[1, 1], dest_comp=1, indices=[BASE])
 intrinsic("shared_atomic_fcomp_swap", src_comp=[1, 1, 1], dest_comp=1, indices=[BASE])
 
-def system_value(name, dest_comp, indices=[]):
+def system_value(name, dest_comp, indices=[], bit_sizes=[32]):
     intrinsic("load_" + name, [], dest_comp, indices,
-              flags=[CAN_ELIMINATE, CAN_REORDER], sysval=True)
+              flags=[CAN_ELIMINATE, CAN_REORDER], sysval=True,
+              bit_sizes=bit_sizes)
 
 system_value("frag_coord", 4)
-system_value("front_face", 1)
+system_value("front_face", 1, bit_sizes=[1, 32])
 system_value("vertex_id", 1)
 system_value("vertex_id_zero_base", 1)
 system_value("first_vertex", 1)
@@ -485,17 +490,17 @@ system_value("local_invocation_index", 1)
 system_value("work_group_id", 3)
 system_value("user_clip_plane", 4, indices=[UCP_ID])
 system_value("num_work_groups", 3)
-system_value("helper_invocation", 1)
+system_value("helper_invocation", 1, bit_sizes=[1, 32])
 system_value("alpha_ref_float", 1)
 system_value("layer_id", 1)
 system_value("view_index", 1)
 system_value("subgroup_size", 1)
 system_value("subgroup_invocation", 1)
-system_value("subgroup_eq_mask", 0)
-system_value("subgroup_ge_mask", 0)
-system_value("subgroup_gt_mask", 0)
-system_value("subgroup_le_mask", 0)
-system_value("subgroup_lt_mask", 0)
+system_value("subgroup_eq_mask", 0, bit_sizes=[32, 64])
+system_value("subgroup_ge_mask", 0, bit_sizes=[32, 64])
+system_value("subgroup_gt_mask", 0, bit_sizes=[32, 64])
+system_value("subgroup_le_mask", 0, bit_sizes=[32, 64])
+system_value("subgroup_lt_mask", 0, bit_sizes=[32, 64])
 system_value("num_subgroups", 1)
 system_value("subgroup_id", 1)
 system_value("local_group_size", 3)
index ac45b94d4968db2bdd1538fedb8676a93c75bb19..3043ffe93d13d55ea7a4df7f9f6e784728e32ba8 100644 (file)
@@ -1,3 +1,5 @@
+from functools import reduce
+import operator
 
 template = """\
 /* Copyright (C) 2018 Red Hat
@@ -36,6 +38,7 @@ const nir_intrinsic_info nir_intrinsic_infos[nir_num_intrinsics] = {
 % endif
    .has_dest = ${"true" if opcode.has_dest else "false"},
    .dest_components = ${max(opcode.dest_components, 0)},
+   .dest_bit_sizes = ${hex(reduce(operator.or_, opcode.bit_sizes, 0))},
    .num_indices = ${opcode.num_indices},
 % if opcode.indices:
    .index_map = {
@@ -64,7 +67,7 @@ def main():
 
     path = os.path.join(args.outdir, 'nir_intrinsics.c')
     with open(path, 'wb') as f:
-        f.write(Template(template, output_encoding='utf-8').render(INTR_OPCODES=INTR_OPCODES))
+        f.write(Template(template, output_encoding='utf-8').render(INTR_OPCODES=INTR_OPCODES, reduce=reduce, operator=operator))
 
 if __name__ == '__main__':
     main()
index 44aaa9161dbfdb0b5f035cb20a27f7dbe3541790..444c0b789af21e7f41f00f059a316d439ef50c99 100644 (file)
@@ -563,9 +563,15 @@ validate_intrinsic_instr(nir_intrinsic_instr *instr, validate_state *state)
 
    if (nir_intrinsic_infos[instr->intrinsic].has_dest) {
       unsigned components_written = nir_intrinsic_dest_components(instr);
+      unsigned bit_sizes = nir_intrinsic_infos[instr->intrinsic].dest_bit_sizes;
 
       validate_assert(state, components_written > 0);
 
+      if (dest_bit_size && bit_sizes)
+         validate_assert(state, dest_bit_size & bit_sizes);
+      else
+         dest_bit_size = dest_bit_size ? dest_bit_size : bit_sizes;
+
       validate_dest(&instr->dest, state, dest_bit_size, components_written);
    }
 }