Merge remote-tracking branch 'mattst88/nir-lower-pack-unpack' into vulkan

This commit is contained in:
Jason Ekstrand
2016-01-25 15:50:31 -08:00
145 changed files with 2306 additions and 1271 deletions
-9
View File
@@ -1442,12 +1442,6 @@ nir_visitor::visit(ir_expression *ir)
case ir_unop_unpack_half_2x16:
result = nir_unpack_half_2x16(&b, srcs[0]);
break;
case ir_unop_unpack_half_2x16_split_x:
result = nir_unpack_half_2x16_split_x(&b, srcs[0]);
break;
case ir_unop_unpack_half_2x16_split_y:
result = nir_unpack_half_2x16_split_y(&b, srcs[0]);
break;
case ir_unop_bitfield_reverse:
result = nir_bitfield_reverse(&b, srcs[0]);
break;
@@ -1731,9 +1725,6 @@ nir_visitor::visit(ir_expression *ir)
}
break;
case ir_binop_pack_half_2x16_split:
result = nir_pack_half_2x16_split(&b, srcs[0], srcs[1]);
break;
case ir_binop_ldexp: result = nir_ldexp(&b, srcs[0], srcs[1]); break;
case ir_triop_fma:
result = nir_ffma(&b, srcs[0], srcs[1], srcs[2]);
+17 -3
View File
@@ -140,7 +140,7 @@ typedef enum {
* ir_variable - it should be easy to translate between the two.
*/
typedef struct {
typedef struct nir_variable {
struct exec_node node;
/**
@@ -383,7 +383,7 @@ nir_variable_get_io_mask(nir_variable *var, gl_shader_stage stage)
return ((1ull << slots) - 1) << var->data.location;
}
typedef struct {
typedef struct nir_register {
struct exec_node node;
unsigned num_components; /** < number of vector components */
@@ -477,7 +477,7 @@ nir_instr_is_last(nir_instr *instr)
return exec_node_is_tail_sentinel(exec_node_get_next(&instr->node));
}
typedef struct {
typedef struct nir_ssa_def {
/** for debugging only, can be NULL */
const char* name;
@@ -1530,6 +1530,20 @@ typedef struct nir_shader_compiler_options {
/** lowers ffract to fsub+ffloor: */
bool lower_ffract;
bool lower_pack_half_2x16;
bool lower_pack_unorm_2x16;
bool lower_pack_snorm_2x16;
bool lower_pack_unorm_4x8;
bool lower_pack_snorm_4x8;
bool lower_unpack_half_2x16;
bool lower_unpack_unorm_2x16;
bool lower_unpack_snorm_2x16;
bool lower_unpack_unorm_4x8;
bool lower_unpack_snorm_4x8;
bool lower_extract_byte;
bool lower_extract_word;
/**
* Does the driver support real 32-bit integers? (Otherwise, integers
* are simulated by floats.)
+14
View File
@@ -134,6 +134,20 @@ nir_imm_int(nir_builder *build, int x)
return nir_build_imm(build, 1, v);
}
static inline nir_ssa_def *
nir_imm_ivec4(nir_builder *build, int x, int y, int z, int w)
{
nir_const_value v;
memset(&v, 0, sizeof(v));
v.i[0] = x;
v.i[1] = y;
v.i[2] = z;
v.i[3] = w;
return nir_build_imm(build, 4, v);
}
static inline nir_ssa_def *
nir_build_alu(nir_builder *build, nir_op op, nir_ssa_def *src0,
nir_ssa_def *src1, nir_ssa_def *src2, nir_ssa_def *src3)
+58 -4
View File
@@ -97,6 +97,20 @@ lower_alu_instr_scalar(nir_alu_instr *instr, nir_builder *b)
*/
return;
case nir_op_pack_half_2x16:
if (!b->shader->options->lower_pack_half_2x16)
return;
nir_ssa_def *val =
nir_pack_half_2x16_split(b, nir_channel(b, instr->src[0].src.ssa,
instr->src[0].swizzle[0]),
nir_channel(b, instr->src[0].src.ssa,
instr->src[0].swizzle[1]));
nir_ssa_def_rewrite_uses(&instr->dest.dest.ssa, nir_src_for_ssa(val));
nir_instr_remove(&instr->instr);
return;
case nir_op_unpack_unorm_4x8:
case nir_op_unpack_snorm_4x8:
case nir_op_unpack_unorm_2x16:
@@ -106,11 +120,51 @@ lower_alu_instr_scalar(nir_alu_instr *instr, nir_builder *b)
*/
return;
case nir_op_unpack_half_2x16:
/* We could split this into unpack_half_2x16_split_[xy], but should
* we?
*/
case nir_op_unpack_half_2x16: {
if (!b->shader->options->lower_unpack_half_2x16)
return;
nir_ssa_def *comps[2];
comps[0] = nir_unpack_half_2x16_split_x(b, instr->src[0].src.ssa);
comps[1] = nir_unpack_half_2x16_split_y(b, instr->src[0].src.ssa);
nir_ssa_def *vec = nir_vec(b, comps, 2);
nir_ssa_def_rewrite_uses(&instr->dest.dest.ssa, nir_src_for_ssa(vec));
nir_instr_remove(&instr->instr);
return;
}
case nir_op_pack_uvec2_to_uint: {
assert(b->shader->options->lower_pack_snorm_2x16 ||
b->shader->options->lower_pack_unorm_2x16);
nir_ssa_def *word =
nir_extract_uword(b, instr->src[0].src.ssa, nir_imm_int(b, 0));
nir_ssa_def *val =
nir_ior(b, nir_ishl(b, nir_channel(b, word, 1), nir_imm_int(b, 16)),
nir_channel(b, word, 0));
nir_ssa_def_rewrite_uses(&instr->dest.dest.ssa, nir_src_for_ssa(val));
nir_instr_remove(&instr->instr);
break;
}
case nir_op_pack_uvec4_to_uint: {
assert(b->shader->options->lower_pack_snorm_4x8 ||
b->shader->options->lower_pack_unorm_4x8);
nir_ssa_def *byte =
nir_extract_ubyte(b, instr->src[0].src.ssa, nir_imm_int(b, 0));
nir_ssa_def *val =
nir_ior(b, nir_ior(b, nir_ishl(b, nir_channel(b, byte, 3), nir_imm_int(b, 24)),
nir_ishl(b, nir_channel(b, byte, 2), nir_imm_int(b, 16))),
nir_ior(b, nir_ishl(b, nir_channel(b, byte, 1), nir_imm_int(b, 8)),
nir_channel(b, byte, 0)));
nir_ssa_def_rewrite_uses(&instr->dest.dest.ssa, nir_src_for_ssa(val));
nir_instr_remove(&instr->instr);
break;
}
case nir_op_fdph: {
nir_ssa_def *sum[4];
+29 -10
View File
@@ -105,7 +105,7 @@ def opcode(name, output_size, output_type, input_sizes, input_types,
opcodes[name] = Opcode(name, output_size, output_type, input_sizes,
input_types, algebraic_properties, const_expr)
def unop_convert(name, in_type, out_type, const_expr):
def unop_convert(name, out_type, in_type, const_expr):
opcode(name, 0, out_type, [0], [in_type], "", const_expr)
def unop(name, ty, const_expr):
@@ -155,17 +155,17 @@ unop("frsq", tfloat, "1.0f / sqrtf(src0)")
unop("fsqrt", tfloat, "sqrtf(src0)")
unop("fexp2", tfloat, "exp2f(src0)")
unop("flog2", tfloat, "log2f(src0)")
unop_convert("f2i", tfloat, tint, "src0") # Float-to-integer conversion.
unop_convert("f2u", tfloat, tuint, "src0") # Float-to-unsigned conversion
unop_convert("i2f", tint, tfloat, "src0") # Integer-to-float conversion.
unop_convert("f2i", tint, tfloat, "src0") # Float-to-integer conversion.
unop_convert("f2u", tuint, tfloat, "src0") # Float-to-unsigned conversion
unop_convert("i2f", tfloat, tint, "src0") # Integer-to-float conversion.
# Float-to-boolean conversion
unop_convert("f2b", tfloat, tbool, "src0 != 0.0f")
unop_convert("f2b", tbool, tfloat, "src0 != 0.0f")
# Boolean-to-float conversion
unop_convert("b2f", tbool, tfloat, "src0 ? 1.0f : 0.0f")
unop_convert("b2f", tfloat, tbool, "src0 ? 1.0f : 0.0f")
# Int-to-boolean conversion
unop_convert("i2b", tint, tbool, "src0 != 0")
unop_convert("b2i", tbool, tint, "src0 ? 1 : 0") # Boolean-to-int conversion
unop_convert("u2f", tuint, tfloat, "src0") # Unsigned-to-float conversion.
unop_convert("i2b", tbool, tint, "src0 != 0")
unop_convert("b2i", tint, tbool, "src0 ? 1 : 0") # Boolean-to-int conversion
unop_convert("u2f", tfloat, tuint, "src0") # Unsigned-to-float conversion.
# Unary floating-point rounding operations.
@@ -238,6 +238,16 @@ unpack_2x16("unorm")
unpack_4x8("unorm")
unpack_2x16("half")
unop_horiz("pack_uvec2_to_uint", 0, tuint, 2, tuint, """
dst = (src0.x & 0xffff) | (src0.y >> 16);
""")
unop_horiz("pack_uvec4_to_uint", 0, tuint, 4, tuint, """
dst = (src0.x << 0) |
(src0.y << 8) |
(src0.z << 16) |
(src0.w << 24);
""")
# Lowered floating point unpacking operations.
@@ -265,7 +275,7 @@ for (unsigned bit = 0; bit < 32; bit++) {
}
""")
unop_convert("ufind_msb", tuint, tint, """
unop_convert("ufind_msb", tint, tuint, """
dst = -1;
for (int bit = 31; bit > 0; bit--) {
if ((src0 >> bit) & 1) {
@@ -551,6 +561,15 @@ dst.x = src0.x;
dst.y = src1.x;
""")
# Byte extraction
binop("extract_ubyte", tuint, "", "(uint8_t)(src0 >> (src1 * 8))")
binop("extract_ibyte", tint, "", "(int8_t)(src0 >> (src1 * 8))")
# Word extraction
binop("extract_uword", tuint, "", "(uint16_t)(src0 >> (src1 * 16))")
binop("extract_iword", tint, "", "(int16_t)(src0 >> (src1 * 16))")
def triop(name, ty, const_expr):
opcode(name, 0, ty, [0, 0, 0], [ty, ty, ty], "", const_expr)
def triop_horiz(name, output_size, src1_size, src2_size, src3_size, const_expr):
+64
View File
@@ -245,6 +245,70 @@ optimizations = [
('bcsel', ('ult', 31, 'bits'), 'value',
('ubfe', 'value', 'offset', 'bits')),
'options->lower_bitfield_extract'),
(('extract_ibyte', a, b),
('ishr', ('ishl', a, ('imul', ('isub', 3, b), 8)), 8),
'options->lower_extract_byte'),
(('extract_ubyte', a, b),
('iand', ('ushr', a, ('imul', b, 8)), 0xff),
'options->lower_extract_byte'),
(('extract_iword', a, b),
('ishr', ('ishl', a, ('imul', ('isub', 1, b), 16)), 16),
'options->lower_extract_word'),
(('extract_uword', a, b),
('iand', ('ushr', a, ('imul', b, 16)), 0xffff),
'options->lower_extract_word'),
(('pack_unorm_2x16', 'v'),
('pack_uvec2_to_uint',
('f2u', ('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)))),
'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)))),
'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)))),
'options->lower_pack_snorm_4x8'),
(('unpack_unorm_2x16', 'v'),
('fdiv', ('u2f', ('vec4', ('extract_uword', 'v', 0),
('extract_uword', 'v', 1), 0, 0)),
65535.0),
'options->lower_unpack_unorm_2x16'),
(('unpack_unorm_4x8', 'v'),
('fdiv', ('u2f', ('vec4', ('extract_ubyte', 'v', 0),
('extract_ubyte', 'v', 1),
('extract_ubyte', 'v', 2),
('extract_ubyte', 'v', 3))),
255.0),
'options->lower_unpack_unorm_4x8'),
(('unpack_snorm_2x16', 'v'),
('fmin', 1.0, ('fmax', -1.0, ('fdiv', ('i2f', ('vec4', ('extract_iword', 'v', 0),
('extract_iword', 'v', 1), 0, 0)),
32767.0))),
'options->lower_unpack_snorm_2x16'),
(('unpack_snorm_4x8', 'v'),
('fmin', 1.0, ('fmax', -1.0, ('fdiv', ('i2f', ('vec4', ('extract_ibyte', 'v', 0),
('extract_ibyte', 'v', 1),
('extract_ibyte', 'v', 2),
('extract_ibyte', 'v', 3))),
127.0))),
'options->lower_unpack_snorm_4x8'),
]
# Add optimizations to handle the case where the result of a ternary is
+1 -1
View File
@@ -487,7 +487,7 @@ print_intrinsic_instr(nir_intrinsic_instr *instr, print_state *state)
if (i != 0)
fprintf(fp, ", ");
fprintf(fp, "%u", instr->const_index[i]);
fprintf(fp, "%d", instr->const_index[i]);
}
fprintf(fp, ")");
+18 -10
View File
@@ -33,7 +33,8 @@
#define ENUM(x) [x] = #x
#define NAME(val) ((((val) < ARRAY_SIZE(names)) && names[(val)]) ? names[(val)] : "UNKNOWN")
const char * gl_shader_stage_name(gl_shader_stage stage)
const char *
gl_shader_stage_name(gl_shader_stage stage)
{
static const char *names[] = {
ENUM(MESA_SHADER_VERTEX),
@@ -51,15 +52,16 @@ const char * gl_shader_stage_name(gl_shader_stage stage)
* Translate a gl_shader_stage to a short shader stage name for debug
* printouts and error messages.
*/
const char * _mesa_shader_stage_to_string(unsigned stage)
const char *
_mesa_shader_stage_to_string(unsigned stage)
{
switch (stage) {
case MESA_SHADER_VERTEX: return "vertex";
case MESA_SHADER_FRAGMENT: return "fragment";
case MESA_SHADER_GEOMETRY: return "geometry";
case MESA_SHADER_COMPUTE: return "compute";
case MESA_SHADER_TESS_CTRL: return "tess ctrl";
case MESA_SHADER_TESS_EVAL: return "tess eval";
case MESA_SHADER_TESS_CTRL: return "tessellation control";
case MESA_SHADER_TESS_EVAL: return "tessellation evaluation";
}
unreachable("Unknown shader stage.");
@@ -69,7 +71,8 @@ const char * _mesa_shader_stage_to_string(unsigned stage)
* Translate a gl_shader_stage to a shader stage abbreviation (VS, GS, FS)
* for debug printouts and error messages.
*/
const char * _mesa_shader_stage_to_abbrev(unsigned stage)
const char *
_mesa_shader_stage_to_abbrev(unsigned stage)
{
switch (stage) {
case MESA_SHADER_VERTEX: return "VS";
@@ -83,7 +86,8 @@ const char * _mesa_shader_stage_to_abbrev(unsigned stage)
unreachable("Unknown shader stage.");
}
const char * gl_vert_attrib_name(gl_vert_attrib attrib)
const char *
gl_vert_attrib_name(gl_vert_attrib attrib)
{
static const char *names[] = {
ENUM(VERT_ATTRIB_POS),
@@ -124,7 +128,8 @@ const char * gl_vert_attrib_name(gl_vert_attrib attrib)
return NAME(attrib);
}
const char * gl_varying_slot_name(gl_varying_slot slot)
const char *
gl_varying_slot_name(gl_varying_slot slot)
{
static const char *names[] = {
ENUM(VARYING_SLOT_POS),
@@ -190,7 +195,8 @@ const char * gl_varying_slot_name(gl_varying_slot slot)
return NAME(slot);
}
const char * gl_system_value_name(gl_system_value sysval)
const char *
gl_system_value_name(gl_system_value sysval)
{
static const char *names[] = {
ENUM(SYSTEM_VALUE_VERTEX_ID),
@@ -218,7 +224,8 @@ const char * gl_system_value_name(gl_system_value sysval)
return NAME(sysval);
}
const char * glsl_interp_qualifier_name(enum glsl_interp_qualifier qual)
const char *
glsl_interp_qualifier_name(enum glsl_interp_qualifier qual)
{
static const char *names[] = {
ENUM(INTERP_QUALIFIER_NONE),
@@ -230,7 +237,8 @@ const char * glsl_interp_qualifier_name(enum glsl_interp_qualifier qual)
return NAME(qual);
}
const char * gl_frag_result_name(gl_frag_result result)
const char *
gl_frag_result_name(gl_frag_result result)
{
static const char *names[] = {
ENUM(FRAG_RESULT_DEPTH),
+8 -8
View File
@@ -47,19 +47,19 @@ typedef enum
MESA_SHADER_COMPUTE = 5,
} gl_shader_stage;
const char * gl_shader_stage_name(gl_shader_stage stage);
const char *gl_shader_stage_name(gl_shader_stage stage);
/**
* Translate a gl_shader_stage to a short shader stage name for debug
* printouts and error messages.
*/
const char * _mesa_shader_stage_to_string(unsigned stage);
const char *_mesa_shader_stage_to_string(unsigned stage);
/**
* Translate a gl_shader_stage to a shader stage abbreviation (VS, GS, FS)
* for debug printouts and error messages.
*/
const char * _mesa_shader_stage_to_abbrev(unsigned stage);
const char *_mesa_shader_stage_to_abbrev(unsigned stage);
#define MESA_SHADER_STAGES (MESA_SHADER_COMPUTE + 1)
@@ -109,7 +109,7 @@ typedef enum
VERT_ATTRIB_MAX = 33
} gl_vert_attrib;
const char * gl_vert_attrib_name(gl_vert_attrib attrib);
const char *gl_vert_attrib_name(gl_vert_attrib attrib);
/**
* Symbolic constats to help iterating over
@@ -254,7 +254,7 @@ typedef enum
#define VARYING_SLOT_PATCH0 (VARYING_SLOT_MAX)
#define VARYING_SLOT_TESS_MAX (VARYING_SLOT_PATCH0 + MAX_VARYING)
const char * gl_varying_slot_name(gl_varying_slot slot);
const char *gl_varying_slot_name(gl_varying_slot slot);
/**
* Bitflags for varying slots.
@@ -467,7 +467,7 @@ typedef enum
SYSTEM_VALUE_MAX /**< Number of values */
} gl_system_value;
const char * gl_system_value_name(gl_system_value sysval);
const char *gl_system_value_name(gl_system_value sysval);
/**
* The possible interpolation qualifiers that can be applied to a fragment
@@ -485,7 +485,7 @@ enum glsl_interp_qualifier
INTERP_QUALIFIER_COUNT /**< Number of interpolation qualifiers */
};
const char * glsl_interp_qualifier_name(enum glsl_interp_qualifier qual);
const char *glsl_interp_qualifier_name(enum glsl_interp_qualifier qual);
/**
* Fragment program results
@@ -516,7 +516,7 @@ typedef enum
FRAG_RESULT_DATA7,
} gl_frag_result;
const char * gl_frag_result_name(gl_frag_result result);
const char *gl_frag_result_name(gl_frag_result result);
#define FRAG_RESULT_MAX (FRAG_RESULT_DATA0 + MAX_DRAW_BUFFERS)