From ea0a1f5beb22982a886ba862ba95f92c9e35165a Mon Sep 17 00:00:00 2001 From: Iago Toral Quiroga Date: Thu, 23 Apr 2015 11:21:54 +0200 Subject: [PATCH] glsl: Add atomic functions from ARB_shader_storage_buffer_object MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Reviewed-by: Kristian Høgsberg --- src/glsl/builtin_functions.cpp | 185 +++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) diff --git a/src/glsl/builtin_functions.cpp b/src/glsl/builtin_functions.cpp index ede9dd867df..f0f6be21b7d 100644 --- a/src/glsl/builtin_functions.cpp +++ b/src/glsl/builtin_functions.cpp @@ -400,6 +400,12 @@ shader_atomic_counters(const _mesa_glsl_parse_state *state) return state->has_atomic_counters(); } +static bool +shader_storage_buffer_object(const _mesa_glsl_parse_state *state) +{ + return state->ARB_shader_storage_buffer_object_enable; +} + static bool shader_trinary_minmax(const _mesa_glsl_parse_state *state) { @@ -741,6 +747,17 @@ private: ir_function_signature *_atomic_counter_op(const char *intrinsic, builtin_available_predicate avail); + ir_function_signature *_atomic_ssbo_intrinsic2(builtin_available_predicate avail, + const glsl_type *type); + ir_function_signature *_atomic_ssbo_op2(const char *intrinsic, + builtin_available_predicate avail, + const glsl_type *type); + ir_function_signature *_atomic_ssbo_intrinsic3(builtin_available_predicate avail, + const glsl_type *type); + ir_function_signature *_atomic_ssbo_op3(const char *intrinsic, + builtin_available_predicate avail, + const glsl_type *type); + B1(min3) B1(max3) B1(mid3) @@ -881,6 +898,55 @@ builtin_builder::create_intrinsics() _atomic_counter_intrinsic(shader_atomic_counters), NULL); + add_function("__intrinsic_ssbo_atomic_add", + _atomic_ssbo_intrinsic2(shader_storage_buffer_object, + glsl_type::uint_type), + _atomic_ssbo_intrinsic2(shader_storage_buffer_object, + glsl_type::int_type), + NULL); + add_function("__intrinsic_ssbo_atomic_min", + _atomic_ssbo_intrinsic2(shader_storage_buffer_object, + glsl_type::uint_type), + _atomic_ssbo_intrinsic2(shader_storage_buffer_object, + glsl_type::int_type), + NULL); + add_function("__intrinsic_ssbo_atomic_max", + _atomic_ssbo_intrinsic2(shader_storage_buffer_object, + glsl_type::uint_type), + _atomic_ssbo_intrinsic2(shader_storage_buffer_object, + glsl_type::int_type), + NULL); + add_function("__intrinsic_ssbo_atomic_and", + _atomic_ssbo_intrinsic2(shader_storage_buffer_object, + glsl_type::uint_type), + _atomic_ssbo_intrinsic2(shader_storage_buffer_object, + glsl_type::int_type), + NULL); + add_function("__intrinsic_ssbo_atomic_or", + _atomic_ssbo_intrinsic2(shader_storage_buffer_object, + glsl_type::uint_type), + _atomic_ssbo_intrinsic2(shader_storage_buffer_object, + glsl_type::int_type), + NULL); + add_function("__intrinsic_ssbo_atomic_xor", + _atomic_ssbo_intrinsic2(shader_storage_buffer_object, + glsl_type::uint_type), + _atomic_ssbo_intrinsic2(shader_storage_buffer_object, + glsl_type::int_type), + NULL); + add_function("__intrinsic_ssbo_atomic_exchange", + _atomic_ssbo_intrinsic2(shader_storage_buffer_object, + glsl_type::uint_type), + _atomic_ssbo_intrinsic2(shader_storage_buffer_object, + glsl_type::int_type), + NULL); + add_function("__intrinsic_ssbo_atomic_comp_swap", + _atomic_ssbo_intrinsic3(shader_storage_buffer_object, + glsl_type::uint_type), + _atomic_ssbo_intrinsic3(shader_storage_buffer_object, + glsl_type::int_type), + NULL); + add_image_functions(false); add_function("__intrinsic_memory_barrier", @@ -2553,6 +2619,71 @@ builtin_builder::create_builtins() shader_atomic_counters), NULL); + add_function("atomicAdd", + _atomic_ssbo_op2("__intrinsic_ssbo_atomic_add", + shader_storage_buffer_object, + glsl_type::uint_type), + _atomic_ssbo_op2("__intrinsic_ssbo_atomic_add", + shader_storage_buffer_object, + glsl_type::int_type), + NULL); + add_function("atomicMin", + _atomic_ssbo_op2("__intrinsic_ssbo_atomic_min", + shader_storage_buffer_object, + glsl_type::uint_type), + _atomic_ssbo_op2("__intrinsic_ssbo_atomic_min", + shader_storage_buffer_object, + glsl_type::int_type), + NULL); + add_function("atomicMax", + _atomic_ssbo_op2("__intrinsic_ssbo_atomic_max", + shader_storage_buffer_object, + glsl_type::uint_type), + _atomic_ssbo_op2("__intrinsic_ssbo_atomic_max", + shader_storage_buffer_object, + glsl_type::int_type), + NULL); + add_function("atomicAnd", + _atomic_ssbo_op2("__intrinsic_ssbo_atomic_and", + shader_storage_buffer_object, + glsl_type::uint_type), + _atomic_ssbo_op2("__intrinsic_ssbo_atomic_and", + shader_storage_buffer_object, + glsl_type::int_type), + NULL); + add_function("atomicOr", + _atomic_ssbo_op2("__intrinsic_ssbo_atomic_or", + shader_storage_buffer_object, + glsl_type::uint_type), + _atomic_ssbo_op2("__intrinsic_ssbo_atomic_or", + shader_storage_buffer_object, + glsl_type::int_type), + NULL); + add_function("atomicXor", + _atomic_ssbo_op2("__intrinsic_ssbo_atomic_xor", + shader_storage_buffer_object, + glsl_type::uint_type), + _atomic_ssbo_op2("__intrinsic_ssbo_atomic_xor", + shader_storage_buffer_object, + glsl_type::int_type), + NULL); + add_function("atomicExchange", + _atomic_ssbo_op2("__intrinsic_ssbo_atomic_exchange", + shader_storage_buffer_object, + glsl_type::uint_type), + _atomic_ssbo_op2("__intrinsic_ssbo_atomic_exchange", + shader_storage_buffer_object, + glsl_type::int_type), + NULL); + add_function("atomicCompSwap", + _atomic_ssbo_op3("__intrinsic_ssbo_atomic_comp_swap", + shader_storage_buffer_object, + glsl_type::uint_type), + _atomic_ssbo_op3("__intrinsic_ssbo_atomic_comp_swap", + shader_storage_buffer_object, + glsl_type::int_type), + NULL); + add_function("min3", _min3(glsl_type::float_type), _min3(glsl_type::vec2_type), @@ -4848,6 +4979,27 @@ builtin_builder::_atomic_counter_intrinsic(builtin_available_predicate avail) return sig; } +ir_function_signature * +builtin_builder::_atomic_ssbo_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_ssbo_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) @@ -4862,6 +5014,39 @@ builtin_builder::_atomic_counter_op(const char *intrinsic, return sig; } +ir_function_signature * +builtin_builder::_atomic_ssbo_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_ssbo_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) { -- 2.30.2