*/
#include "main/macros.h"
+#include "main/mtypes.h"
#include "compiler/glsl_types.h"
#include "ir.h"
#include "ir_builder.h"
class find_precision_visitor : public ir_rvalue_enter_visitor {
public:
- find_precision_visitor();
+ find_precision_visitor(const struct gl_shader_compiler_options *options);
~find_precision_visitor();
virtual void handle_rvalue(ir_rvalue **rvalue);
struct hash_table *clone_ht;
void *lowered_builtin_mem_ctx;
+
+ const struct gl_shader_compiler_options *options;
};
class find_lowerable_rvalues_visitor : public ir_hierarchical_visitor {
std::vector<ir_instruction *> lowerable_children;
};
- find_lowerable_rvalues_visitor(struct set *result);
+ find_lowerable_rvalues_visitor(struct set *result,
+ const struct gl_shader_compiler_options *options);
+ bool can_lower_type(const glsl_type *type) const;
static void stack_enter(class ir_instruction *ir, void *data);
static void stack_leave(class ir_instruction *ir, void *data);
virtual ir_visitor_status visit_leave(ir_assignment *ir);
virtual ir_visitor_status visit_leave(ir_call *ir);
- static can_lower_state handle_precision(const glsl_type *type,
- int precision);
+ can_lower_state handle_precision(const glsl_type *type,
+ int precision) const;
static parent_relation get_parent_relation(ir_instruction *parent,
ir_instruction *child);
std::vector<stack_entry> stack;
struct set *lowerable_rvalues;
+ const struct gl_shader_compiler_options *options;
void pop_stack_entry();
void add_lowerable_children(const stack_entry &entry);
};
bool
-can_lower_type(const glsl_type *type)
+find_lowerable_rvalues_visitor::can_lower_type(const glsl_type *type) const
{
/* Don’t lower any expressions involving non-float types except bool and
* texture samplers. This will rule out operations that change the type such
*/
switch (type->base_type) {
- case GLSL_TYPE_FLOAT:
+ /* TODO: should we do anything for these two with regard to Int16 vs FP16
+ * support?
+ */
case GLSL_TYPE_BOOL:
case GLSL_TYPE_SAMPLER:
return true;
+ case GLSL_TYPE_FLOAT:
+ return options->LowerPrecisionFloat16;
+
+ case GLSL_TYPE_UINT:
+ case GLSL_TYPE_INT:
+ return options->LowerPrecisionInt16;
+
default:
return false;
}
}
-find_lowerable_rvalues_visitor::find_lowerable_rvalues_visitor(struct set *res)
+find_lowerable_rvalues_visitor::find_lowerable_rvalues_visitor(struct set *res,
+ const struct gl_shader_compiler_options *opts)
{
lowerable_rvalues = res;
+ options = opts;
callback_enter = stack_enter;
callback_leave = stack_leave;
data_enter = this;
enum find_lowerable_rvalues_visitor::can_lower_state
find_lowerable_rvalues_visitor::handle_precision(const glsl_type *type,
- int precision)
+ int precision) const
{
if (!can_lower_type(type))
return CANT_LOWER;
}
void
-find_lowerable_rvalues(exec_list *instructions,
+find_lowerable_rvalues(const struct gl_shader_compiler_options *options,
+ exec_list *instructions,
struct set *result)
{
- find_lowerable_rvalues_visitor v(result);
+ find_lowerable_rvalues_visitor v(result, options);
visit_list_elements(&v, instructions);
}
static ir_rvalue *
-convert_precision(int op, ir_rvalue *ir)
+convert_precision(glsl_base_type type, bool up, ir_rvalue *ir)
{
- unsigned base_type = (op == ir_unop_f2fmp ?
- GLSL_TYPE_FLOAT16 : GLSL_TYPE_FLOAT);
+ unsigned new_type, op;
+
+ if (up) {
+ switch (type) {
+ case GLSL_TYPE_FLOAT16:
+ new_type = GLSL_TYPE_FLOAT;
+ op = ir_unop_f162f;
+ break;
+ case GLSL_TYPE_INT16:
+ new_type = GLSL_TYPE_INT;
+ op = ir_unop_i2i;
+ break;
+ case GLSL_TYPE_UINT16:
+ new_type = GLSL_TYPE_UINT;
+ op = ir_unop_u2u;
+ break;
+ default:
+ unreachable("invalid type");
+ return NULL;
+ }
+ } else {
+ switch (type) {
+ case GLSL_TYPE_FLOAT:
+ new_type = GLSL_TYPE_FLOAT16;
+ op = ir_unop_f2fmp;
+ break;
+ case GLSL_TYPE_INT:
+ new_type = GLSL_TYPE_INT16;
+ op = ir_unop_i2imp;
+ break;
+ case GLSL_TYPE_UINT:
+ new_type = GLSL_TYPE_UINT16;
+ op = ir_unop_u2ump;
+ break;
+ default:
+ unreachable("invalid type");
+ return NULL;
+ }
+ }
+
const glsl_type *desired_type;
- desired_type = glsl_type::get_instance(base_type,
+ desired_type = glsl_type::get_instance(new_type,
ir->type->vector_elements,
ir->type->matrix_columns);
return new(mem_ctx) ir_expression(op, desired_type, ir, NULL);
}
+static glsl_base_type
+lower_type(glsl_base_type type)
+{
+ switch (type) {
+ case GLSL_TYPE_FLOAT:
+ return GLSL_TYPE_FLOAT16;
+ case GLSL_TYPE_INT:
+ return GLSL_TYPE_INT16;
+ case GLSL_TYPE_UINT:
+ return GLSL_TYPE_UINT16;
+ default:
+ unreachable("invalid type");
+ return GLSL_TYPE_ERROR;;
+ }
+}
+
void
lower_precision_visitor::handle_rvalue(ir_rvalue **rvalue)
{
if (ir->as_dereference()) {
if (!ir->type->is_boolean())
- *rvalue = convert_precision(ir_unop_f2fmp, ir);
- } else if (ir->type->is_float()) {
- ir->type = glsl_type::get_instance(GLSL_TYPE_FLOAT16,
+ *rvalue = convert_precision(ir->type->base_type, false, ir);
+ } else if (ir->type->base_type == GLSL_TYPE_FLOAT ||
+ ir->type->base_type == GLSL_TYPE_INT ||
+ ir->type->base_type == GLSL_TYPE_UINT) {
+ ir->type = glsl_type::get_instance(lower_type(ir->type->base_type),
ir->type->vector_elements,
ir->type->matrix_columns,
ir->type->explicit_stride,
if (const_ir) {
ir_constant_data value;
- for (unsigned i = 0; i < ARRAY_SIZE(value.f16); i++)
- value.f16[i] = _mesa_float_to_half(const_ir->value.f[i]);
+ if (ir->type->base_type == GLSL_TYPE_FLOAT16) {
+ for (unsigned i = 0; i < ARRAY_SIZE(value.f16); i++)
+ value.f16[i] = _mesa_float_to_half(const_ir->value.f[i]);
+ } else if (ir->type->base_type == GLSL_TYPE_INT16) {
+ for (unsigned i = 0; i < ARRAY_SIZE(value.i16); i++)
+ value.i16[i] = const_ir->value.i[i];
+ } else if (ir->type->base_type == GLSL_TYPE_UINT16) {
+ for (unsigned i = 0; i < ARRAY_SIZE(value.u16); i++)
+ value.u16[i] = const_ir->value.u[i];
+ } else {
+ unreachable("invalid type");
+ }
const_ir->value = value;
}
case ir_unop_f2b:
ir->operation = ir_unop_f162b;
break;
+ case ir_unop_b2i:
+ case ir_unop_i2b:
+ /* Nothing to do - they both support int16. */
+ break;
default:
break;
}
/* Checking the precision of rvalue can be lowered first throughout
* find_lowerable_rvalues_visitor.
* Once it found the precision of rvalue can be lowered, then we can
- * add conversion f2fmp through lower_precision_visitor.
+ * add conversion f2fmp, etc. through lower_precision_visitor.
*/
if (*rvalue == NULL)
return;
* converted to bool
*/
if ((*rvalue)->type->base_type != GLSL_TYPE_BOOL)
- *rvalue = convert_precision(ir_unop_f162f, *rvalue);
+ *rvalue = convert_precision((*rvalue)->type->base_type, true, *rvalue);
progress = true;
}
param->data.precision = GLSL_PRECISION_MEDIUM;
}
- lower_precision(&lowered_sig->body);
+ lower_precision(options, &lowered_sig->body);
_mesa_hash_table_clear(clone_ht, NULL);
return lowered_sig;
}
-find_precision_visitor::find_precision_visitor()
+find_precision_visitor::find_precision_visitor(const struct gl_shader_compiler_options *options)
: progress(false),
lowerable_rvalues(_mesa_pointer_set_create(NULL)),
lowered_builtins(NULL),
clone_ht(NULL),
- lowered_builtin_mem_ctx(NULL)
+ lowered_builtin_mem_ctx(NULL),
+ options(options)
{
}
}
bool
-lower_precision(exec_list *instructions)
+lower_precision(const struct gl_shader_compiler_options *options,
+ exec_list *instructions)
{
- find_precision_visitor v;
+ find_precision_visitor v(options);
- find_lowerable_rvalues(instructions, v.lowerable_rvalues);
+ find_lowerable_rvalues(options, instructions, v.lowerable_rvalues);
visit_list_elements(&v, instructions);
TESTS = [
- Test("simple division",
+ Test("f32 simple division",
"""
uniform mediump float a, b;
}
""",
r'\(expression +float16_t +/'),
+ Test("i32 simple division",
+ """
+ #version 300 es
+ precision mediump float;
+ precision mediump int;
+ uniform mediump int a, b;
+
+ out vec4 color;
+
+ void main()
+ {
+ color = vec4(a / b);
+ }
+ """,
+ r'\(expression +int16_t +/'),
+ Test("u32 simple division",
+ """
+ #version 300 es
+ precision mediump float;
+ precision mediump int;
+ uniform mediump uint a, b;
+
+ out vec4 color;
+
+ void main()
+ {
+ color = vec4(a / b);
+ }
+ """,
+ r'\(expression +uint16_t +/'),
Test("dot",
"""
uniform mediump vec2 a, b;
}
""",
r'\(expression +float16_t +dot\b'),
- Test("array with const index",
+ Test("f32 array with const index",
"""
precision mediump float;
}
""",
r'\(expression +float16_t +/'),
- Test("array with uniform index",
+ Test("i32 array with const index",
+ """
+ #version 300 es
+ precision mediump float;
+ precision mediump int;
+
+ uniform int in_simple[2];
+
+ out vec4 color;
+
+ void main()
+ {
+ color = vec4(in_simple[0] / in_simple[1]);
+ }
+ """,
+ r'\(expression +int16_t +/'),
+ Test("u32 array with const index",
+ """
+ #version 300 es
+ precision mediump float;
+ precision mediump int;
+
+ uniform uint in_simple[2];
+
+ out vec4 color;
+
+ void main()
+ {
+ color = vec4(in_simple[0] / in_simple[1]);
+ }
+ """,
+ r'\(expression +uint16_t +/'),
+ Test("f32 array with uniform index",
"""
precision mediump float;
}
""",
r'\(expression +float16_t +/'),
- Test("array-of-array with const index",
+ Test("i32 array with uniform index",
+ """
+ #version 300 es
+ precision mediump float;
+ precision mediump int;
+
+ uniform int in_simple[2];
+ uniform int i0, i1;
+
+ out vec4 color;
+
+ void main()
+ {
+ color = vec4(in_simple[i0] / in_simple[i1]);
+ }
+ """,
+ r'\(expression +int16_t +/'),
+ Test("u32 array with uniform index",
+ """
+ #version 300 es
+ precision mediump float;
+ precision mediump int;
+
+ uniform uint in_simple[2];
+ uniform int i0, i1;
+
+ out vec4 color;
+
+ void main()
+ {
+ color = vec4(in_simple[i0] / in_simple[i1]);
+ }
+ """,
+ r'\(expression +uint16_t +/'),
+ Test("f32 array-of-array with const index",
"""
#version 310 es
precision mediump float;
}
""",
r'\(expression +float16_t +/'),
- Test("array-of-array with uniform index",
+ Test("i32 array-of-array with const index",
+ """
+ #version 310 es
+ precision mediump float;
+ precision mediump int;
+
+ uniform int in_aoa[2][2];
+
+ layout(location = 0) out highp int out_color;
+
+ void main()
+ {
+ out_color = in_aoa[0][0] / in_aoa[1][1];
+ }
+ """,
+ r'\(expression +int16_t +/'),
+ Test("u32 array-of-array with const index",
+ """
+ #version 310 es
+ precision mediump float;
+ precision mediump int;
+
+ uniform uint in_aoa[2][2];
+
+ layout(location = 0) out highp uint out_color;
+
+ void main()
+ {
+ out_color = in_aoa[0][0] / in_aoa[1][1];
+ }
+ """,
+ r'\(expression +uint16_t +/'),
+ Test("f32 array-of-array with uniform index",
"""
#version 310 es
precision mediump float;
}
""",
r'\(expression +float16_t +/'),
- Test("array index",
+ Test("i32 array-of-array with uniform index",
+ """
+ #version 310 es
+ precision mediump float;
+ precision mediump int;
+
+ uniform int in_aoa[2][2];
+ uniform int i0, i1;
+
+ layout(location = 0) out highp int out_color;
+
+ void main()
+ {
+ out_color = in_aoa[i0][i0] / in_aoa[i1][i1];
+ }
+ """,
+ r'\(expression +int16_t +/'),
+ Test("u32 array-of-array with uniform index",
+ """
+ #version 310 es
+ precision mediump float;
+ precision mediump int;
+
+ uniform uint in_aoa[2][2];
+ uniform int i0, i1;
+
+ layout(location = 0) out highp uint out_color;
+
+ void main()
+ {
+ out_color = in_aoa[i0][i0] / in_aoa[i1][i1];
+ }
+ """,
+ r'\(expression +uint16_t +/'),
+ Test("f32 array index",
"""
uniform mediump float a, b;
uniform mediump float values[2];
}
""",
r'\(expression +float16_t +/'),
- Test("function",
+ Test("i32 array index",
+ """
+ #version 310 es
+ precision mediump float;
+ precision mediump int;
+
+ uniform mediump int a, b;
+ uniform mediump int values[2];
+
+ out highp int color;
+
+ void main()
+ {
+ color = values[a / b];
+ }
+ """,
+ r'\(expression +int16_t +/'),
+ Test("f32 function",
"""
precision mediump float;
}
""",
r'\(expression +float16_t +/'),
- Test("function mediump args",
+ Test("i32 function",
+ """
+ #version 310 es
+ precision mediump float;
+ precision mediump int;
+
+ uniform int a, b;
+
+ mediump int
+ get_a()
+ {
+ return a;
+ }
+
+ int
+ get_b()
+ {
+ return b;
+ }
+
+ out highp int color;
+
+ void main()
+ {
+ color = get_a() / get_b();
+ }
+ """,
+ r'\(expression +int16_t +/'),
+ Test("u32 function",
+ """
+ #version 310 es
+ precision mediump float;
+ precision mediump int;
+
+ uniform uint a, b;
+
+ mediump uint
+ get_a()
+ {
+ return a;
+ }
+
+ uint
+ get_b()
+ {
+ return b;
+ }
+
+ out highp uint color;
+
+ void main()
+ {
+ color = get_a() / get_b();
+ }
+ """,
+ r'\(expression +uint16_t +/'),
+ Test("f32 function mediump args",
"""
precision mediump float;
}
""",
r'\(expression +float16_t +/'),
- Test("function highp args",
+ Test("i32 function mediump args",
+ """
+ #version 310 es
+ precision mediump float;
+ precision mediump int;
+
+ uniform int a, b;
+
+ mediump int
+ do_div(int x, int y)
+ {
+ return x / y;
+ }
+
+ out highp int color;
+
+ void main()
+ {
+ color = do_div(a, b);
+ }
+ """,
+ r'\(expression +int16_t +/'),
+ Test("u32 function mediump args",
+ """
+ #version 310 es
+ precision mediump float;
+ precision mediump int;
+
+ uniform uint a, b;
+
+ mediump uint
+ do_div(uint x, uint y)
+ {
+ return x / y;
+ }
+
+ out highp uint color;
+
+ void main()
+ {
+ color = do_div(a, b);
+ }
+ """,
+ r'\(expression +uint16_t +/'),
+ Test("f32 function highp args",
"""
precision mediump float;
}
""",
r'\(expression +float +/'),
- Test("function inout different precision highp",
+ Test("i32 function highp args",
+ """
+ #version 310 es
+ precision mediump float;
+ precision mediump int;
+
+ uniform int a, b;
+
+ mediump int
+ do_div(highp int x, highp int y)
+ {
+ return x / y;
+ }
+
+ out highp int color;
+
+ void main()
+ {
+ color = do_div(a, b);
+ }
+ """,
+ r'\(expression +int +/'),
+ Test("u32 function highp args",
+ """
+ #version 310 es
+ precision mediump float;
+ precision mediump int;
+
+ uniform uint a, b;
+
+ mediump uint
+ do_div(highp uint x, highp uint y)
+ {
+ return x / y;
+ }
+
+ out highp uint color;
+
+ void main()
+ {
+ color = do_div(a, b);
+ }
+ """,
+ r'\(expression +uint +/'),
+ Test("f32 function inout different precision highp",
"""
uniform mediump float a, b;
}
""",
r'\(expression +float +/'),
- Test("function inout different precision mediump",
+ Test("i32 function inout different precision highp",
+ """
+ #version 310 es
+ uniform mediump int a, b;
+
+ void
+ do_div(inout highp int x, highp int y)
+ {
+ x = x / y;
+ }
+
+ out mediump int color;
+
+ void main()
+ {
+ mediump int temp = a;
+ do_div(temp, b);
+ color = temp;
+ }
+ """,
+ r'\(expression +int +/'),
+ Test("u32 function inout different precision highp",
+ """
+ #version 310 es
+ uniform mediump uint a, b;
+
+ void
+ do_div(inout highp uint x, highp uint y)
+ {
+ x = x / y;
+ }
+
+ out mediump uint color;
+
+ void main()
+ {
+ mediump uint temp = a;
+ do_div(temp, b);
+ color = temp;
+ }
+ """,
+ r'\(expression +uint +/'),
+ Test("f32 function inout different precision mediump",
"""
uniform highp float a, b;
}
""",
r'\(expression +float16_t +/'),
- Test("if",
+ Test("i32 function inout different precision mediump",
+ """
+ #version 310 es
+ uniform highp int a, b;
+
+ out highp int color;
+
+ void
+ do_div(inout mediump int x, mediump int y)
+ {
+ x = x / y;
+ }
+
+ void main()
+ {
+ highp int temp = a;
+ do_div(temp, b);
+ color = temp;
+ }
+ """,
+ r'\(expression +int16_t +/'),
+ Test("u32 function inout different precision mediump",
+ """
+ #version 310 es
+ uniform highp uint a, b;
+
+ out highp uint color;
+
+ void
+ do_div(inout mediump uint x, mediump uint y)
+ {
+ x = x / y;
+ }
+
+ void main()
+ {
+ highp uint temp = a;
+ do_div(temp, b);
+ color = temp;
+ }
+ """,
+ r'\(expression +uint16_t +/'),
+ Test("f32 if",
"""
precision mediump float;
}
""",
r'\(expression +float16_t +/'),
+ Test("i32 if",
+ """
+ #version 310 es
+ precision mediump float;
+ precision mediump int;
+
+ uniform int a, b;
+
+ out vec4 color;
+
+ void
+ main()
+ {
+ if (a / b < 10)
+ color = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ color = vec4(1.0, 0.0, 0.0, 1.0);
+ }
+ """,
+ r'\(expression +int16_t +/'),
+ Test("u32 if",
+ """
+ #version 310 es
+ precision mediump float;
+ precision mediump int;
+
+ uniform uint a, b;
+
+ out vec4 color;
+
+ void
+ main()
+ {
+ if (a / b < 10u)
+ color = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ color = vec4(1.0, 0.0, 0.0, 1.0);
+ }
+ """,
+ r'\(expression +uint16_t +/'),
Test("matrix",
"""
precision mediump float;
}
""",
r'\(expression +f16vec2 \*.*\bf16mat2\b'),
- Test("simple struct deref",
+ Test("f32 simple struct deref",
"""
precision mediump float;
}
""",
r'\(expression +float16_t +/'),
- Test("embedded struct deref",
+ Test("i32 simple struct deref",
+ """
+ #version 310 es
+ precision mediump float;
+ precision mediump int;
+
+ struct simple {
+ int a, b;
+ };
+
+ uniform simple in_simple;
+
+ out highp int color;
+
+ void main()
+ {
+ color = in_simple.a / in_simple.b;
+ }
+ """,
+ r'\(expression +int16_t +/'),
+ Test("u32 simple struct deref",
+ """
+ #version 310 es
+ precision mediump float;
+ precision mediump int;
+
+ struct simple {
+ uint a, b;
+ };
+
+ uniform simple in_simple;
+
+ out highp uint color;
+
+ void main()
+ {
+ color = in_simple.a / in_simple.b;
+ }
+ """,
+ r'\(expression +uint16_t +/'),
+ Test("f32 embedded struct deref",
"""
precision mediump float;
}
""",
r'\(expression +float16_t +/'),
- Test("arrayed struct deref",
+ Test("i32 embedded struct deref",
+ """
+ #version 310 es
+ precision mediump float;
+ precision mediump int;
+
+ struct simple {
+ int a, b;
+ };
+
+ struct embedded {
+ simple a, b;
+ };
+
+ uniform embedded in_embedded;
+
+ out highp int color;
+
+ void main()
+ {
+ color = in_embedded.a.a / in_embedded.b.b;
+ }
+ """,
+ r'\(expression +int16_t +/'),
+ Test("u32 embedded struct deref",
+ """
+ #version 310 es
+ precision mediump float;
+ precision mediump int;
+
+ struct simple {
+ uint a, b;
+ };
+
+ struct embedded {
+ simple a, b;
+ };
+
+ uniform embedded in_embedded;
+
+ out highp uint color;
+
+ void main()
+ {
+ color = in_embedded.a.a / in_embedded.b.b;
+ }
+ """,
+ r'\(expression +uint16_t +/'),
+ Test("f32 arrayed struct deref",
"""
precision mediump float;
}
""",
r'\(expression +float16_t +/'),
- Test("mixed precision not lowered",
+ Test("i32 arrayed struct deref",
+ """
+ #version 310 es
+ precision mediump float;
+ precision mediump int;
+
+ struct simple {
+ int a, b;
+ };
+
+ struct arrayed {
+ simple a[2];
+ };
+
+ uniform arrayed in_arrayed;
+
+ out highp int color;
+
+ void main()
+ {
+ color = in_arrayed.a[0].a / in_arrayed.a[1].b;
+ }
+ """,
+ r'\(expression +int16_t +/'),
+ Test("u32 arrayed struct deref",
+ """
+ #version 310 es
+ precision mediump float;
+ precision mediump int;
+
+ struct simple {
+ uint a, b;
+ };
+
+ struct arrayed {
+ simple a[2];
+ };
+
+ uniform arrayed in_arrayed;
+
+ out highp uint color;
+
+ void main()
+ {
+ color = in_arrayed.a[0].a / in_arrayed.a[1].b;
+ }
+ """,
+ r'\(expression +uint16_t +/'),
+ Test("f32 mixed precision not lowered",
"""
uniform mediump float a;
uniform highp float b;
}
""",
r'\(expression +float +/'),
- Test("texture sample",
+ Test("i32 mixed precision not lowered",
+ """
+ #version 310 es
+ uniform mediump int a;
+ uniform highp int b;
+
+ out mediump int color;
+
+ void main()
+ {
+ color = a / b;
+ }
+ """,
+ r'\(expression +int +/'),
+ Test("u32 mixed precision not lowered",
+ """
+ #version 310 es
+ uniform mediump uint a;
+ uniform highp uint b;
+
+ out mediump uint color;
+
+ void main()
+ {
+ color = a / b;
+ }
+ """,
+ r'\(expression +uint +/'),
+ Test("f32 texture sample",
"""
precision mediump float;
gl_FragColor = texture2D(tex, coord) / divisor;
}
""",
- r'\(expression +f16vec4 +/'),
- Test("expression in lvalue",
+ r'\(expression +f16vec4 +/.*\(tex +f16vec4 +'),
+ Test("i32 texture sample",
+ """
+ #version 310 es
+ precision mediump float;
+ precision mediump int;
+
+ uniform mediump isampler2D tex;
+ uniform vec2 coord;
+ uniform int divisor;
+
+ out highp ivec4 color;
+
+ void main()
+ {
+ color = texture(tex, coord) / divisor;
+ }
+ """,
+ r'\(expression +i16vec4 +/.*\(tex +i16vec4 +'),
+ Test("u32 texture sample",
+ """
+ #version 310 es
+ precision mediump float;
+ precision mediump int;
+
+ uniform mediump usampler2D tex;
+ uniform vec2 coord;
+ uniform uint divisor;
+
+ out highp uvec4 color;
+
+ void main()
+ {
+ color = texture(tex, coord) / divisor;
+ }
+ """,
+ r'\(expression +u16vec4 +/.*\(tex +u16vec4 +'),
+ Test("f32 expression in lvalue",
"""
uniform mediump float a, b;
}
""",
r'\(expression +float16_t +/'),
- Test("builtin with const arg",
+ Test("i32 expression in lvalue",
+ """
+ #version 310 es
+ precision mediump float;
+ precision mediump int;
+
+ uniform mediump int a, b;
+
+ out vec4 color;
+
+ void main()
+ {
+ color = vec4(1.0);
+ color[a / b] = 0.5;
+ }
+ """,
+ r'\(expression +int16_t +/'),
+ Test("f32 builtin with const arg",
"""
uniform mediump float a;
}
""",
r'\(expression +float16_t min'),
+ Test("i32 builtin with const arg",
+ """
+ #version 310 es
+ uniform mediump int a;
+
+ out highp int color;
+
+ void main()
+ {
+ color = min(a, 3);
+ }
+ """,
+ r'\(expression +int16_t min'),
+ Test("u32 builtin with const arg",
+ """
+ #version 310 es
+ uniform mediump uint a;
+
+ out highp uint color;
+
+ void main()
+ {
+ color = min(a, 3u);
+ }
+ """,
+ r'\(expression +uint16_t min'),
]
ir = compile_shader(standalone_compiler, test.source)
if re.search(test.match_re, ir) is None:
+ print(ir)
return False
return True