nir: move to compiler/
[mesa.git] / src / glsl / builtin_functions.cpp
index 4462bfd2324c0cda7816122f08b95c100489a8fa..95e86df1cdd247f589956c799918e532280e68af 100644 (file)
@@ -135,6 +135,12 @@ v140(const _mesa_glsl_parse_state *state)
    return state->is_version(140, 0);
 }
 
+static bool
+v140_or_es3(const _mesa_glsl_parse_state *state)
+{
+   return state->is_version(140, 300);
+}
+
 static bool
 v400_fs_only(const _mesa_glsl_parse_state *state)
 {
@@ -478,6 +484,12 @@ compute_shader(const _mesa_glsl_parse_state *state)
    return state->stage == MESA_SHADER_COMPUTE;
 }
 
+static bool
+buffer_atomics_supported(const _mesa_glsl_parse_state *state)
+{
+   return compute_shader(state) || shader_storage_buffer_object(state);
+}
+
 static bool
 barrier_supported(const _mesa_glsl_parse_state *state)
 {
@@ -538,6 +550,7 @@ private:
    ir_variable *in_var(const glsl_type *type, const char *name);
    ir_variable *out_var(const glsl_type *type, const char *name);
    ir_constant *imm(float f, unsigned vector_elements=1);
+   ir_constant *imm(bool b, unsigned vector_elements=1);
    ir_constant *imm(int i, unsigned vector_elements=1);
    ir_constant *imm(unsigned u, unsigned vector_elements=1);
    ir_constant *imm(double d, unsigned vector_elements=1);
@@ -931,51 +944,51 @@ builtin_builder::create_intrinsics()
                 NULL);
 
    add_function("__intrinsic_atomic_add",
-                _atomic_intrinsic2(shader_storage_buffer_object,
+                _atomic_intrinsic2(buffer_atomics_supported,
                                    glsl_type::uint_type),
-                _atomic_intrinsic2(shader_storage_buffer_object,
+                _atomic_intrinsic2(buffer_atomics_supported,
                                    glsl_type::int_type),
                 NULL);
    add_function("__intrinsic_atomic_min",
-                _atomic_intrinsic2(shader_storage_buffer_object,
+                _atomic_intrinsic2(buffer_atomics_supported,
                                    glsl_type::uint_type),
-                _atomic_intrinsic2(shader_storage_buffer_object,
+                _atomic_intrinsic2(buffer_atomics_supported,
                                    glsl_type::int_type),
                 NULL);
    add_function("__intrinsic_atomic_max",
-                _atomic_intrinsic2(shader_storage_buffer_object,
+                _atomic_intrinsic2(buffer_atomics_supported,
                                    glsl_type::uint_type),
-                _atomic_intrinsic2(shader_storage_buffer_object,
+                _atomic_intrinsic2(buffer_atomics_supported,
                                    glsl_type::int_type),
                 NULL);
    add_function("__intrinsic_atomic_and",
-                _atomic_intrinsic2(shader_storage_buffer_object,
+                _atomic_intrinsic2(buffer_atomics_supported,
                                    glsl_type::uint_type),
-                _atomic_intrinsic2(shader_storage_buffer_object,
+                _atomic_intrinsic2(buffer_atomics_supported,
                                    glsl_type::int_type),
                 NULL);
    add_function("__intrinsic_atomic_or",
-                _atomic_intrinsic2(shader_storage_buffer_object,
+                _atomic_intrinsic2(buffer_atomics_supported,
                                    glsl_type::uint_type),
-                _atomic_intrinsic2(shader_storage_buffer_object,
+                _atomic_intrinsic2(buffer_atomics_supported,
                                    glsl_type::int_type),
                 NULL);
    add_function("__intrinsic_atomic_xor",
-                _atomic_intrinsic2(shader_storage_buffer_object,
+                _atomic_intrinsic2(buffer_atomics_supported,
                                    glsl_type::uint_type),
-                _atomic_intrinsic2(shader_storage_buffer_object,
+                _atomic_intrinsic2(buffer_atomics_supported,
                                    glsl_type::int_type),
                 NULL);
    add_function("__intrinsic_atomic_exchange",
-                _atomic_intrinsic2(shader_storage_buffer_object,
+                _atomic_intrinsic2(buffer_atomics_supported,
                                    glsl_type::uint_type),
-                _atomic_intrinsic2(shader_storage_buffer_object,
+                _atomic_intrinsic2(buffer_atomics_supported,
                                    glsl_type::int_type),
                 NULL);
    add_function("__intrinsic_atomic_comp_swap",
-                _atomic_intrinsic3(shader_storage_buffer_object,
+                _atomic_intrinsic3(buffer_atomics_supported,
                                    glsl_type::uint_type),
-                _atomic_intrinsic3(shader_storage_buffer_object,
+                _atomic_intrinsic3(buffer_atomics_supported,
                                    glsl_type::int_type),
                 NULL);
 
@@ -1432,9 +1445,9 @@ builtin_builder::create_builtins()
 
                 NULL);
    add_function("inverse",
-                _inverse_mat2(v120, glsl_type::mat2_type),
-                _inverse_mat3(v120, glsl_type::mat3_type),
-                _inverse_mat4(v120, glsl_type::mat4_type),
+                _inverse_mat2(v140_or_es3, glsl_type::mat2_type),
+                _inverse_mat3(v140_or_es3, glsl_type::mat3_type),
+                _inverse_mat4(v140_or_es3, glsl_type::mat4_type),
                 _inverse_mat2(fp64, glsl_type::dmat2_type),
                 _inverse_mat3(fp64, glsl_type::dmat3_type),
                 _inverse_mat4(fp64, glsl_type::dmat4_type),
@@ -2683,66 +2696,66 @@ builtin_builder::create_builtins()
 
    add_function("atomicAdd",
                 _atomic_op2("__intrinsic_atomic_add",
-                            shader_storage_buffer_object,
+                            buffer_atomics_supported,
                             glsl_type::uint_type),
                 _atomic_op2("__intrinsic_atomic_add",
-                            shader_storage_buffer_object,
+                            buffer_atomics_supported,
                             glsl_type::int_type),
                 NULL);
    add_function("atomicMin",
                 _atomic_op2("__intrinsic_atomic_min",
-                            shader_storage_buffer_object,
+                            buffer_atomics_supported,
                             glsl_type::uint_type),
                 _atomic_op2("__intrinsic_atomic_min",
-                            shader_storage_buffer_object,
+                            buffer_atomics_supported,
                             glsl_type::int_type),
                 NULL);
    add_function("atomicMax",
                 _atomic_op2("__intrinsic_atomic_max",
-                            shader_storage_buffer_object,
+                            buffer_atomics_supported,
                             glsl_type::uint_type),
                 _atomic_op2("__intrinsic_atomic_max",
-                            shader_storage_buffer_object,
+                            buffer_atomics_supported,
                             glsl_type::int_type),
                 NULL);
    add_function("atomicAnd",
                 _atomic_op2("__intrinsic_atomic_and",
-                            shader_storage_buffer_object,
+                            buffer_atomics_supported,
                             glsl_type::uint_type),
                 _atomic_op2("__intrinsic_atomic_and",
-                            shader_storage_buffer_object,
+                            buffer_atomics_supported,
                             glsl_type::int_type),
                 NULL);
    add_function("atomicOr",
                 _atomic_op2("__intrinsic_atomic_or",
-                            shader_storage_buffer_object,
+                            buffer_atomics_supported,
                             glsl_type::uint_type),
                 _atomic_op2("__intrinsic_atomic_or",
-                            shader_storage_buffer_object,
+                            buffer_atomics_supported,
                             glsl_type::int_type),
                 NULL);
    add_function("atomicXor",
                 _atomic_op2("__intrinsic_atomic_xor",
-                            shader_storage_buffer_object,
+                            buffer_atomics_supported,
                             glsl_type::uint_type),
                 _atomic_op2("__intrinsic_atomic_xor",
-                            shader_storage_buffer_object,
+                            buffer_atomics_supported,
                             glsl_type::int_type),
                 NULL);
    add_function("atomicExchange",
                 _atomic_op2("__intrinsic_atomic_exchange",
-                            shader_storage_buffer_object,
+                            buffer_atomics_supported,
                             glsl_type::uint_type),
                 _atomic_op2("__intrinsic_atomic_exchange",
-                            shader_storage_buffer_object,
+                            buffer_atomics_supported,
                             glsl_type::int_type),
                 NULL);
    add_function("atomicCompSwap",
                 _atomic_op3("__intrinsic_atomic_comp_swap",
-                            shader_storage_buffer_object,
+                            buffer_atomics_supported,
                             glsl_type::uint_type),
                 _atomic_op3("__intrinsic_atomic_comp_swap",
-                            shader_storage_buffer_object,
+                            buffer_atomics_supported,
                             glsl_type::int_type),
                 NULL);
 
@@ -2999,6 +3012,12 @@ builtin_builder::out_var(const glsl_type *type, const char *name)
    return new(mem_ctx) ir_variable(type, name, ir_var_function_out);
 }
 
+ir_constant *
+builtin_builder::imm(bool b, unsigned vector_elements)
+{
+   return new(mem_ctx) ir_constant(b, vector_elements);
+}
+
 ir_constant *
 builtin_builder::imm(float f, unsigned vector_elements)
 {
@@ -3248,7 +3267,7 @@ builtin_builder::_atan2(const glsl_type *type)
       ir_factory outer_then(&outer_if->then_instructions, mem_ctx);
 
       /* Then...call atan(y/x) */
-      do_atan(body, glsl_type::float_type, r, div(y, x));
+      do_atan(outer_then, glsl_type::float_type, r, div(y, x));
 
       /*     ...and fix it up: */
       ir_if *inner_if = new(mem_ctx) ir_if(less(x, imm(0.0f)));
@@ -4358,7 +4377,13 @@ builtin_builder::_notEqual(builtin_available_predicate avail,
 ir_function_signature *
 builtin_builder::_any(const glsl_type *type)
 {
-   return unop(always_available, ir_unop_any, glsl_type::bool_type, type);
+   ir_variable *v = in_var(type, "v");
+   MAKE_SIG(glsl_type::bool_type, always_available, 1, v);
+
+   const unsigned vec_elem = v->type->vector_elements;
+   body.emit(ret(expr(ir_binop_any_nequal, v, imm(false, vec_elem))));
+
+   return sig;
 }
 
 ir_function_signature *
@@ -4367,20 +4392,8 @@ builtin_builder::_all(const glsl_type *type)
    ir_variable *v = in_var(type, "v");
    MAKE_SIG(glsl_type::bool_type, always_available, 1, v);
 
-   switch (type->vector_elements) {
-   case 2:
-      body.emit(ret(logic_and(swizzle_x(v), swizzle_y(v))));
-      break;
-   case 3:
-      body.emit(ret(logic_and(logic_and(swizzle_x(v), swizzle_y(v)),
-                              swizzle_z(v))));
-      break;
-   case 4:
-      body.emit(ret(logic_and(logic_and(logic_and(swizzle_x(v), swizzle_y(v)),
-                                        swizzle_z(v)),
-                              swizzle_w(v))));
-      break;
-   }
+   const unsigned vec_elem = v->type->vector_elements;
+   body.emit(ret(expr(ir_binop_all_equal, v, imm(true, vec_elem))));
 
    return sig;
 }
@@ -4876,12 +4889,18 @@ builtin_builder::_noise4(const glsl_type *type)
 ir_function_signature *
 builtin_builder::_bitfieldExtract(const glsl_type *type)
 {
+   bool is_uint = type->base_type == GLSL_TYPE_UINT;
    ir_variable *value  = in_var(type, "value");
    ir_variable *offset = in_var(glsl_type::int_type, "offset");
    ir_variable *bits   = in_var(glsl_type::int_type, "bits");
    MAKE_SIG(type, gpu_shader5_or_es31, 3, value, offset, bits);
 
-   body.emit(ret(expr(ir_triop_bitfield_extract, value, offset, bits)));
+   operand cast_offset = is_uint ? i2u(offset) : operand(offset);
+   operand cast_bits = is_uint ? i2u(bits) : operand(bits);
+
+   body.emit(ret(expr(ir_triop_bitfield_extract, value,
+      swizzle(cast_offset, SWIZZLE_XXXX, type->vector_elements),
+      swizzle(cast_bits, SWIZZLE_XXXX, type->vector_elements))));
 
    return sig;
 }
@@ -4889,13 +4908,19 @@ builtin_builder::_bitfieldExtract(const glsl_type *type)
 ir_function_signature *
 builtin_builder::_bitfieldInsert(const glsl_type *type)
 {
+   bool is_uint = type->base_type == GLSL_TYPE_UINT;
    ir_variable *base   = in_var(type, "base");
    ir_variable *insert = in_var(type, "insert");
    ir_variable *offset = in_var(glsl_type::int_type, "offset");
    ir_variable *bits   = in_var(glsl_type::int_type, "bits");
    MAKE_SIG(type, gpu_shader5_or_es31, 4, base, insert, offset, bits);
 
-   body.emit(ret(bitfield_insert(base, insert, offset, bits)));
+   operand cast_offset = is_uint ? i2u(offset) : operand(offset);
+   operand cast_bits = is_uint ? i2u(bits) : operand(bits);
+
+   body.emit(ret(bitfield_insert(base, insert,
+      swizzle(cast_offset, SWIZZLE_XXXX, type->vector_elements),
+      swizzle(cast_bits, SWIZZLE_XXXX, type->vector_elements))));
 
    return sig;
 }