* name and parameters.
*/
+
+/**
+ * Unfortunately, some versions of MinGW produce bad code if this file
+ * is compiled with -O2 or -O3. The resulting driver will crash in random
+ * places if the app uses GLSL.
+ * The work-around is to disable optimizations for just this file. Luckily,
+ * this code is basically just executed once.
+ *
+ * MinGW 4.6.3 (in Ubuntu 13.10) does not have this bug.
+ * MinGW 5.3.1 (in Ubuntu 16.04) definitely has this bug.
+ * MinGW 6.2.0 (in Ubuntu 16.10) definitely has this bug.
+ * MinGW x.y.z - don't know. Assume versions after 4.6.x are buggy
+ */
+
+#if defined(__MINGW32__) && ((__GNUC__ * 100) + __GNUC_MINOR >= 407)
+#warning "disabling optimizations for this file to work around compiler bug"
+#pragma GCC optimize("O1")
+#endif
+
+
#include <stdarg.h>
#include <stdio.h>
#include "main/core.h" /* for struct gl_shader */
#include "program/prog_instruction.h"
#include <math.h>
#include "builtin_functions.h"
+#include "util/hash_table.h"
#define M_PIf ((float) M_PI)
#define M_PI_2f ((float) M_PI_2)
return state->ARB_shader_atomic_counter_ops_enable;
}
+static bool
+shader_ballot(const _mesa_glsl_parse_state *state)
+{
+ return state->ARB_shader_ballot_enable;
+}
+
static bool
shader_clock(const _mesa_glsl_parse_state *state)
{
const glsl_type *sampler_type,
const glsl_type *coord_type,
int flags = 0);
- B0(textureCubeArrayShadow);
+ BA1(textureCubeArrayShadow);
ir_function_signature *_texelFetch(builtin_available_predicate avail,
const glsl_type *return_type,
const glsl_type *sampler_type,
ir_function_signature *_memory_barrier(const char *intrinsic_name,
builtin_available_predicate avail);
+ ir_function_signature *_ballot();
+ ir_function_signature *_read_first_invocation(const glsl_type *type);
+ ir_function_signature *_read_invocation(const glsl_type *type);
+
ir_function_signature *_shader_clock_intrinsic(builtin_available_predicate avail,
const glsl_type *type);
ir_function_signature *_shader_clock(builtin_available_predicate avail,
/* samplerCubeArrayShadow is special; it has an extra parameter
* for the shadow comparator since there is no vec5 type.
*/
- _textureCubeArrayShadow(),
+ _textureCubeArrayShadow(texture_cube_map_array, glsl_type::samplerCubeArrayShadow_type),
_texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler2DRect_type, glsl_type::vec2_type),
_texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler2DRect_type, glsl_type::vec2_type),
compute_shader),
NULL);
+ add_function("ballotARB", _ballot(), NULL);
+
+ add_function("readInvocationARB",
+ _read_invocation(glsl_type::float_type),
+ _read_invocation(glsl_type::vec2_type),
+ _read_invocation(glsl_type::vec3_type),
+ _read_invocation(glsl_type::vec4_type),
+
+ _read_invocation(glsl_type::int_type),
+ _read_invocation(glsl_type::ivec2_type),
+ _read_invocation(glsl_type::ivec3_type),
+ _read_invocation(glsl_type::ivec4_type),
+
+ _read_invocation(glsl_type::uint_type),
+ _read_invocation(glsl_type::uvec2_type),
+ _read_invocation(glsl_type::uvec3_type),
+ _read_invocation(glsl_type::uvec4_type),
+ NULL);
+
+ add_function("readFirstInvocationARB",
+ _read_first_invocation(glsl_type::float_type),
+ _read_first_invocation(glsl_type::vec2_type),
+ _read_first_invocation(glsl_type::vec3_type),
+ _read_first_invocation(glsl_type::vec4_type),
+
+ _read_first_invocation(glsl_type::int_type),
+ _read_first_invocation(glsl_type::ivec2_type),
+ _read_first_invocation(glsl_type::ivec3_type),
+ _read_first_invocation(glsl_type::ivec4_type),
+
+ _read_first_invocation(glsl_type::uint_type),
+ _read_first_invocation(glsl_type::uvec2_type),
+ _read_first_invocation(glsl_type::uvec3_type),
+ _read_first_invocation(glsl_type::uvec4_type),
+ NULL);
+
add_function("clock2x32ARB",
_shader_clock(shader_clock,
glsl_type::uvec2_type),
}
ir_function_signature *
-builtin_builder::_textureCubeArrayShadow()
+builtin_builder::_textureCubeArrayShadow(builtin_available_predicate avail,
+ const glsl_type *sampler_type)
{
- ir_variable *s = in_var(glsl_type::samplerCubeArrayShadow_type, "sampler");
+ ir_variable *s = in_var(sampler_type, "sampler");
ir_variable *P = in_var(glsl_type::vec4_type, "P");
ir_variable *compare = in_var(glsl_type::float_type, "compare");
- MAKE_SIG(glsl_type::float_type, texture_cube_map_array, 3, s, P, compare);
+ MAKE_SIG(glsl_type::float_type, avail, 3, s, P, compare);
ir_texture *tex = new(mem_ctx) ir_texture(ir_tex);
tex->set_sampler(var_ref(s), glsl_type::float_type);
return sig;
}
+ir_function_signature *
+builtin_builder::_ballot()
+{
+ ir_variable *value = in_var(glsl_type::bool_type, "value");
+
+ MAKE_SIG(glsl_type::uint64_t_type, shader_ballot, 1, value);
+ body.emit(ret(expr(ir_unop_ballot, value)));
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_read_first_invocation(const glsl_type *type)
+{
+ ir_variable *value = in_var(type, "value");
+
+ MAKE_SIG(type, shader_ballot, 1, value);
+ body.emit(ret(expr(ir_unop_read_first_invocation, value)));
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_read_invocation(const glsl_type *type)
+{
+ ir_variable *value = in_var(type, "value");
+ ir_variable *invocation = in_var(glsl_type::uint_type, "invocation");
+
+ MAKE_SIG(type, shader_ballot, 2, value, invocation);
+ body.emit(ret(expr(ir_binop_read_invocation, value, invocation)));
+ return sig;
+}
+
ir_function_signature *
builtin_builder::_shader_clock_intrinsic(builtin_available_predicate avail,
const glsl_type *type)
{
MAKE_SIG(type, avail, 0);
- ir_variable *retval = body.make_temp(type, "clock_retval");
+ ir_variable *retval = body.make_temp(glsl_type::uvec2_type, "clock_retval");
body.emit(call(shader->symbols->get_function("__intrinsic_shader_clock"),
retval, sig->parameters));
_mesa_glsl_find_builtin_function(_mesa_glsl_parse_state *state,
const char *name, exec_list *actual_parameters)
{
- ir_function_signature * s;
+ ir_function_signature *s;
mtx_lock(&builtins_lock);
s = builtins.find(state, name, actual_parameters);
mtx_unlock(&builtins_lock);
- return s;
+
+ if (s == NULL)
+ return NULL;
+
+ struct hash_table *ht =
+ _mesa_hash_table_create(NULL, _mesa_hash_pointer, _mesa_key_pointer_equal);
+ void *mem_ctx = state;
+ ir_function *f = s->function()->clone(mem_ctx, ht);
+ _mesa_hash_table_destroy(ht, NULL);
+
+ return f->matching_signature(state, actual_parameters, true);
}
-ir_function *
-_mesa_glsl_find_builtin_function_by_name(const char *name)
+bool
+_mesa_glsl_has_builtin_function(const char *name)
{
ir_function *f;
mtx_lock(&builtins_lock);
f = builtins.shader->symbols->get_function(name);
mtx_unlock(&builtins_lock);
- return f;
+
+ return f != NULL;
}
gl_shader *