aboutsummaryrefslogtreecommitdiffstats
path: root/src/compiler/nir
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/nir')
-rw-r--r--src/compiler/nir/nir.c122
-rw-r--r--src/compiler/nir/nir_builder.h4
-rw-r--r--src/compiler/nir/nir_lower_double_ops.c4
-rw-r--r--src/compiler/nir/nir_lower_idiv.c16
-rw-r--r--src/compiler/nir/nir_lower_tex.c4
-rw-r--r--src/compiler/nir/nir_opcodes.py54
-rw-r--r--src/compiler/nir/nir_opcodes_c.py66
-rw-r--r--src/compiler/nir/nir_opt_algebraic.py40
8 files changed, 121 insertions, 189 deletions
diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c
index 37fd9cb5c56..937b6300624 100644
--- a/src/compiler/nir/nir.c
+++ b/src/compiler/nir/nir.c
@@ -1958,125 +1958,3 @@ nir_system_value_from_intrinsic(nir_intrinsic_op intrin)
unreachable("intrinsic doesn't produce a system value");
}
}
-
-nir_op
-nir_type_conversion_op(nir_alu_type src, nir_alu_type dst)
-{
- nir_alu_type src_base_type = (nir_alu_type) nir_alu_type_get_base_type(src);
- nir_alu_type dst_base_type = (nir_alu_type) nir_alu_type_get_base_type(dst);
- unsigned src_bitsize = nir_alu_type_get_type_size(src);
- unsigned dst_bitsize = nir_alu_type_get_type_size(dst);
-
- if (src_bitsize == dst_bitsize) {
- switch (src_base_type) {
- case nir_type_int:
- case nir_type_uint:
- if (dst_base_type == nir_type_uint || dst_base_type == nir_type_int)
- return nir_op_imov;
- break;
- case nir_type_float:
- if (dst_base_type == nir_type_float)
- return nir_op_fmov;
- break;
- case nir_type_bool:
- if (dst_base_type == nir_type_bool)
- return nir_op_imov;
- break;
- default:
- unreachable("Invalid conversion");
- }
- }
-
- switch (src_base_type) {
- case nir_type_int:
- switch (dst_base_type) {
- case nir_type_int:
- assert(src_bitsize != dst_bitsize);
- return (dst_bitsize == 32) ? nir_op_i2i32 : nir_op_i2i64;
- case nir_type_uint:
- assert(src_bitsize != dst_bitsize);
- return (dst_bitsize == 32) ? nir_op_i2u32 : nir_op_i2u64;
- case nir_type_float:
- switch (src_bitsize) {
- case 32:
- return (dst_bitsize == 32) ? nir_op_i2f : nir_op_i2d;
- case 64:
- return (dst_bitsize == 32) ? nir_op_i642f : nir_op_i642d;
- default:
- unreachable("Invalid conversion");
- }
- case nir_type_bool:
- return (src_bitsize == 32) ? nir_op_i2b : nir_op_i642b;
- default:
- unreachable("Invalid conversion");
- }
-
- case nir_type_uint:
- switch (dst_base_type) {
- case nir_type_int:
- assert(src_bitsize != dst_bitsize);
- return (dst_bitsize == 32) ? nir_op_u2i32 : nir_op_u2i64;
- case nir_type_uint:
- assert(src_bitsize != dst_bitsize);
- return (dst_bitsize == 32) ? nir_op_u2u32 : nir_op_u2u64;
- case nir_type_float:
- switch (src_bitsize) {
- case 32:
- return (dst_bitsize == 32) ? nir_op_u2f : nir_op_u2d;
- case 64:
- return (dst_bitsize == 32) ? nir_op_u642f : nir_op_u642d;
- default:
- unreachable("Invalid conversion");
- }
- case nir_type_bool:
- return (src_bitsize == 32) ? nir_op_i2b : nir_op_i642b;
- default:
- unreachable("Invalid conversion");
- }
-
- case nir_type_float:
- switch (dst_base_type) {
- case nir_type_int:
- switch (src_bitsize) {
- case 32:
- return (dst_bitsize == 32) ? nir_op_f2i : nir_op_f2i64;
- case 64:
- return (dst_bitsize == 32) ? nir_op_d2i : nir_op_f2i64;
- default:
- unreachable("Invalid conversion");
- }
- case nir_type_uint:
- switch (src_bitsize) {
- case 32:
- return (dst_bitsize == 32) ? nir_op_f2u : nir_op_f2u64;
- case 64:
- return (dst_bitsize == 32) ? nir_op_d2u : nir_op_f2u64;
- default:
- unreachable("Invalid conversion");
- }
- case nir_type_float:
- assert(src_bitsize != dst_bitsize);
- return (dst_bitsize == 32) ? nir_op_d2f : nir_op_f2d;
- case nir_type_bool:
- return (src_bitsize == 32) ? nir_op_f2b : nir_op_d2b;
- default:
- unreachable("Invalid conversion");
- }
-
- case nir_type_bool:
- switch (dst_base_type) {
- case nir_type_int:
- case nir_type_uint:
- return (dst_bitsize == 32) ? nir_op_b2i : nir_op_b2i64;
- case nir_type_float:
- /* GLSL just emits f2d(b2f(x)) for b2d */
- assert(dst_bitsize == 32);
- return nir_op_b2f;
- default:
- unreachable("Invalid conversion");
- }
-
- default:
- unreachable("Invalid conversion");
- }
-}
diff --git a/src/compiler/nir/nir_builder.h b/src/compiler/nir/nir_builder.h
index 1dc56ebf53d..a4f15b6d335 100644
--- a/src/compiler/nir/nir_builder.h
+++ b/src/compiler/nir/nir_builder.h
@@ -328,6 +328,10 @@ nir_build_alu(nir_builder *build, nir_op op, nir_ssa_def *src0,
}
}
+ /* When in doubt, assume 32. */
+ if (bit_size == 0)
+ bit_size = 32;
+
/* Make sure we don't swizzle from outside of our source vector (like if a
* scalar value was passed into a multiply with a vector).
*/
diff --git a/src/compiler/nir/nir_lower_double_ops.c b/src/compiler/nir/nir_lower_double_ops.c
index ad9631327b4..00eeb89b1bd 100644
--- a/src/compiler/nir/nir_lower_double_ops.c
+++ b/src/compiler/nir/nir_lower_double_ops.c
@@ -116,7 +116,7 @@ lower_rcp(nir_builder *b, nir_ssa_def *src)
/* cast to float, do an rcp, and then cast back to get an approximate
* result
*/
- nir_ssa_def *ra = nir_f2d(b, nir_frcp(b, nir_d2f(b, src_norm)));
+ nir_ssa_def *ra = nir_f2f64(b, nir_frcp(b, nir_f2f32(b, src_norm)));
/* Fixup the exponent of the result - note that we check if this is too
* small below.
@@ -180,7 +180,7 @@ lower_sqrt_rsq(nir_builder *b, nir_ssa_def *src, bool sqrt)
nir_iadd(b, nir_imm_int(b, 1023),
even));
- nir_ssa_def *ra = nir_f2d(b, nir_frsq(b, nir_d2f(b, src_norm)));
+ nir_ssa_def *ra = nir_f2f64(b, nir_frsq(b, nir_f2f32(b, src_norm)));
nir_ssa_def *new_exp = nir_isub(b, get_exponent(b, ra), half);
ra = set_exponent(b, ra, new_exp);
diff --git a/src/compiler/nir/nir_lower_idiv.c b/src/compiler/nir/nir_lower_idiv.c
index 6726b718aaa..194ca5a75a8 100644
--- a/src/compiler/nir/nir_lower_idiv.c
+++ b/src/compiler/nir/nir_lower_idiv.c
@@ -56,15 +56,15 @@ convert_instr(nir_builder *bld, nir_alu_instr *alu)
denom = nir_ssa_for_alu_src(bld, alu, 1);
if (is_signed) {
- af = nir_i2f(bld, numer);
- bf = nir_i2f(bld, denom);
+ af = nir_i2f32(bld, numer);
+ bf = nir_i2f32(bld, denom);
af = nir_fabs(bld, af);
bf = nir_fabs(bld, bf);
a = nir_iabs(bld, numer);
b = nir_iabs(bld, denom);
} else {
- af = nir_u2f(bld, numer);
- bf = nir_u2f(bld, denom);
+ af = nir_u2f32(bld, numer);
+ bf = nir_u2f32(bld, denom);
a = numer;
b = denom;
}
@@ -75,17 +75,17 @@ convert_instr(nir_builder *bld, nir_alu_instr *alu)
q = nir_fmul(bld, af, bf);
if (is_signed) {
- q = nir_f2i(bld, q);
+ q = nir_f2i32(bld, q);
} else {
- q = nir_f2u(bld, q);
+ q = nir_f2u32(bld, q);
}
/* get error of first result: */
r = nir_imul(bld, q, b);
r = nir_isub(bld, a, r);
- r = nir_u2f(bld, r);
+ r = nir_u2f32(bld, r);
r = nir_fmul(bld, r, bf);
- r = nir_f2u(bld, r);
+ r = nir_f2u32(bld, r);
/* add quotients: */
q = nir_iadd(bld, q, r);
diff --git a/src/compiler/nir/nir_lower_tex.c b/src/compiler/nir/nir_lower_tex.c
index 213406aaa98..70054679955 100644
--- a/src/compiler/nir/nir_lower_tex.c
+++ b/src/compiler/nir/nir_lower_tex.c
@@ -121,7 +121,7 @@ lower_offset(nir_builder *b, nir_tex_instr *tex)
nir_ssa_def *offset_coord;
if (nir_tex_instr_src_type(tex, coord_index) == nir_type_float) {
assert(tex->sampler_dim == GLSL_SAMPLER_DIM_RECT);
- offset_coord = nir_fadd(b, coord, nir_i2f(b, offset));
+ offset_coord = nir_fadd(b, coord, nir_i2f32(b, offset));
} else {
offset_coord = nir_iadd(b, coord, offset);
}
@@ -176,7 +176,7 @@ get_texture_size(nir_builder *b, nir_tex_instr *tex)
nir_tex_instr_dest_size(txs), 32, NULL);
nir_builder_instr_insert(b, &txs->instr);
- return nir_i2f(b, &txs->dest.ssa);
+ return nir_i2f32(b, &txs->dest.ssa);
}
static void
diff --git a/src/compiler/nir/nir_opcodes.py b/src/compiler/nir/nir_opcodes.py
index 8cad74832a6..52868d5f5a4 100644
--- a/src/compiler/nir/nir_opcodes.py
+++ b/src/compiler/nir/nir_opcodes.py
@@ -165,42 +165,26 @@ unop("frsq", tfloat, "bit_size == 64 ? 1.0 / sqrt(src0) : 1.0f / sqrtf(src0)")
unop("fsqrt", tfloat, "bit_size == 64 ? sqrt(src0) : sqrtf(src0)")
unop("fexp2", tfloat, "exp2f(src0)")
unop("flog2", tfloat, "log2f(src0)")
-unop_convert("f2i", tint32, tfloat32, "src0") # Float-to-integer conversion.
-unop_convert("f2u", tuint32, tfloat32, "src0") # Float-to-unsigned conversion
-unop_convert("d2i", tint32, tfloat64, "src0") # Double-to-integer conversion.
-unop_convert("d2u", tuint32, tfloat64, "src0") # Double-to-unsigned conversion.
-unop_convert("i2f", tfloat32, tint32, "src0") # Integer-to-float conversion.
-unop_convert("i2d", tfloat64, tint32, "src0") # Integer-to-double conversion.
-unop_convert("i2i32", tint32, tint, "src0") # General int (int8_t, int64_t, etc.) to int32_t conversion
-unop_convert("u2i32", tint32, tuint, "src0") # General uint (uint8_t, uint64_t, etc.) to int32_t conversion
-unop_convert("i2u32", tuint32, tint, "src0") # General int (int8_t, int64_t, etc.) to uint32_t conversion
-unop_convert("u2u32", tuint32, tuint, "src0") # General uint (uint8_t, uint64_t, etc.) to uint32_t conversion
-unop_convert("i2i64", tint64, tint, "src0") # General int (int8_t, int32_t, etc.) to int64_t conversion
-unop_convert("u2i64", tint64, tuint, "src0") # General uint (uint8_t, uint64_t, etc.) to int64_t conversion
-unop_convert("f2i64", tint64, tfloat, "src0") # General float (float or double) to int64_t conversion
-unop_convert("i2u64", tuint64, tint, "src0") # General int (int8_t, int64_t, etc.) to uint64_t conversion
-unop_convert("u2u64", tuint64, tuint, "src0") # General uint (uint8_t, uint32_t, etc.) to uint64_t conversion
-unop_convert("f2u64", tuint64, tfloat, "src0") # General float (float or double) to uint64_t conversion
-unop_convert("i642f", tfloat32, tint64, "src0") # int64_t-to-float conversion.
-unop_convert("i642b", tbool, tint64, "src0") # int64_t-to-bool conversion.
-unop_convert("i642d", tfloat64, tint64, "src0") # int64_t-to-double conversion.
-unop_convert("u642f", tfloat32, tuint64, "src0") # uint64_t-to-float conversion.
-unop_convert("u642d", tfloat64, tuint64, "src0") # uint64_t-to-double conversion.
-
-# Float-to-boolean conversion
-unop_convert("f2b", tbool, tfloat32, "src0 != 0.0f")
-unop_convert("d2b", tbool, tfloat64, "src0 != 0.0")
-# Boolean-to-float conversion
-unop_convert("b2f", tfloat32, tbool, "src0 ? 1.0f : 0.0f")
-# Int-to-boolean conversion
+
+# Generate all of the numeric conversion opcodes
+for src_t in [tint, tuint, tfloat]:
+ if src_t in (tint, tuint):
+ dst_types = [tfloat, src_t]
+ elif src_t == tfloat:
+ dst_types = [tint, tuint, tfloat]
+
+ for dst_t in dst_types:
+ for bit_size in [32, 64]:
+ unop_convert("{}2{}{}".format(src_t[0], dst_t[0], bit_size),
+ dst_t + str(bit_size), src_t, "src0")
+
+# We'll hand-code the to/from bool conversion opcodes. Because bool doesn't
+# have multiple bit-sizes, we can always infer the size from the other type.
+unop_convert("f2b", tbool, tfloat, "src0 != 0.0")
unop_convert("i2b", tbool, tint, "src0 != 0")
-unop_convert("b2i", tint32, tbool, "src0 ? 1 : 0") # Boolean-to-int conversion
-unop_convert("b2i64", tint64, tbool, "src0 ? 1 : 0") # Boolean-to-int64_t conversion.
-unop_convert("u2f", tfloat32, tuint32, "src0") # Unsigned-to-float conversion.
-unop_convert("u2d", tfloat64, tuint32, "src0") # Unsigned-to-double conversion.
-# double-to-float conversion
-unop_convert("d2f", tfloat32, tfloat64, "src0") # Double to single precision
-unop_convert("f2d", tfloat64, tfloat32, "src0") # Single to double precision
+unop_convert("b2f", tfloat, tbool, "src0 ? 1.0 : 0.0")
+unop_convert("b2i", tint, tbool, "src0 ? 1 : 0")
+
# Unary floating-point rounding operations.
diff --git a/src/compiler/nir/nir_opcodes_c.py b/src/compiler/nir/nir_opcodes_c.py
index 5f8bdc12a07..c66f3bc7ad4 100644
--- a/src/compiler/nir/nir_opcodes_c.py
+++ b/src/compiler/nir/nir_opcodes_c.py
@@ -29,6 +29,72 @@ from mako.template import Template
template = Template("""
#include "nir.h"
+nir_op
+nir_type_conversion_op(nir_alu_type src, nir_alu_type dst)
+{
+ nir_alu_type src_base = (nir_alu_type) nir_alu_type_get_base_type(src);
+ nir_alu_type dst_base = (nir_alu_type) nir_alu_type_get_base_type(dst);
+ unsigned src_bit_size = nir_alu_type_get_type_size(src);
+ unsigned dst_bit_size = nir_alu_type_get_type_size(dst);
+
+ if (src == dst && src_base == nir_type_float) {
+ return nir_op_fmov;
+ } else if ((src_base == nir_type_int || src_base == nir_type_uint) &&
+ (dst_base == nir_type_int || dst_base == nir_type_uint) &&
+ src_bit_size == dst_bit_size) {
+ /* Integer <-> integer conversions with the same bit-size on both
+ * ends are just no-op moves.
+ */
+ return nir_op_imov;
+ }
+
+ switch (src_base) {
+% for src_t in ['int', 'uint', 'float']:
+ case nir_type_${src_t}:
+ switch (dst_base) {
+% for dst_t in ['int', 'uint', 'float']:
+ case nir_type_${dst_t}:
+% if src_t in ['int', 'uint'] and dst_t in ['int', 'uint']:
+% if dst_t == 'int':
+<% continue %>
+% else:
+<% dst_t = src_t %>
+% endif
+% endif
+ switch (dst_bit_size) {
+% for dst_bits in [32, 64]:
+ case ${dst_bits}:
+ return ${'nir_op_{}2{}{}'.format(src_t[0], dst_t[0], dst_bits)};
+% endfor
+ default:
+ unreachable("Invalid nir alu bit size");
+ }
+% endfor
+ case nir_type_bool:
+% if src_t == 'float':
+ return nir_op_f2b;
+% else:
+ return nir_op_i2b;
+% endif
+ default:
+ unreachable("Invalid nir alu base type");
+ }
+% endfor
+ case nir_type_bool:
+ switch (dst_base) {
+ case nir_type_int:
+ case nir_type_uint:
+ return nir_op_b2i;
+ case nir_type_float:
+ return nir_op_b2f;
+ default:
+ unreachable("Invalid nir alu base type");
+ }
+ default:
+ unreachable("Invalid nir alu base type");
+ }
+}
+
const nir_op_info nir_op_infos[nir_num_opcodes] = {
% for name, opcode in sorted(opcodes.iteritems()):
{
diff --git a/src/compiler/nir/nir_opt_algebraic.py b/src/compiler/nir/nir_opt_algebraic.py
index f60c338b624..49c1460e25a 100644
--- a/src/compiler/nir/nir_opt_algebraic.py
+++ b/src/compiler/nir/nir_opt_algebraic.py
@@ -78,7 +78,7 @@ optimizations = [
(('ineg', ('ineg', a)), a),
(('fabs', ('fabs', a)), ('fabs', a)),
(('fabs', ('fneg', a)), ('fabs', a)),
- (('fabs', ('u2f', a)), ('u2f', a)),
+ (('fabs', ('u2f32', a)), ('u2f32', a)),
(('iabs', ('iabs', a)), ('iabs', a)),
(('iabs', ('ineg', a)), ('iabs', a)),
(('~fadd', a, 0.0), a),
@@ -212,7 +212,7 @@ optimizations = [
(('fsat', ('fadd', ('b2f', a), ('b2f', b))), ('b2f', ('ior', a, b))),
(('iand', 'a@bool', 1.0), ('b2f', a)),
# True/False are ~0 and 0 in NIR. b2i of True is 1, and -1 is ~0 (True).
- (('ineg', ('b2i', a)), a),
+ (('ineg', ('b2i@32', a)), a),
(('flt', ('fneg', ('b2f', a)), 0), a), # Generated by TGSI KILL_IF.
(('flt', ('fsub', 0.0, ('b2f', a)), 0), a), # Generated by TGSI KILL_IF.
# Comparison with the same args. Note that these are not done for
@@ -298,8 +298,8 @@ optimizations = [
# Conversions
(('i2b', ('b2i', a)), a),
- (('f2i', ('ftrunc', a)), ('f2i', a)),
- (('f2u', ('ftrunc', a)), ('f2u', a)),
+ (('f2i32', ('ftrunc', a)), ('f2i32', a)),
+ (('f2u32', ('ftrunc', a)), ('f2u32', a)),
(('i2b', ('ineg', a)), ('i2b', a)),
(('i2b', ('iabs', a)), ('i2b', a)),
(('fabs', ('b2f', a)), ('b2f', a)),
@@ -387,49 +387,49 @@ optimizations = [
(('pack_unorm_2x16', 'v'),
('pack_uvec2_to_uint',
- ('f2u', ('fround_even', ('fmul', ('fsat', 'v'), 65535.0)))),
+ ('f2u32', ('fround_even', ('fmul', ('fsat', 'v'), 65535.0)))),
'options->lower_pack_unorm_2x16'),
(('pack_unorm_4x8', 'v'),
('pack_uvec4_to_uint',
- ('f2u', ('fround_even', ('fmul', ('fsat', 'v'), 255.0)))),
+ ('f2u32', ('fround_even', ('fmul', ('fsat', 'v'), 255.0)))),
'options->lower_pack_unorm_4x8'),
(('pack_snorm_2x16', 'v'),
('pack_uvec2_to_uint',
- ('f2i', ('fround_even', ('fmul', ('fmin', 1.0, ('fmax', -1.0, 'v')), 32767.0)))),
+ ('f2i32', ('fround_even', ('fmul', ('fmin', 1.0, ('fmax', -1.0, 'v')), 32767.0)))),
'options->lower_pack_snorm_2x16'),
(('pack_snorm_4x8', 'v'),
('pack_uvec4_to_uint',
- ('f2i', ('fround_even', ('fmul', ('fmin', 1.0, ('fmax', -1.0, 'v')), 127.0)))),
+ ('f2i32', ('fround_even', ('fmul', ('fmin', 1.0, ('fmax', -1.0, 'v')), 127.0)))),
'options->lower_pack_snorm_4x8'),
(('unpack_unorm_2x16', 'v'),
- ('fdiv', ('u2f', ('vec2', ('extract_u16', 'v', 0),
- ('extract_u16', 'v', 1))),
+ ('fdiv', ('u2f32', ('vec2', ('extract_u16', 'v', 0),
+ ('extract_u16', 'v', 1))),
65535.0),
'options->lower_unpack_unorm_2x16'),
(('unpack_unorm_4x8', 'v'),
- ('fdiv', ('u2f', ('vec4', ('extract_u8', 'v', 0),
- ('extract_u8', 'v', 1),
- ('extract_u8', 'v', 2),
- ('extract_u8', 'v', 3))),
+ ('fdiv', ('u2f32', ('vec4', ('extract_u8', 'v', 0),
+ ('extract_u8', 'v', 1),
+ ('extract_u8', 'v', 2),
+ ('extract_u8', 'v', 3))),
255.0),
'options->lower_unpack_unorm_4x8'),
(('unpack_snorm_2x16', 'v'),
- ('fmin', 1.0, ('fmax', -1.0, ('fdiv', ('i2f', ('vec2', ('extract_i16', 'v', 0),
- ('extract_i16', 'v', 1))),
+ ('fmin', 1.0, ('fmax', -1.0, ('fdiv', ('i2f32', ('vec2', ('extract_i16', 'v', 0),
+ ('extract_i16', 'v', 1))),
32767.0))),
'options->lower_unpack_snorm_2x16'),
(('unpack_snorm_4x8', 'v'),
- ('fmin', 1.0, ('fmax', -1.0, ('fdiv', ('i2f', ('vec4', ('extract_i8', 'v', 0),
- ('extract_i8', 'v', 1),
- ('extract_i8', 'v', 2),
- ('extract_i8', 'v', 3))),
+ ('fmin', 1.0, ('fmax', -1.0, ('fdiv', ('i2f32', ('vec4', ('extract_i8', 'v', 0),
+ ('extract_i8', 'v', 1),
+ ('extract_i8', 'v', 2),
+ ('extract_i8', 'v', 3))),
127.0))),
'options->lower_unpack_snorm_4x8'),
]