#include "glsl_parser_extras.h"
#include "program/prog_instruction.h"
#include <math.h>
+#include "builtin_functions.h"
#define M_PIf ((float) M_PI)
#define M_PI_2f ((float) M_PI_2)
return state->ARB_shader_clock_enable;
}
+static bool
+shader_clock_int64(const _mesa_glsl_parse_state *state)
+{
+ return state->ARB_shader_clock_enable &&
+ state->ARB_gpu_shader_int64_enable;
+}
+
static bool
shader_storage_buffer_object(const _mesa_glsl_parse_state *state)
{
return state->has_double();
}
+static bool
+int64(const _mesa_glsl_parse_state *state)
+{
+ return state->has_int64();
+}
+
+static bool
+int64_fp64(const _mesa_glsl_parse_state *state)
+{
+ return state->has_int64() && state->has_double();
+}
+
static bool
compute_shader(const _mesa_glsl_parse_state *state)
{
return state->stage == MESA_SHADER_COMPUTE;
}
+static bool
+compute_shader_supported(const _mesa_glsl_parse_state *state)
+{
+ return state->has_compute_shader();
+}
+
static bool
buffer_atomics_supported(const _mesa_glsl_parse_state *state)
{
return state->ARB_shader_group_vote_enable;
}
+static bool
+integer_functions_supported(const _mesa_glsl_parse_state *state)
+{
+ return state->extensions->MESA_shader_integer_functions;
+}
/** @} */
/******************************************************************************/
B1(floatBitsToUint)
B1(intBitsToFloat)
B1(uintBitsToFloat)
+
+ BA1(doubleBitsToInt64)
+ BA1(doubleBitsToUint64)
+ BA1(int64BitsToDouble)
+ BA1(uint64BitsToDouble)
+
ir_function_signature *_packUnorm2x16(builtin_available_predicate avail);
ir_function_signature *_packSnorm2x16(builtin_available_predicate avail);
ir_function_signature *_packUnorm4x8(builtin_available_predicate avail);
ir_function_signature *_unpackHalf2x16(builtin_available_predicate avail);
ir_function_signature *_packDouble2x32(builtin_available_predicate avail);
ir_function_signature *_unpackDouble2x32(builtin_available_predicate avail);
+ ir_function_signature *_packInt2x32(builtin_available_predicate avail);
+ ir_function_signature *_unpackInt2x32(builtin_available_predicate avail);
+ ir_function_signature *_packUint2x32(builtin_available_predicate avail);
+ ir_function_signature *_unpackUint2x32(builtin_available_predicate avail);
BA1(length)
BA1(distance);
ir_intrinsic_group_memory_barrier),
NULL);
add_function("__intrinsic_memory_barrier_atomic_counter",
- _memory_barrier_intrinsic(compute_shader,
+ _memory_barrier_intrinsic(compute_shader_supported,
ir_intrinsic_memory_barrier_atomic_counter),
NULL);
add_function("__intrinsic_memory_barrier_buffer",
- _memory_barrier_intrinsic(compute_shader,
+ _memory_barrier_intrinsic(compute_shader_supported,
ir_intrinsic_memory_barrier_buffer),
NULL);
add_function("__intrinsic_memory_barrier_image",
- _memory_barrier_intrinsic(compute_shader,
+ _memory_barrier_intrinsic(compute_shader_supported,
ir_intrinsic_memory_barrier_image),
NULL);
add_function("__intrinsic_memory_barrier_shared",
_##NAME(glsl_type::ivec4_type), \
NULL);
-#define FID(NAME) \
+#define FI64(NAME) \
add_function(#NAME, \
_##NAME(always_available, glsl_type::float_type), \
_##NAME(always_available, glsl_type::vec2_type), \
_##NAME(fp64, glsl_type::dvec2_type), \
_##NAME(fp64, glsl_type::dvec3_type), \
_##NAME(fp64, glsl_type::dvec4_type), \
+ _##NAME(int64, glsl_type::int64_t_type), \
+ _##NAME(int64, glsl_type::i64vec2_type), \
+ _##NAME(int64, glsl_type::i64vec3_type), \
+ _##NAME(int64, glsl_type::i64vec4_type), \
NULL);
-#define FIUD(NAME) \
+#define FIUD_VEC(NAME) \
add_function(#NAME, \
- _##NAME(always_available, glsl_type::float_type), \
_##NAME(always_available, glsl_type::vec2_type), \
_##NAME(always_available, glsl_type::vec3_type), \
_##NAME(always_available, glsl_type::vec4_type), \
\
- _##NAME(always_available, glsl_type::int_type), \
_##NAME(always_available, glsl_type::ivec2_type), \
_##NAME(always_available, glsl_type::ivec3_type), \
_##NAME(always_available, glsl_type::ivec4_type), \
\
- _##NAME(v130, glsl_type::uint_type), \
_##NAME(v130, glsl_type::uvec2_type), \
_##NAME(v130, glsl_type::uvec3_type), \
_##NAME(v130, glsl_type::uvec4_type), \
- _##NAME(fp64, glsl_type::double_type), \
_##NAME(fp64, glsl_type::dvec2_type), \
_##NAME(fp64, glsl_type::dvec3_type), \
_##NAME(fp64, glsl_type::dvec4_type), \
+ _##NAME(int64, glsl_type::int64_t_type), \
+ _##NAME(int64, glsl_type::i64vec2_type), \
+ _##NAME(int64, glsl_type::i64vec3_type), \
+ _##NAME(int64, glsl_type::i64vec4_type), \
+ _##NAME(int64, glsl_type::uint64_t_type), \
+ _##NAME(int64, glsl_type::u64vec2_type), \
+ _##NAME(int64, glsl_type::u64vec3_type), \
+ _##NAME(int64, glsl_type::u64vec4_type), \
NULL);
#define IU(NAME) \
_##NAME(glsl_type::uvec4_type), \
NULL);
-#define FIUBD(NAME) \
+#define FIUBD_VEC(NAME) \
add_function(#NAME, \
- _##NAME(always_available, glsl_type::float_type), \
_##NAME(always_available, glsl_type::vec2_type), \
_##NAME(always_available, glsl_type::vec3_type), \
_##NAME(always_available, glsl_type::vec4_type), \
\
- _##NAME(always_available, glsl_type::int_type), \
_##NAME(always_available, glsl_type::ivec2_type), \
_##NAME(always_available, glsl_type::ivec3_type), \
_##NAME(always_available, glsl_type::ivec4_type), \
\
- _##NAME(v130, glsl_type::uint_type), \
_##NAME(v130, glsl_type::uvec2_type), \
_##NAME(v130, glsl_type::uvec3_type), \
_##NAME(v130, glsl_type::uvec4_type), \
\
- _##NAME(always_available, glsl_type::bool_type), \
_##NAME(always_available, glsl_type::bvec2_type), \
_##NAME(always_available, glsl_type::bvec3_type), \
_##NAME(always_available, glsl_type::bvec4_type), \
\
- _##NAME(fp64, glsl_type::double_type), \
_##NAME(fp64, glsl_type::dvec2_type), \
_##NAME(fp64, glsl_type::dvec3_type), \
_##NAME(fp64, glsl_type::dvec4_type), \
+ _##NAME(int64, glsl_type::int64_t_type), \
+ _##NAME(int64, glsl_type::i64vec2_type), \
+ _##NAME(int64, glsl_type::i64vec3_type), \
+ _##NAME(int64, glsl_type::i64vec4_type), \
+ _##NAME(int64, glsl_type::uint64_t_type), \
+ _##NAME(int64, glsl_type::u64vec2_type), \
+ _##NAME(int64, glsl_type::u64vec3_type), \
+ _##NAME(int64, glsl_type::u64vec4_type), \
NULL);
#define FIUD2_MIXED(NAME) \
_##NAME(fp64, glsl_type::dvec2_type, glsl_type::dvec2_type), \
_##NAME(fp64, glsl_type::dvec3_type, glsl_type::dvec3_type), \
_##NAME(fp64, glsl_type::dvec4_type, glsl_type::dvec4_type), \
+ \
+ _##NAME(int64, glsl_type::int64_t_type, glsl_type::int64_t_type), \
+ _##NAME(int64, glsl_type::i64vec2_type, glsl_type::int64_t_type), \
+ _##NAME(int64, glsl_type::i64vec3_type, glsl_type::int64_t_type), \
+ _##NAME(int64, glsl_type::i64vec4_type, glsl_type::int64_t_type), \
+ _##NAME(int64, glsl_type::i64vec2_type, glsl_type::i64vec2_type), \
+ _##NAME(int64, glsl_type::i64vec3_type, glsl_type::i64vec3_type), \
+ _##NAME(int64, glsl_type::i64vec4_type, glsl_type::i64vec4_type), \
+ _##NAME(int64, glsl_type::uint64_t_type, glsl_type::uint64_t_type), \
+ _##NAME(int64, glsl_type::u64vec2_type, glsl_type::uint64_t_type), \
+ _##NAME(int64, glsl_type::u64vec3_type, glsl_type::uint64_t_type), \
+ _##NAME(int64, glsl_type::u64vec4_type, glsl_type::uint64_t_type), \
+ _##NAME(int64, glsl_type::u64vec2_type, glsl_type::u64vec2_type), \
+ _##NAME(int64, glsl_type::u64vec3_type, glsl_type::u64vec3_type), \
+ _##NAME(int64, glsl_type::u64vec4_type, glsl_type::u64vec4_type), \
NULL);
F(radians)
F(log2)
FD(sqrt)
FD(inversesqrt)
- FID(abs)
- FID(sign)
+ FI64(abs)
+ FI64(sign)
FD(floor)
FD(trunc)
FD(round)
_mix_sel(shader_integer_mix, glsl_type::bvec2_type, glsl_type::bvec2_type),
_mix_sel(shader_integer_mix, glsl_type::bvec3_type, glsl_type::bvec3_type),
_mix_sel(shader_integer_mix, glsl_type::bvec4_type, glsl_type::bvec4_type),
+
+ _mix_sel(int64, glsl_type::int64_t_type, glsl_type::bool_type),
+ _mix_sel(int64, glsl_type::i64vec2_type, glsl_type::bvec2_type),
+ _mix_sel(int64, glsl_type::i64vec3_type, glsl_type::bvec3_type),
+ _mix_sel(int64, glsl_type::i64vec4_type, glsl_type::bvec4_type),
+
+ _mix_sel(int64, glsl_type::uint64_t_type, glsl_type::bool_type),
+ _mix_sel(int64, glsl_type::u64vec2_type, glsl_type::bvec2_type),
+ _mix_sel(int64, glsl_type::u64vec3_type, glsl_type::bvec3_type),
+ _mix_sel(int64, glsl_type::u64vec4_type, glsl_type::bvec4_type),
NULL);
add_function("step",
_uintBitsToFloat(glsl_type::uvec4_type),
NULL);
+ add_function("doubleBitsToInt64",
+ _doubleBitsToInt64(int64_fp64, glsl_type::double_type),
+ _doubleBitsToInt64(int64_fp64, glsl_type::dvec2_type),
+ _doubleBitsToInt64(int64_fp64, glsl_type::dvec3_type),
+ _doubleBitsToInt64(int64_fp64, glsl_type::dvec4_type),
+ NULL);
+
+ add_function("doubleBitsToUint64",
+ _doubleBitsToUint64(int64_fp64, glsl_type::double_type),
+ _doubleBitsToUint64(int64_fp64, glsl_type::dvec2_type),
+ _doubleBitsToUint64(int64_fp64, glsl_type::dvec3_type),
+ _doubleBitsToUint64(int64_fp64, glsl_type::dvec4_type),
+ NULL);
+
+ add_function("int64BitsToDouble",
+ _int64BitsToDouble(int64_fp64, glsl_type::int64_t_type),
+ _int64BitsToDouble(int64_fp64, glsl_type::i64vec2_type),
+ _int64BitsToDouble(int64_fp64, glsl_type::i64vec3_type),
+ _int64BitsToDouble(int64_fp64, glsl_type::i64vec4_type),
+ NULL);
+
+ add_function("uint64BitsToDouble",
+ _uint64BitsToDouble(int64_fp64, glsl_type::uint64_t_type),
+ _uint64BitsToDouble(int64_fp64, glsl_type::u64vec2_type),
+ _uint64BitsToDouble(int64_fp64, glsl_type::u64vec3_type),
+ _uint64BitsToDouble(int64_fp64, glsl_type::u64vec4_type),
+ NULL);
+
add_function("packUnorm2x16", _packUnorm2x16(shader_packing_or_es3_or_gpu_shader5), NULL);
add_function("packSnorm2x16", _packSnorm2x16(shader_packing_or_es3), NULL);
add_function("packUnorm4x8", _packUnorm4x8(shader_packing_or_es31_or_gpu_shader5), NULL);
add_function("packDouble2x32", _packDouble2x32(fp64), NULL);
add_function("unpackDouble2x32", _unpackDouble2x32(fp64), NULL);
+ add_function("packInt2x32", _packInt2x32(int64), NULL);
+ add_function("unpackInt2x32", _unpackInt2x32(int64), NULL);
+ add_function("packUint2x32", _packUint2x32(int64), NULL);
+ add_function("unpackUint2x32", _unpackUint2x32(int64), NULL);
FD(length)
FD(distance)
_transpose(fp64, glsl_type::dmat4x2_type),
_transpose(fp64, glsl_type::dmat4x3_type),
NULL);
- FIUD(lessThan)
- FIUD(lessThanEqual)
- FIUD(greaterThan)
- FIUD(greaterThanEqual)
- FIUBD(notEqual)
- FIUBD(equal)
+ FIUD_VEC(lessThan)
+ FIUD_VEC(lessThanEqual)
+ FIUD_VEC(greaterThan)
+ FIUD_VEC(greaterThanEqual)
+ FIUBD_VEC(notEqual)
+ FIUBD_VEC(equal)
add_function("any",
_any(glsl_type::bvec2_type),
_texture(ir_tex, v130, glsl_type::float_type, glsl_type::sampler1DArrayShadow_type, glsl_type::vec3_type),
_texture(ir_tex, v130, glsl_type::float_type, glsl_type::sampler2DArrayShadow_type, glsl_type::vec4_type),
/* samplerCubeArrayShadow is special; it has an extra parameter
- * for the shadow comparitor since there is no vec5 type.
+ * for the shadow comparator since there is no vec5 type.
*/
_textureCubeArrayShadow(),
NULL);
add_function("memoryBarrierAtomicCounter",
_memory_barrier("__intrinsic_memory_barrier_atomic_counter",
- compute_shader),
+ compute_shader_supported),
NULL);
add_function("memoryBarrierBuffer",
_memory_barrier("__intrinsic_memory_barrier_buffer",
- compute_shader),
+ compute_shader_supported),
NULL);
add_function("memoryBarrierImage",
_memory_barrier("__intrinsic_memory_barrier_image",
- compute_shader),
+ compute_shader_supported),
NULL);
add_function("memoryBarrierShared",
_memory_barrier("__intrinsic_memory_barrier_shared",
glsl_type::uvec2_type),
NULL);
+ add_function("clockARB",
+ _shader_clock(shader_clock_int64,
+ glsl_type::uint64_t_type),
+ NULL);
+
add_function("anyInvocationARB", _vote(ir_unop_vote_any), NULL);
add_function("allInvocationsARB", _vote(ir_unop_vote_all), NULL);
add_function("allInvocationsEqualARB", _vote(ir_unop_vote_eq), NULL);
+ add_function("__builtin_idiv64",
+ generate_ir::idiv64(mem_ctx, integer_functions_supported),
+ NULL);
+
+ add_function("__builtin_imod64",
+ generate_ir::imod64(mem_ctx, integer_functions_supported),
+ NULL);
+
+ add_function("__builtin_sign64",
+ generate_ir::sign64(mem_ctx, integer_functions_supported),
+ NULL);
+
+ add_function("__builtin_udiv64",
+ generate_ir::udiv64(mem_ctx, integer_functions_supported),
+ NULL);
+
+ add_function("__builtin_umod64",
+ generate_ir::umod64(mem_ctx, integer_functions_supported),
+ NULL);
+
+ add_function("__builtin_umul64",
+ generate_ir::umul64(mem_ctx, integer_functions_supported),
+ NULL);
+
#undef F
#undef FI
-#undef FIUD
-#undef FIUBD
+#undef FIUD_VEC
+#undef FIUBD_VEC
#undef FIU2_MIXED
}
ir_function_signature *
builtin_builder::_atan2(const glsl_type *type)
{
- ir_variable *vec_y = in_var(type, "vec_y");
- ir_variable *vec_x = in_var(type, "vec_x");
- MAKE_SIG(type, always_available, 2, vec_y, vec_x);
-
- ir_variable *vec_result = body.make_temp(type, "vec_result");
- ir_variable *r = body.make_temp(glsl_type::float_type, "r");
- for (int i = 0; i < type->vector_elements; i++) {
- ir_variable *y = body.make_temp(glsl_type::float_type, "y");
- ir_variable *x = body.make_temp(glsl_type::float_type, "x");
- body.emit(assign(y, swizzle(vec_y, i, 1)));
- body.emit(assign(x, swizzle(vec_x, i, 1)));
-
- /* If |x| >= 1.0e-8 * |y|: */
- ir_if *outer_if =
- new(mem_ctx) ir_if(greater(abs(x), mul(imm(1.0e-8f), abs(y))));
-
- ir_factory outer_then(&outer_if->then_instructions, mem_ctx);
-
- /* Then...call atan(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)));
- inner_if->then_instructions.push_tail(
- if_tree(gequal(y, imm(0.0f)),
- assign(r, add(r, imm(M_PIf))),
- assign(r, sub(r, imm(M_PIf)))));
- outer_then.emit(inner_if);
+ const unsigned n = type->vector_elements;
+ ir_variable *y = in_var(type, "y");
+ ir_variable *x = in_var(type, "x");
+ MAKE_SIG(type, always_available, 2, y, x);
- /* Else... */
- outer_if->else_instructions.push_tail(
- assign(r, mul(sign(y), imm(M_PI_2f))));
+ /* If we're on the left half-plane rotate the coordinates π/2 clock-wise
+ * for the y=0 discontinuity to end up aligned with the vertical
+ * discontinuity of atan(s/t) along t=0. This also makes sure that we
+ * don't attempt to divide by zero along the vertical line, which may give
+ * unspecified results on non-GLSL 4.1-capable hardware.
+ */
+ ir_variable *flip = body.make_temp(glsl_type::bvec(n), "flip");
+ body.emit(assign(flip, gequal(imm(0.0f, n), x)));
+ ir_variable *s = body.make_temp(type, "s");
+ body.emit(assign(s, csel(flip, abs(x), y)));
+ ir_variable *t = body.make_temp(type, "t");
+ body.emit(assign(t, csel(flip, y, abs(x))));
- body.emit(outer_if);
+ /* If the magnitude of the denominator exceeds some huge value, scale down
+ * the arguments in order to prevent the reciprocal operation from flushing
+ * its result to zero, which would cause precision problems, and for s
+ * infinite would cause us to return a NaN instead of the correct finite
+ * value.
+ *
+ * If fmin and fmax are respectively the smallest and largest positive
+ * normalized floating point values representable by the implementation,
+ * the constants below should be in agreement with:
+ *
+ * huge <= 1 / fmin
+ * scale <= 1 / fmin / fmax (for |t| >= huge)
+ *
+ * In addition scale should be a negative power of two in order to avoid
+ * loss of precision. The values chosen below should work for most usual
+ * floating point representations with at least the dynamic range of ATI's
+ * 24-bit representation.
+ */
+ ir_constant *huge = imm(1e18f, n);
+ ir_variable *scale = body.make_temp(type, "scale");
+ body.emit(assign(scale, csel(gequal(abs(t), huge),
+ imm(0.25f, n), imm(1.0f, n))));
+ ir_variable *rcp_scaled_t = body.make_temp(type, "rcp_scaled_t");
+ body.emit(assign(rcp_scaled_t, rcp(mul(t, scale))));
+ ir_expression *s_over_t = mul(mul(s, scale), rcp_scaled_t);
+
+ /* For |x| = |y| assume tan = 1 even if infinite (i.e. pretend momentarily
+ * that ∞/∞ = 1) in order to comply with the rather artificial rules
+ * inherited from IEEE 754-2008, namely:
+ *
+ * "atan2(±∞, −∞) is ±3π/4
+ * atan2(±∞, +∞) is ±π/4"
+ *
+ * Note that this is inconsistent with the rules for the neighborhood of
+ * zero that are based on iterated limits:
+ *
+ * "atan2(±0, −0) is ±π
+ * atan2(±0, +0) is ±0"
+ *
+ * but GLSL specifically allows implementations to deviate from IEEE rules
+ * at (0,0), so we take that license (i.e. pretend that 0/0 = 1 here as
+ * well).
+ */
+ ir_expression *tan = csel(equal(abs(x), abs(y)),
+ imm(1.0f, n), abs(s_over_t));
- body.emit(assign(vec_result, r, 1 << i));
- }
- body.emit(ret(vec_result));
+ /* Calculate the arctangent and fix up the result if we had flipped the
+ * coordinate system.
+ */
+ ir_variable *arc = body.make_temp(type, "arc");
+ do_atan(body, type, arc, tan);
+ body.emit(assign(arc, add(arc, mul(b2f(flip), imm(M_PI_2f)))));
+
+ /* Rather convoluted calculation of the sign of the result. When x < 0 we
+ * cannot use fsign because we need to be able to distinguish between
+ * negative and positive zero. Unfortunately we cannot use bitwise
+ * arithmetic tricks either because of back-ends without integer support.
+ * When x >= 0 rcp_scaled_t will always be non-negative so this won't be
+ * able to distinguish between negative and positive zero, but we don't
+ * care because atan2 is continuous along the whole positive y = 0
+ * half-line, so it won't affect the result significantly.
+ */
+ body.emit(ret(csel(less(min2(y, rcp_scaled_t), imm(0.0f, n)),
+ neg(arc), arc)));
return sig;
}
ir_variable *x = in_var(type, "x");
MAKE_SIG(type, v130, 1, x);
- /* (e^x - e^(-x)) / (e^x + e^(-x)) */
- body.emit(ret(div(sub(exp(x), exp(neg(x))),
- add(exp(x), exp(neg(x))))));
+ /* tanh(x) := (0.5 * (e^x - e^(-x))) / (0.5 * (e^x + e^(-x)))
+ *
+ * With a little algebra this reduces to (e^2x - 1) / (e^2x + 1)
+ *
+ * Clamp x to (-inf, +10] to avoid precision problems. When x > 10, e^2x
+ * is so much larger than 1.0 that 1.0 gets flushed to zero in the
+ * computation e^2x +/- 1 so it can be ignored.
+ */
+ ir_variable *t = body.make_temp(type, "tmp");
+ body.emit(assign(t, min2(x, imm(10.0f))));
+
+ body.emit(ret(div(sub(exp(mul(t, imm(2.0f))), imm(1.0f)),
+ add(exp(mul(t, imm(2.0f))), imm(1.0f)))));
return sig;
}
return sig;
}
+ir_function_signature *
+builtin_builder::_doubleBitsToInt64(builtin_available_predicate avail, const glsl_type *type)
+{
+ ir_variable *x = in_var(type, "x");
+ MAKE_SIG(glsl_type::i64vec(type->vector_elements), avail, 1, x);
+ body.emit(ret(bitcast_d2i64(x)));
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_doubleBitsToUint64(builtin_available_predicate avail, const glsl_type *type)
+{
+ ir_variable *x = in_var(type, "x");
+ MAKE_SIG(glsl_type::u64vec(type->vector_elements), avail, 1, x);
+ body.emit(ret(bitcast_d2u64(x)));
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_int64BitsToDouble(builtin_available_predicate avail, const glsl_type *type)
+{
+ ir_variable *x = in_var(type, "x");
+ MAKE_SIG(glsl_type::dvec(type->vector_elements), avail, 1, x);
+ body.emit(ret(bitcast_i642d(x)));
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_uint64BitsToDouble(builtin_available_predicate avail, const glsl_type *type)
+{
+ ir_variable *x = in_var(type, "x");
+ MAKE_SIG(glsl_type::dvec(type->vector_elements), avail, 1, x);
+ body.emit(ret(bitcast_u642d(x)));
+ return sig;
+}
+
ir_function_signature *
builtin_builder::_packUnorm2x16(builtin_available_predicate avail)
{
return sig;
}
+ir_function_signature *
+builtin_builder::_packInt2x32(builtin_available_predicate avail)
+{
+ ir_variable *v = in_var(glsl_type::ivec2_type, "v");
+ MAKE_SIG(glsl_type::int64_t_type, avail, 1, v);
+ body.emit(ret(expr(ir_unop_pack_int_2x32, v)));
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_unpackInt2x32(builtin_available_predicate avail)
+{
+ ir_variable *p = in_var(glsl_type::int64_t_type, "p");
+ MAKE_SIG(glsl_type::ivec2_type, avail, 1, p);
+ body.emit(ret(expr(ir_unop_unpack_int_2x32, p)));
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_packUint2x32(builtin_available_predicate avail)
+{
+ ir_variable *v = in_var(glsl_type::uvec2_type, "v");
+ MAKE_SIG(glsl_type::uint64_t_type, avail, 1, v);
+ body.emit(ret(expr(ir_unop_pack_uint_2x32, v)));
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_unpackUint2x32(builtin_available_predicate avail)
+{
+ ir_variable *p = in_var(glsl_type::uint64_t_type, "p");
+ MAKE_SIG(glsl_type::uvec2_type, avail, 1, p);
+ body.emit(ret(expr(ir_unop_unpack_uint_2x32, p)));
+ return sig;
+}
+
ir_function_signature *
builtin_builder::_length(builtin_available_predicate avail, const glsl_type *type)
{
if (coord_size == coord_type->vector_elements) {
tex->coordinate = var_ref(P);
} else {
- /* The incoming coordinate also has the projector or shadow comparitor,
+ /* The incoming coordinate also has the projector or shadow comparator,
* so we need to swizzle those away.
*/
tex->coordinate = swizzle_for_size(P, coord_size);
*/
ir_variable *refz = in_var(glsl_type::float_type, "refz");
sig->parameters.push_tail(refz);
- tex->shadow_comparitor = var_ref(refz);
+ tex->shadow_comparator = var_ref(refz);
} else {
- /* The shadow comparitor is normally in the Z component, but a few types
+ /* The shadow comparator is normally in the Z component, but a few types
* have sufficiently large coordinates that it's in W.
*/
- tex->shadow_comparitor = swizzle(P, MAX2(coord_size, SWIZZLE_Z), 1);
+ tex->shadow_comparator = swizzle(P, MAX2(coord_size, SWIZZLE_Z), 1);
}
}
tex->set_sampler(var_ref(s), glsl_type::float_type);
tex->coordinate = var_ref(P);
- tex->shadow_comparitor = var_ref(compare);
+ tex->shadow_comparator = var_ref(compare);
body.emit(ret(tex));
body.emit(call(shader->symbols->get_function("__intrinsic_shader_clock"),
retval, sig->parameters));
- body.emit(ret(retval));
+
+ if (type == glsl_type::uint64_t_type) {
+ body.emit(ret(expr(ir_unop_pack_uint_2x32, retval)));
+ } else {
+ body.emit(ret(retval));
+ }
+
return sig;
}