diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 3e360432051..b805e290094 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -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; diff --git a/src/compiler/nir/nir_intrinsics.py b/src/compiler/nir/nir_intrinsics.py index 2d89f8861ae..a5cc3f7401c 100644 --- a/src/compiler/nir/nir_intrinsics.py +++ b/src/compiler/nir/nir_intrinsics.py @@ -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) diff --git a/src/compiler/nir/nir_intrinsics_c.py b/src/compiler/nir/nir_intrinsics_c.py index ac45b94d496..3043ffe93d1 100644 --- a/src/compiler/nir/nir_intrinsics_c.py +++ b/src/compiler/nir/nir_intrinsics_c.py @@ -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() diff --git a/src/compiler/nir/nir_validate.c b/src/compiler/nir/nir_validate.c index 44aaa9161db..444c0b789af 100644 --- a/src/compiler/nir/nir_validate.c +++ b/src/compiler/nir/nir_validate.c @@ -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); } }