Cycles: Enable floating point atomic support in Metal

Utilises native floating point atomic operations if available. Supported in Metal 3.0+ onwards.
Authored by Apple: Michael Parkin-White

Pull Request: https://projects.blender.org/blender/blender/pulls/116786
This commit is contained in:
Michael Jones
2024-01-04 17:08:29 +01:00
committed by Michael Jones (Apple)
parent 29ed7a69e6
commit 31001b67fd
2 changed files with 20 additions and 0 deletions
@@ -579,6 +579,11 @@ void MetalDevice::compile_and_load(int device_id, MetalPipelineType pso_type)
if (@available(macos 12.0, *)) {
options.languageVersion = MTLLanguageVersion2_4;
}
# if defined(MAC_OS_VERSION_13_0)
if (@available(macos 13.0, *)) {
options.languageVersion = MTLLanguageVersion3_0;
}
# endif
# if defined(MAC_OS_VERSION_14_0)
if (@available(macos 14.0, *)) {
options.languageVersion = MTLLanguageVersion3_1;
+15
View File
@@ -61,6 +61,10 @@ ccl_device_inline float atomic_compare_and_swap_float(volatile float *dest,
ccl_device_inline float atomic_add_and_fetch_float(volatile ccl_global float *_source,
const float operand)
{
# if __METAL_VERSION__ >= 300
return atomic_fetch_add_explicit(
(ccl_global atomic_float *)_source, operand, memory_order_relaxed);
# else
volatile ccl_global atomic_int *source = (ccl_global atomic_int *)_source;
union {
int int_value;
@@ -76,6 +80,7 @@ ccl_device_inline float atomic_add_and_fetch_float(volatile ccl_global float *_s
memory_order_relaxed));
return new_value.float_value;
# endif
}
template<class T> ccl_device_inline uint32_t atomic_fetch_and_add_uint32(device T *p, int x)
@@ -132,6 +137,15 @@ ccl_device_inline float atomic_compare_and_swap_float(volatile ccl_global float
const float old_val,
const float new_val)
{
# if __METAL_VERSION__ >= 300
float prev_value = old_val;
atomic_compare_exchange_weak_explicit((ccl_global atomic_float *)dest,
&prev_value,
new_val,
memory_order_relaxed,
memory_order_relaxed);
return prev_value;
# else
int prev_value;
prev_value = __float_as_int(old_val);
atomic_compare_exchange_weak_explicit((ccl_global atomic_int *)dest,
@@ -140,6 +154,7 @@ ccl_device_inline float atomic_compare_and_swap_float(volatile ccl_global float
memory_order_relaxed,
memory_order_relaxed);
return __int_as_float(prev_value);
# endif
}
# define atomic_store(p, x) atomic_store_explicit(p, x, memory_order_relaxed)