return state->is_version(140, 0);
}
+static bool
+v400_fs_only(const _mesa_glsl_parse_state *state)
+{
+ return state->is_version(400, 0) &&
+ state->stage == MESA_SHADER_FRAGMENT;
+}
+
static bool
es31(const _mesa_glsl_parse_state *state)
{
static bool
texture_multisample_array(const _mesa_glsl_parse_state *state)
{
- return state->is_version(150, 0) ||
- state->ARB_texture_multisample_enable;
+ return state->is_version(150, 320) ||
+ state->ARB_texture_multisample_enable ||
+ state->OES_texture_storage_multisample_2d_array_enable;
+}
+
+static bool
+texture_samples_identical(const _mesa_glsl_parse_state *state)
+{
+ return texture_multisample(state) &&
+ state->EXT_shader_samples_identical_enable;
+}
+
+static bool
+texture_samples_identical_array(const _mesa_glsl_parse_state *state)
+{
+ return texture_multisample_array(state) &&
+ state->EXT_shader_samples_identical_enable;
}
static bool
return state->has_atomic_counters();
}
+static bool
+shader_clock(const _mesa_glsl_parse_state *state)
+{
+ return state->ARB_shader_clock_enable;
+}
+
+static bool
+shader_storage_buffer_object(const _mesa_glsl_parse_state *state)
+{
+ return state->has_shader_storage_buffer_objects();
+}
+
static bool
shader_trinary_minmax(const _mesa_glsl_parse_state *state)
{
static bool
shader_image_load_store(const _mesa_glsl_parse_state *state)
+{
+ return (state->is_version(420, 310) ||
+ state->ARB_shader_image_load_store_enable);
+}
+
+static bool
+shader_image_atomic(const _mesa_glsl_parse_state *state)
{
return (state->is_version(420, 0) ||
state->ARB_shader_image_load_store_enable);
}
+static bool
+shader_image_size(const _mesa_glsl_parse_state *state)
+{
+ return state->is_version(430, 310) ||
+ state->ARB_shader_image_size_enable;
+}
+
+static bool
+shader_samples(const _mesa_glsl_parse_state *state)
+{
+ return state->is_version(450, 0) ||
+ state->ARB_shader_texture_image_samples_enable;
+}
+
static bool
gs_streams(const _mesa_glsl_parse_state *state)
{
return state->has_double();
}
+static bool
+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)
{
- return state->stage == MESA_SHADER_COMPUTE ||
+ return compute_shader(state) ||
state->stage == MESA_SHADER_TESS_CTRL;
}
/** Create a new function and add the given signatures. */
void add_function(const char *name, ...);
+ typedef ir_function_signature *(builtin_builder::*image_prototype_ctr)(const glsl_type *image_type,
+ unsigned num_arguments,
+ unsigned flags);
+
enum image_function_flags {
IMAGE_FUNCTION_EMIT_STUB = (1 << 0),
IMAGE_FUNCTION_RETURNS_VOID = (1 << 1),
IMAGE_FUNCTION_HAS_VECTOR_DATA_TYPE = (1 << 2),
IMAGE_FUNCTION_SUPPORTS_FLOAT_DATA_TYPE = (1 << 3),
IMAGE_FUNCTION_READ_ONLY = (1 << 4),
- IMAGE_FUNCTION_WRITE_ONLY = (1 << 5)
+ IMAGE_FUNCTION_WRITE_ONLY = (1 << 5),
+ IMAGE_FUNCTION_AVAIL_ATOMIC = (1 << 6),
+ IMAGE_FUNCTION_MS_ONLY = (1 << 7),
};
/**
*/
void add_image_function(const char *name,
const char *intrinsic_name,
+ image_prototype_ctr prototype,
unsigned num_arguments,
unsigned flags);
ir_expression_operation opcode,
const glsl_type *return_type,
const glsl_type *param_type);
- ir_function_signature *binop(ir_expression_operation opcode,
- builtin_available_predicate avail,
+ ir_function_signature *binop(builtin_available_predicate avail,
+ ir_expression_operation opcode,
const glsl_type *return_type,
const glsl_type *param0_type,
const glsl_type *param1_type);
B1(any);
B1(all);
B1(not);
- B2(textureSize);
- ir_function_signature *_textureSize(builtin_available_predicate avail,
- const glsl_type *return_type,
- const glsl_type *sampler_type);
+ BA2(textureSize);
+ B1(textureSamples);
/** Flags to _texture() */
#define TEX_PROJECT 1
const glsl_type *stream_type);
B0(barrier)
- B2(textureQueryLod);
+ BA2(textureQueryLod);
B1(textureQueryLevels);
+ BA2(textureSamplesIdentical);
B1(dFdx);
B1(dFdy);
B1(fwidth);
B1(interpolateAtOffset)
B1(interpolateAtSample)
- ir_function_signature *_atomic_intrinsic(builtin_available_predicate avail);
- ir_function_signature *_atomic_op(const char *intrinsic,
- builtin_available_predicate avail);
+ ir_function_signature *_atomic_counter_intrinsic(builtin_available_predicate avail);
+ ir_function_signature *_atomic_counter_op(const char *intrinsic,
+ builtin_available_predicate avail);
+
+ ir_function_signature *_atomic_intrinsic2(builtin_available_predicate avail,
+ const glsl_type *type);
+ ir_function_signature *_atomic_op2(const char *intrinsic,
+ builtin_available_predicate avail,
+ const glsl_type *type);
+ ir_function_signature *_atomic_intrinsic3(builtin_available_predicate avail,
+ const glsl_type *type);
+ ir_function_signature *_atomic_op3(const char *intrinsic,
+ builtin_available_predicate avail,
+ const glsl_type *type);
B1(min3)
B1(max3)
B1(mid3)
ir_function_signature *_image_prototype(const glsl_type *image_type,
- const char *intrinsic_name,
unsigned num_arguments,
unsigned flags);
- ir_function_signature *_image(const glsl_type *image_type,
+ ir_function_signature *_image_size_prototype(const glsl_type *image_type,
+ unsigned num_arguments,
+ unsigned flags);
+ ir_function_signature *_image_samples_prototype(const glsl_type *image_type,
+ unsigned num_arguments,
+ unsigned flags);
+ ir_function_signature *_image(image_prototype_ctr prototype,
+ const glsl_type *image_type,
const char *intrinsic_name,
unsigned num_arguments,
unsigned flags);
ir_function_signature *_memory_barrier_intrinsic(
builtin_available_predicate avail);
- ir_function_signature *_memory_barrier(
- builtin_available_predicate avail);
+ ir_function_signature *_memory_barrier(const char *intrinsic_name,
+ builtin_available_predicate avail);
+
+ ir_function_signature *_shader_clock_intrinsic(builtin_available_predicate avail,
+ const glsl_type *type);
+ ir_function_signature *_shader_clock(builtin_available_predicate avail,
+ const glsl_type *type);
#undef B0
#undef B1
builtin_builder::create_intrinsics()
{
add_function("__intrinsic_atomic_read",
- _atomic_intrinsic(shader_atomic_counters),
+ _atomic_counter_intrinsic(shader_atomic_counters),
NULL);
add_function("__intrinsic_atomic_increment",
- _atomic_intrinsic(shader_atomic_counters),
+ _atomic_counter_intrinsic(shader_atomic_counters),
NULL);
add_function("__intrinsic_atomic_predecrement",
- _atomic_intrinsic(shader_atomic_counters),
+ _atomic_counter_intrinsic(shader_atomic_counters),
+ NULL);
+
+ add_function("__intrinsic_atomic_add",
+ _atomic_intrinsic2(buffer_atomics_supported,
+ glsl_type::uint_type),
+ _atomic_intrinsic2(buffer_atomics_supported,
+ glsl_type::int_type),
+ NULL);
+ add_function("__intrinsic_atomic_min",
+ _atomic_intrinsic2(buffer_atomics_supported,
+ glsl_type::uint_type),
+ _atomic_intrinsic2(buffer_atomics_supported,
+ glsl_type::int_type),
+ NULL);
+ add_function("__intrinsic_atomic_max",
+ _atomic_intrinsic2(buffer_atomics_supported,
+ glsl_type::uint_type),
+ _atomic_intrinsic2(buffer_atomics_supported,
+ glsl_type::int_type),
+ NULL);
+ add_function("__intrinsic_atomic_and",
+ _atomic_intrinsic2(buffer_atomics_supported,
+ glsl_type::uint_type),
+ _atomic_intrinsic2(buffer_atomics_supported,
+ glsl_type::int_type),
+ NULL);
+ add_function("__intrinsic_atomic_or",
+ _atomic_intrinsic2(buffer_atomics_supported,
+ glsl_type::uint_type),
+ _atomic_intrinsic2(buffer_atomics_supported,
+ glsl_type::int_type),
+ NULL);
+ add_function("__intrinsic_atomic_xor",
+ _atomic_intrinsic2(buffer_atomics_supported,
+ glsl_type::uint_type),
+ _atomic_intrinsic2(buffer_atomics_supported,
+ glsl_type::int_type),
+ NULL);
+ add_function("__intrinsic_atomic_exchange",
+ _atomic_intrinsic2(buffer_atomics_supported,
+ glsl_type::uint_type),
+ _atomic_intrinsic2(buffer_atomics_supported,
+ glsl_type::int_type),
+ NULL);
+ add_function("__intrinsic_atomic_comp_swap",
+ _atomic_intrinsic3(buffer_atomics_supported,
+ glsl_type::uint_type),
+ _atomic_intrinsic3(buffer_atomics_supported,
+ glsl_type::int_type),
NULL);
add_image_functions(false);
add_function("__intrinsic_memory_barrier",
_memory_barrier_intrinsic(shader_image_load_store),
NULL);
+ add_function("__intrinsic_group_memory_barrier",
+ _memory_barrier_intrinsic(compute_shader),
+ NULL);
+ add_function("__intrinsic_memory_barrier_atomic_counter",
+ _memory_barrier_intrinsic(compute_shader),
+ NULL);
+ add_function("__intrinsic_memory_barrier_buffer",
+ _memory_barrier_intrinsic(compute_shader),
+ NULL);
+ add_function("__intrinsic_memory_barrier_image",
+ _memory_barrier_intrinsic(compute_shader),
+ NULL);
+ add_function("__intrinsic_memory_barrier_shared",
+ _memory_barrier_intrinsic(compute_shader),
+ NULL);
+
+ add_function("__intrinsic_shader_clock",
+ _shader_clock_intrinsic(shader_clock,
+ glsl_type::uvec2_type),
+ NULL);
}
/**
_smoothstep(fp64, glsl_type::dvec3_type, glsl_type::dvec3_type),
_smoothstep(fp64, glsl_type::dvec4_type, glsl_type::dvec4_type),
NULL);
-
+
FD130(isnan)
FD130(isinf)
FD(distance)
FD(dot)
- add_function("cross", _cross(always_available, glsl_type::vec3_type),
+ add_function("cross", _cross(always_available, glsl_type::vec3_type),
_cross(fp64, glsl_type::dvec3_type), NULL);
FD(normalize)
_textureSize(texture_multisample_array, glsl_type::ivec3_type, glsl_type::usampler2DMSArray_type),
NULL);
+ add_function("textureSamples",
+ _textureSamples(glsl_type::sampler2DMS_type),
+ _textureSamples(glsl_type::isampler2DMS_type),
+ _textureSamples(glsl_type::usampler2DMS_type),
+
+ _textureSamples(glsl_type::sampler2DMSArray_type),
+ _textureSamples(glsl_type::isampler2DMSArray_type),
+ _textureSamples(glsl_type::usampler2DMSArray_type),
+ NULL);
+
add_function("texture",
_texture(ir_tex, v130, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::float_type),
_texture(ir_tex, v130, glsl_type::ivec4_type, glsl_type::isampler1D_type, glsl_type::float_type),
add_function("barrier", _barrier(), NULL);
add_function("textureQueryLOD",
- _textureQueryLod(glsl_type::sampler1D_type, glsl_type::float_type),
- _textureQueryLod(glsl_type::isampler1D_type, glsl_type::float_type),
- _textureQueryLod(glsl_type::usampler1D_type, glsl_type::float_type),
-
- _textureQueryLod(glsl_type::sampler2D_type, glsl_type::vec2_type),
- _textureQueryLod(glsl_type::isampler2D_type, glsl_type::vec2_type),
- _textureQueryLod(glsl_type::usampler2D_type, glsl_type::vec2_type),
-
- _textureQueryLod(glsl_type::sampler3D_type, glsl_type::vec3_type),
- _textureQueryLod(glsl_type::isampler3D_type, glsl_type::vec3_type),
- _textureQueryLod(glsl_type::usampler3D_type, glsl_type::vec3_type),
-
- _textureQueryLod(glsl_type::samplerCube_type, glsl_type::vec3_type),
- _textureQueryLod(glsl_type::isamplerCube_type, glsl_type::vec3_type),
- _textureQueryLod(glsl_type::usamplerCube_type, glsl_type::vec3_type),
-
- _textureQueryLod(glsl_type::sampler1DArray_type, glsl_type::float_type),
- _textureQueryLod(glsl_type::isampler1DArray_type, glsl_type::float_type),
- _textureQueryLod(glsl_type::usampler1DArray_type, glsl_type::float_type),
-
- _textureQueryLod(glsl_type::sampler2DArray_type, glsl_type::vec2_type),
- _textureQueryLod(glsl_type::isampler2DArray_type, glsl_type::vec2_type),
- _textureQueryLod(glsl_type::usampler2DArray_type, glsl_type::vec2_type),
-
- _textureQueryLod(glsl_type::samplerCubeArray_type, glsl_type::vec3_type),
- _textureQueryLod(glsl_type::isamplerCubeArray_type, glsl_type::vec3_type),
- _textureQueryLod(glsl_type::usamplerCubeArray_type, glsl_type::vec3_type),
+ _textureQueryLod(texture_query_lod, glsl_type::sampler1D_type, glsl_type::float_type),
+ _textureQueryLod(texture_query_lod, glsl_type::isampler1D_type, glsl_type::float_type),
+ _textureQueryLod(texture_query_lod, glsl_type::usampler1D_type, glsl_type::float_type),
+
+ _textureQueryLod(texture_query_lod, glsl_type::sampler2D_type, glsl_type::vec2_type),
+ _textureQueryLod(texture_query_lod, glsl_type::isampler2D_type, glsl_type::vec2_type),
+ _textureQueryLod(texture_query_lod, glsl_type::usampler2D_type, glsl_type::vec2_type),
+
+ _textureQueryLod(texture_query_lod, glsl_type::sampler3D_type, glsl_type::vec3_type),
+ _textureQueryLod(texture_query_lod, glsl_type::isampler3D_type, glsl_type::vec3_type),
+ _textureQueryLod(texture_query_lod, glsl_type::usampler3D_type, glsl_type::vec3_type),
+
+ _textureQueryLod(texture_query_lod, glsl_type::samplerCube_type, glsl_type::vec3_type),
+ _textureQueryLod(texture_query_lod, glsl_type::isamplerCube_type, glsl_type::vec3_type),
+ _textureQueryLod(texture_query_lod, glsl_type::usamplerCube_type, glsl_type::vec3_type),
+
+ _textureQueryLod(texture_query_lod, glsl_type::sampler1DArray_type, glsl_type::float_type),
+ _textureQueryLod(texture_query_lod, glsl_type::isampler1DArray_type, glsl_type::float_type),
+ _textureQueryLod(texture_query_lod, glsl_type::usampler1DArray_type, glsl_type::float_type),
+
+ _textureQueryLod(texture_query_lod, glsl_type::sampler2DArray_type, glsl_type::vec2_type),
+ _textureQueryLod(texture_query_lod, glsl_type::isampler2DArray_type, glsl_type::vec2_type),
+ _textureQueryLod(texture_query_lod, glsl_type::usampler2DArray_type, glsl_type::vec2_type),
+
+ _textureQueryLod(texture_query_lod, glsl_type::samplerCubeArray_type, glsl_type::vec3_type),
+ _textureQueryLod(texture_query_lod, glsl_type::isamplerCubeArray_type, glsl_type::vec3_type),
+ _textureQueryLod(texture_query_lod, glsl_type::usamplerCubeArray_type, glsl_type::vec3_type),
+
+ _textureQueryLod(texture_query_lod, glsl_type::sampler1DShadow_type, glsl_type::float_type),
+ _textureQueryLod(texture_query_lod, glsl_type::sampler2DShadow_type, glsl_type::vec2_type),
+ _textureQueryLod(texture_query_lod, glsl_type::samplerCubeShadow_type, glsl_type::vec3_type),
+ _textureQueryLod(texture_query_lod, glsl_type::sampler1DArrayShadow_type, glsl_type::float_type),
+ _textureQueryLod(texture_query_lod, glsl_type::sampler2DArrayShadow_type, glsl_type::vec2_type),
+ _textureQueryLod(texture_query_lod, glsl_type::samplerCubeArrayShadow_type, glsl_type::vec3_type),
+ NULL);
- _textureQueryLod(glsl_type::sampler1DShadow_type, glsl_type::float_type),
- _textureQueryLod(glsl_type::sampler2DShadow_type, glsl_type::vec2_type),
- _textureQueryLod(glsl_type::samplerCubeShadow_type, glsl_type::vec3_type),
- _textureQueryLod(glsl_type::sampler1DArrayShadow_type, glsl_type::float_type),
- _textureQueryLod(glsl_type::sampler2DArrayShadow_type, glsl_type::vec2_type),
- _textureQueryLod(glsl_type::samplerCubeArrayShadow_type, glsl_type::vec3_type),
+ add_function("textureQueryLod",
+ _textureQueryLod(v400_fs_only, glsl_type::sampler1D_type, glsl_type::float_type),
+ _textureQueryLod(v400_fs_only, glsl_type::isampler1D_type, glsl_type::float_type),
+ _textureQueryLod(v400_fs_only, glsl_type::usampler1D_type, glsl_type::float_type),
+
+ _textureQueryLod(v400_fs_only, glsl_type::sampler2D_type, glsl_type::vec2_type),
+ _textureQueryLod(v400_fs_only, glsl_type::isampler2D_type, glsl_type::vec2_type),
+ _textureQueryLod(v400_fs_only, glsl_type::usampler2D_type, glsl_type::vec2_type),
+
+ _textureQueryLod(v400_fs_only, glsl_type::sampler3D_type, glsl_type::vec3_type),
+ _textureQueryLod(v400_fs_only, glsl_type::isampler3D_type, glsl_type::vec3_type),
+ _textureQueryLod(v400_fs_only, glsl_type::usampler3D_type, glsl_type::vec3_type),
+
+ _textureQueryLod(v400_fs_only, glsl_type::samplerCube_type, glsl_type::vec3_type),
+ _textureQueryLod(v400_fs_only, glsl_type::isamplerCube_type, glsl_type::vec3_type),
+ _textureQueryLod(v400_fs_only, glsl_type::usamplerCube_type, glsl_type::vec3_type),
+
+ _textureQueryLod(v400_fs_only, glsl_type::sampler1DArray_type, glsl_type::float_type),
+ _textureQueryLod(v400_fs_only, glsl_type::isampler1DArray_type, glsl_type::float_type),
+ _textureQueryLod(v400_fs_only, glsl_type::usampler1DArray_type, glsl_type::float_type),
+
+ _textureQueryLod(v400_fs_only, glsl_type::sampler2DArray_type, glsl_type::vec2_type),
+ _textureQueryLod(v400_fs_only, glsl_type::isampler2DArray_type, glsl_type::vec2_type),
+ _textureQueryLod(v400_fs_only, glsl_type::usampler2DArray_type, glsl_type::vec2_type),
+
+ _textureQueryLod(v400_fs_only, glsl_type::samplerCubeArray_type, glsl_type::vec3_type),
+ _textureQueryLod(v400_fs_only, glsl_type::isamplerCubeArray_type, glsl_type::vec3_type),
+ _textureQueryLod(v400_fs_only, glsl_type::usamplerCubeArray_type, glsl_type::vec3_type),
+
+ _textureQueryLod(v400_fs_only, glsl_type::sampler1DShadow_type, glsl_type::float_type),
+ _textureQueryLod(v400_fs_only, glsl_type::sampler2DShadow_type, glsl_type::vec2_type),
+ _textureQueryLod(v400_fs_only, glsl_type::samplerCubeShadow_type, glsl_type::vec3_type),
+ _textureQueryLod(v400_fs_only, glsl_type::sampler1DArrayShadow_type, glsl_type::float_type),
+ _textureQueryLod(v400_fs_only, glsl_type::sampler2DArrayShadow_type, glsl_type::vec2_type),
+ _textureQueryLod(v400_fs_only, glsl_type::samplerCubeArrayShadow_type, glsl_type::vec3_type),
NULL);
add_function("textureQueryLevels",
NULL);
+ add_function("textureSamplesIdenticalEXT",
+ _textureSamplesIdentical(texture_samples_identical, glsl_type::sampler2DMS_type, glsl_type::ivec2_type),
+ _textureSamplesIdentical(texture_samples_identical, glsl_type::isampler2DMS_type, glsl_type::ivec2_type),
+ _textureSamplesIdentical(texture_samples_identical, glsl_type::usampler2DMS_type, glsl_type::ivec2_type),
+
+ _textureSamplesIdentical(texture_samples_identical_array, glsl_type::sampler2DMSArray_type, glsl_type::ivec3_type),
+ _textureSamplesIdentical(texture_samples_identical_array, glsl_type::isampler2DMSArray_type, glsl_type::ivec3_type),
+ _textureSamplesIdentical(texture_samples_identical_array, glsl_type::usampler2DMSArray_type, glsl_type::ivec3_type),
+ NULL);
+
add_function("texture1D",
_texture(ir_tex, v110, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::float_type),
_texture(ir_txb, v110_fs_only, glsl_type::vec4_type, glsl_type::sampler1D_type, glsl_type::float_type),
NULL);
add_function("atomicCounter",
- _atomic_op("__intrinsic_atomic_read",
- shader_atomic_counters),
+ _atomic_counter_op("__intrinsic_atomic_read",
+ shader_atomic_counters),
NULL);
add_function("atomicCounterIncrement",
- _atomic_op("__intrinsic_atomic_increment",
- shader_atomic_counters),
+ _atomic_counter_op("__intrinsic_atomic_increment",
+ shader_atomic_counters),
NULL);
add_function("atomicCounterDecrement",
- _atomic_op("__intrinsic_atomic_predecrement",
- shader_atomic_counters),
+ _atomic_counter_op("__intrinsic_atomic_predecrement",
+ shader_atomic_counters),
+ NULL);
+
+ add_function("atomicAdd",
+ _atomic_op2("__intrinsic_atomic_add",
+ buffer_atomics_supported,
+ glsl_type::uint_type),
+ _atomic_op2("__intrinsic_atomic_add",
+ buffer_atomics_supported,
+ glsl_type::int_type),
+ NULL);
+ add_function("atomicMin",
+ _atomic_op2("__intrinsic_atomic_min",
+ buffer_atomics_supported,
+ glsl_type::uint_type),
+ _atomic_op2("__intrinsic_atomic_min",
+ buffer_atomics_supported,
+ glsl_type::int_type),
+ NULL);
+ add_function("atomicMax",
+ _atomic_op2("__intrinsic_atomic_max",
+ buffer_atomics_supported,
+ glsl_type::uint_type),
+ _atomic_op2("__intrinsic_atomic_max",
+ buffer_atomics_supported,
+ glsl_type::int_type),
+ NULL);
+ add_function("atomicAnd",
+ _atomic_op2("__intrinsic_atomic_and",
+ buffer_atomics_supported,
+ glsl_type::uint_type),
+ _atomic_op2("__intrinsic_atomic_and",
+ buffer_atomics_supported,
+ glsl_type::int_type),
+ NULL);
+ add_function("atomicOr",
+ _atomic_op2("__intrinsic_atomic_or",
+ buffer_atomics_supported,
+ glsl_type::uint_type),
+ _atomic_op2("__intrinsic_atomic_or",
+ buffer_atomics_supported,
+ glsl_type::int_type),
+ NULL);
+ add_function("atomicXor",
+ _atomic_op2("__intrinsic_atomic_xor",
+ buffer_atomics_supported,
+ glsl_type::uint_type),
+ _atomic_op2("__intrinsic_atomic_xor",
+ buffer_atomics_supported,
+ glsl_type::int_type),
+ NULL);
+ add_function("atomicExchange",
+ _atomic_op2("__intrinsic_atomic_exchange",
+ buffer_atomics_supported,
+ glsl_type::uint_type),
+ _atomic_op2("__intrinsic_atomic_exchange",
+ buffer_atomics_supported,
+ glsl_type::int_type),
+ NULL);
+ add_function("atomicCompSwap",
+ _atomic_op3("__intrinsic_atomic_comp_swap",
+ buffer_atomics_supported,
+ glsl_type::uint_type),
+ _atomic_op3("__intrinsic_atomic_comp_swap",
+ buffer_atomics_supported,
+ glsl_type::int_type),
NULL);
add_function("min3",
add_image_functions(true);
add_function("memoryBarrier",
- _memory_barrier(shader_image_load_store),
+ _memory_barrier("__intrinsic_memory_barrier",
+ shader_image_load_store),
+ NULL);
+ add_function("groupMemoryBarrier",
+ _memory_barrier("__intrinsic_group_memory_barrier",
+ compute_shader),
+ NULL);
+ add_function("memoryBarrierAtomicCounter",
+ _memory_barrier("__intrinsic_memory_barrier_atomic_counter",
+ compute_shader),
+ NULL);
+ add_function("memoryBarrierBuffer",
+ _memory_barrier("__intrinsic_memory_barrier_buffer",
+ compute_shader),
+ NULL);
+ add_function("memoryBarrierImage",
+ _memory_barrier("__intrinsic_memory_barrier_image",
+ compute_shader),
+ NULL);
+ add_function("memoryBarrierShared",
+ _memory_barrier("__intrinsic_memory_barrier_shared",
+ compute_shader),
+ NULL);
+
+ add_function("clock2x32ARB",
+ _shader_clock(shader_clock,
+ glsl_type::uvec2_type),
NULL);
#undef F
void
builtin_builder::add_image_function(const char *name,
const char *intrinsic_name,
+ image_prototype_ctr prototype,
unsigned num_arguments,
unsigned flags)
{
glsl_type::uimage2DMS_type,
glsl_type::uimage2DMSArray_type
};
+
ir_function *f = new(mem_ctx) ir_function(name);
for (unsigned i = 0; i < ARRAY_SIZE(types); ++i) {
- if (types[i]->sampler_type != GLSL_TYPE_FLOAT ||
- (flags & IMAGE_FUNCTION_SUPPORTS_FLOAT_DATA_TYPE))
- f->add_signature(_image(types[i], intrinsic_name,
+ if ((types[i]->sampler_type != GLSL_TYPE_FLOAT ||
+ (flags & IMAGE_FUNCTION_SUPPORTS_FLOAT_DATA_TYPE)) &&
+ (types[i]->sampler_dimensionality == GLSL_SAMPLER_DIM_MS ||
+ !(flags & IMAGE_FUNCTION_MS_ONLY)))
+ f->add_signature(_image(prototype, types[i], intrinsic_name,
num_arguments, flags));
}
const unsigned flags = (glsl ? IMAGE_FUNCTION_EMIT_STUB : 0);
add_image_function(glsl ? "imageLoad" : "__intrinsic_image_load",
- "__intrinsic_image_load", 0,
- (flags | IMAGE_FUNCTION_HAS_VECTOR_DATA_TYPE |
+ "__intrinsic_image_load",
+ &builtin_builder::_image_prototype, 0,
+ (flags | IMAGE_FUNCTION_HAS_VECTOR_DATA_TYPE |
IMAGE_FUNCTION_SUPPORTS_FLOAT_DATA_TYPE |
IMAGE_FUNCTION_READ_ONLY));
add_image_function(glsl ? "imageStore" : "__intrinsic_image_store",
- "__intrinsic_image_store", 1,
+ "__intrinsic_image_store",
+ &builtin_builder::_image_prototype, 1,
(flags | IMAGE_FUNCTION_RETURNS_VOID |
IMAGE_FUNCTION_HAS_VECTOR_DATA_TYPE |
IMAGE_FUNCTION_SUPPORTS_FLOAT_DATA_TYPE |
IMAGE_FUNCTION_WRITE_ONLY));
+ const unsigned atom_flags = flags | IMAGE_FUNCTION_AVAIL_ATOMIC;
+
add_image_function(glsl ? "imageAtomicAdd" : "__intrinsic_image_atomic_add",
- "__intrinsic_image_atomic_add", 1, flags);
+ "__intrinsic_image_atomic_add",
+ &builtin_builder::_image_prototype, 1, atom_flags);
add_image_function(glsl ? "imageAtomicMin" : "__intrinsic_image_atomic_min",
- "__intrinsic_image_atomic_min", 1, flags);
+ "__intrinsic_image_atomic_min",
+ &builtin_builder::_image_prototype, 1, atom_flags);
add_image_function(glsl ? "imageAtomicMax" : "__intrinsic_image_atomic_max",
- "__intrinsic_image_atomic_max", 1, flags);
+ "__intrinsic_image_atomic_max",
+ &builtin_builder::_image_prototype, 1, atom_flags);
add_image_function(glsl ? "imageAtomicAnd" : "__intrinsic_image_atomic_and",
- "__intrinsic_image_atomic_and", 1, flags);
+ "__intrinsic_image_atomic_and",
+ &builtin_builder::_image_prototype, 1, atom_flags);
add_image_function(glsl ? "imageAtomicOr" : "__intrinsic_image_atomic_or",
- "__intrinsic_image_atomic_or", 1, flags);
+ "__intrinsic_image_atomic_or",
+ &builtin_builder::_image_prototype, 1, atom_flags);
add_image_function(glsl ? "imageAtomicXor" : "__intrinsic_image_atomic_xor",
- "__intrinsic_image_atomic_xor", 1, flags);
+ "__intrinsic_image_atomic_xor",
+ &builtin_builder::_image_prototype, 1, atom_flags);
add_image_function((glsl ? "imageAtomicExchange" :
"__intrinsic_image_atomic_exchange"),
- "__intrinsic_image_atomic_exchange", 1, flags);
+ "__intrinsic_image_atomic_exchange",
+ &builtin_builder::_image_prototype, 1, atom_flags);
add_image_function((glsl ? "imageAtomicCompSwap" :
"__intrinsic_image_atomic_comp_swap"),
- "__intrinsic_image_atomic_comp_swap", 2, flags);
+ "__intrinsic_image_atomic_comp_swap",
+ &builtin_builder::_image_prototype, 2, atom_flags);
+
+ add_image_function(glsl ? "imageSize" : "__intrinsic_image_size",
+ "__intrinsic_image_size",
+ &builtin_builder::_image_size_prototype, 1,
+ flags | IMAGE_FUNCTION_SUPPORTS_FLOAT_DATA_TYPE);
+
+ add_image_function(glsl ? "imageSamples" : "__intrinsic_image_samples",
+ "__intrinsic_image_samples",
+ &builtin_builder::_image_samples_prototype, 1,
+ flags | IMAGE_FUNCTION_SUPPORTS_FLOAT_DATA_TYPE |
+ IMAGE_FUNCTION_MS_ONLY);
}
ir_variable *
}
ir_function_signature *
-builtin_builder::binop(ir_expression_operation opcode,
- builtin_available_predicate avail,
+builtin_builder::binop(builtin_available_predicate avail,
+ ir_expression_operation opcode,
const glsl_type *return_type,
const glsl_type *param0_type,
const glsl_type *param1_type)
ir_function_signature *
builtin_builder::_pow(const glsl_type *type)
{
- return binop(ir_binop_pow, always_available, type, type, type);
+ return binop(always_available, ir_binop_pow, type, type, type);
}
UNOP(exp, ir_unop_exp, always_available)
ir_function_signature *
builtin_builder::_mod(const glsl_type *x_type, const glsl_type *y_type)
{
- return binop(ir_binop_mod, always_available, x_type, x_type, y_type);
+ return binop(always_available, ir_binop_mod, x_type, x_type, y_type);
}
ir_function_signature *
builtin_builder::_min(builtin_available_predicate avail,
const glsl_type *x_type, const glsl_type *y_type)
{
- return binop(ir_binop_min, avail, x_type, x_type, y_type);
+ return binop(avail, ir_binop_min, x_type, x_type, y_type);
}
ir_function_signature *
builtin_builder::_max(builtin_available_predicate avail,
const glsl_type *x_type, const glsl_type *y_type)
{
- return binop(ir_binop_max, avail, x_type, x_type, y_type);
+ return binop(avail, ir_binop_max, x_type, x_type, y_type);
}
ir_function_signature *
ir_constant_data infinities;
for (int i = 0; i < type->vector_elements; i++) {
- infinities.f[i] = INFINITY;
+ switch (type->base_type) {
+ case GLSL_TYPE_FLOAT:
+ infinities.f[i] = INFINITY;
+ break;
+ case GLSL_TYPE_DOUBLE:
+ infinities.d[i] = INFINITY;
+ break;
+ default:
+ unreachable("unknown type");
+ }
}
body.emit(ret(equal(abs(x), imm(type, infinities))));
builtin_builder::_dot(builtin_available_predicate avail, const glsl_type *type)
{
if (type->vector_elements == 1)
- return binop(ir_binop_mul, avail, type, type, type);
+ return binop(avail, ir_binop_mul, type, type, type);
- return binop(ir_binop_dot, avail,
+ return binop(avail, ir_binop_dot,
type->get_base_type(), type, type);
}
builtin_builder::_lessThan(builtin_available_predicate avail,
const glsl_type *type)
{
- return binop(ir_binop_less, avail,
+ return binop(avail, ir_binop_less,
glsl_type::bvec(type->vector_elements), type, type);
}
builtin_builder::_lessThanEqual(builtin_available_predicate avail,
const glsl_type *type)
{
- return binop(ir_binop_lequal, avail,
+ return binop(avail, ir_binop_lequal,
glsl_type::bvec(type->vector_elements), type, type);
}
builtin_builder::_greaterThan(builtin_available_predicate avail,
const glsl_type *type)
{
- return binop(ir_binop_greater, avail,
+ return binop(avail, ir_binop_greater,
glsl_type::bvec(type->vector_elements), type, type);
}
builtin_builder::_greaterThanEqual(builtin_available_predicate avail,
const glsl_type *type)
{
- return binop(ir_binop_gequal, avail,
+ return binop(avail, ir_binop_gequal,
glsl_type::bvec(type->vector_elements), type, type);
}
builtin_builder::_equal(builtin_available_predicate avail,
const glsl_type *type)
{
- return binop(ir_binop_equal, avail,
+ return binop(avail, ir_binop_equal,
glsl_type::bvec(type->vector_elements), type, type);
}
builtin_builder::_notEqual(builtin_available_predicate avail,
const glsl_type *type)
{
- return binop(ir_binop_nequal, avail,
+ return binop(avail, ir_binop_nequal,
glsl_type::bvec(type->vector_elements), type, type);
}
return sig;
}
+ir_function_signature *
+builtin_builder::_textureSamples(const glsl_type *sampler_type)
+{
+ ir_variable *s = in_var(sampler_type, "sampler");
+ MAKE_SIG(glsl_type::int_type, shader_samples, 1, s);
+
+ ir_texture *tex = new(mem_ctx) ir_texture(ir_texture_samples);
+ tex->set_sampler(new(mem_ctx) ir_dereference_variable(s), glsl_type::int_type);
+ body.emit(ret(tex));
+
+ return sig;
+}
+
ir_function_signature *
builtin_builder::_texture(ir_texture_opcode opcode,
builtin_available_predicate avail,
}
ir_function_signature *
-builtin_builder::_textureQueryLod(const glsl_type *sampler_type,
+builtin_builder::_textureQueryLod(builtin_available_predicate avail,
+ const glsl_type *sampler_type,
const glsl_type *coord_type)
{
ir_variable *s = in_var(sampler_type, "sampler");
ir_variable *coord = in_var(coord_type, "coord");
/* The sampler and coordinate always exist; add optional parameters later. */
- MAKE_SIG(glsl_type::vec2_type, texture_query_lod, 2, s, coord);
+ MAKE_SIG(glsl_type::vec2_type, avail, 2, s, coord);
ir_texture *tex = new(mem_ctx) ir_texture(ir_lod);
tex->coordinate = var_ref(coord);
return sig;
}
+ir_function_signature *
+builtin_builder::_textureSamplesIdentical(builtin_available_predicate avail,
+ const glsl_type *sampler_type,
+ const glsl_type *coord_type)
+{
+ ir_variable *s = in_var(sampler_type, "sampler");
+ ir_variable *P = in_var(coord_type, "P");
+ const glsl_type *return_type = glsl_type::bool_type;
+ MAKE_SIG(return_type, avail, 2, s, P);
+
+ ir_texture *tex = new(mem_ctx) ir_texture(ir_samples_identical);
+ tex->coordinate = var_ref(P);
+ tex->set_sampler(var_ref(s), return_type);
+
+ body.emit(ret(tex));
+
+ return sig;
+}
+
UNOP(dFdx, ir_unop_dFdx, fs_oes_derivatives)
UNOP(dFdxCoarse, ir_unop_dFdx_coarse, fs_derivative_control)
UNOP(dFdxFine, ir_unop_dFdx_fine, fs_derivative_control)
ir_function_signature *
builtin_builder::_ldexp(const glsl_type *x_type, const glsl_type *exp_type)
{
- return binop(ir_binop_ldexp, x_type->base_type == GLSL_TYPE_DOUBLE ? fp64 : gpu_shader5_or_es31, x_type, x_type, exp_type);
+ return binop(x_type->base_type == GLSL_TYPE_DOUBLE ? fp64 : gpu_shader5_or_es31,
+ ir_binop_ldexp, x_type, x_type, exp_type);
}
ir_function_signature *
}
ir_function_signature *
-builtin_builder::_atomic_intrinsic(builtin_available_predicate avail)
+builtin_builder::_atomic_counter_intrinsic(builtin_available_predicate avail)
{
ir_variable *counter = in_var(glsl_type::atomic_uint_type, "counter");
MAKE_INTRINSIC(glsl_type::uint_type, avail, 1, counter);
}
ir_function_signature *
-builtin_builder::_atomic_op(const char *intrinsic,
- builtin_available_predicate avail)
+builtin_builder::_atomic_intrinsic2(builtin_available_predicate avail,
+ const glsl_type *type)
+{
+ ir_variable *atomic = in_var(type, "atomic");
+ ir_variable *data = in_var(type, "data");
+ MAKE_INTRINSIC(type, avail, 2, atomic, data);
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_atomic_intrinsic3(builtin_available_predicate avail,
+ const glsl_type *type)
+{
+ ir_variable *atomic = in_var(type, "atomic");
+ ir_variable *data1 = in_var(type, "data1");
+ ir_variable *data2 = in_var(type, "data2");
+ MAKE_INTRINSIC(type, avail, 3, atomic, data1, data2);
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_atomic_counter_op(const char *intrinsic,
+ builtin_available_predicate avail)
{
ir_variable *counter = in_var(glsl_type::atomic_uint_type, "atomic_counter");
MAKE_SIG(glsl_type::uint_type, avail, 1, counter);
return sig;
}
+ir_function_signature *
+builtin_builder::_atomic_op2(const char *intrinsic,
+ builtin_available_predicate avail,
+ const glsl_type *type)
+{
+ ir_variable *atomic = in_var(type, "atomic_var");
+ ir_variable *data = in_var(type, "atomic_data");
+ MAKE_SIG(type, avail, 2, atomic, data);
+
+ ir_variable *retval = body.make_temp(type, "atomic_retval");
+ body.emit(call(shader->symbols->get_function(intrinsic), retval,
+ sig->parameters));
+ body.emit(ret(retval));
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_atomic_op3(const char *intrinsic,
+ builtin_available_predicate avail,
+ const glsl_type *type)
+{
+ ir_variable *atomic = in_var(type, "atomic_var");
+ ir_variable *data1 = in_var(type, "atomic_data1");
+ ir_variable *data2 = in_var(type, "atomic_data2");
+ MAKE_SIG(type, avail, 3, atomic, data1, data2);
+
+ ir_variable *retval = body.make_temp(type, "atomic_retval");
+ body.emit(call(shader->symbols->get_function(intrinsic), retval,
+ sig->parameters));
+ body.emit(ret(retval));
+ return sig;
+}
+
ir_function_signature *
builtin_builder::_min3(const glsl_type *type)
{
ir_function_signature *
builtin_builder::_image_prototype(const glsl_type *image_type,
- const char *intrinsic_name,
unsigned num_arguments,
unsigned flags)
{
ir_variable *coord = in_var(
glsl_type::ivec(image_type->coordinate_components()), "coord");
- ir_function_signature *sig = new_sig(
- ret_type, shader_image_load_store, 2, image, coord);
+ const builtin_available_predicate avail =
+ (flags & IMAGE_FUNCTION_AVAIL_ATOMIC ? shader_image_atomic :
+ shader_image_load_store);
+ ir_function_signature *sig = new_sig(ret_type, avail, 2, image, coord);
/* Sample index for multisample images. */
if (image_type->sampler_dimensionality == GLSL_SAMPLER_DIM_MS)
}
ir_function_signature *
-builtin_builder::_image(const glsl_type *image_type,
+builtin_builder::_image_size_prototype(const glsl_type *image_type,
+ unsigned /* num_arguments */,
+ unsigned /* flags */)
+{
+ const glsl_type *ret_type;
+ unsigned num_components = image_type->coordinate_components();
+
+ /* From the ARB_shader_image_size extension:
+ * "Cube images return the dimensions of one face."
+ */
+ if (image_type->sampler_dimensionality == GLSL_SAMPLER_DIM_CUBE &&
+ !image_type->sampler_array) {
+ num_components = 2;
+ }
+
+ /* FIXME: Add the highp precision qualifier for GLES 3.10 when it is
+ * supported by mesa.
+ */
+ ret_type = glsl_type::get_instance(GLSL_TYPE_INT, num_components, 1);
+
+ ir_variable *image = in_var(image_type, "image");
+ ir_function_signature *sig = new_sig(ret_type, shader_image_size, 1, image);
+
+ /* Set the maximal set of qualifiers allowed for this image
+ * built-in. Function calls with arguments having fewer
+ * qualifiers than present in the prototype are allowed by the
+ * spec, but not with more, i.e. this will make the compiler
+ * accept everything that needs to be accepted, and reject cases
+ * like loads from write-only or stores to read-only images.
+ */
+ image->data.image_read_only = true;
+ image->data.image_write_only = true;
+ image->data.image_coherent = true;
+ image->data.image_volatile = true;
+ image->data.image_restrict = true;
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_image_samples_prototype(const glsl_type *image_type,
+ unsigned /* num_arguments */,
+ unsigned /* flags */)
+{
+ ir_variable *image = in_var(image_type, "image");
+ ir_function_signature *sig =
+ new_sig(glsl_type::int_type, shader_samples, 1, image);
+
+ /* Set the maximal set of qualifiers allowed for this image
+ * built-in. Function calls with arguments having fewer
+ * qualifiers than present in the prototype are allowed by the
+ * spec, but not with more, i.e. this will make the compiler
+ * accept everything that needs to be accepted, and reject cases
+ * like loads from write-only or stores to read-only images.
+ */
+ image->data.image_read_only = true;
+ image->data.image_write_only = true;
+ image->data.image_coherent = true;
+ image->data.image_volatile = true;
+ image->data.image_restrict = true;
+
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_image(image_prototype_ctr prototype,
+ const glsl_type *image_type,
const char *intrinsic_name,
unsigned num_arguments,
unsigned flags)
{
- ir_function_signature *sig = _image_prototype(image_type, intrinsic_name,
- num_arguments, flags);
+ ir_function_signature *sig = (this->*prototype)(image_type,
+ num_arguments, flags);
if (flags & IMAGE_FUNCTION_EMIT_STUB) {
ir_factory body(&sig->body, mem_ctx);
}
ir_function_signature *
-builtin_builder::_memory_barrier(builtin_available_predicate avail)
+builtin_builder::_memory_barrier(const char *intrinsic_name,
+ builtin_available_predicate avail)
{
MAKE_SIG(glsl_type::void_type, avail, 0);
- body.emit(call(shader->symbols->get_function("__intrinsic_memory_barrier"),
+ body.emit(call(shader->symbols->get_function(intrinsic_name),
NULL, sig->parameters));
return sig;
}
+ir_function_signature *
+builtin_builder::_shader_clock_intrinsic(builtin_available_predicate avail,
+ const glsl_type *type)
+{
+ MAKE_INTRINSIC(type, avail, 0);
+ return sig;
+}
+
+ir_function_signature *
+builtin_builder::_shader_clock(builtin_available_predicate avail,
+ const glsl_type *type)
+{
+ MAKE_SIG(type, avail, 0);
+
+ ir_variable *retval = body.make_temp(type, "clock_retval");
+
+ body.emit(call(shader->symbols->get_function("__intrinsic_shader_clock"),
+ retval, sig->parameters));
+ body.emit(ret(retval));
+ return sig;
+}
+
/** @} */
/******************************************************************************/
}
ir_function *
-_mesa_glsl_find_builtin_function_by_name(_mesa_glsl_parse_state *state,
- const char *name)
+_mesa_glsl_find_builtin_function_by_name(const char *name)
{
ir_function *f;
mtx_lock(&builtins_lock);
return builtins.shader;
}
+
+/**
+ * Get the function signature for main from a shader
+ */
+ir_function_signature *
+_mesa_get_main_function_signature(gl_shader *sh)
+{
+ ir_function *const f = sh->symbols->get_function("main");
+ if (f != NULL) {
+ exec_list void_parameters;
+
+ /* Look for the 'void main()' signature and ensure that it's defined.
+ * This keeps the linker from accidentally pick a shader that just
+ * contains a prototype for main.
+ *
+ * We don't have to check for multiple definitions of main (in multiple
+ * shaders) because that would have already been caught above.
+ */
+ ir_function_signature *sig =
+ f->matching_signature(NULL, &void_parameters, false);
+ if ((sig != NULL) && sig->is_defined) {
+ return sig;
+ }
+ }
+
+ return NULL;
+}
+
/** @} */