forked from gfx-rs/wgpu
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[naga] Implement atomicCompareExchangeWeak for MSL backend
* See issue gfx-rs#5257
- Loading branch information
1 parent
d9178a1
commit 76c7deb
Showing
6 changed files
with
310 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
// language: metal1.0 | ||
#include <metal_stdlib> | ||
#include <simd/simd.h> | ||
|
||
using metal::uint; | ||
|
||
struct type_2 { | ||
metal::atomic_int inner[128]; | ||
}; | ||
struct type_4 { | ||
metal::atomic_uint inner[128]; | ||
}; | ||
struct _atomic_compare_exchange_resultSint4_ { | ||
int old_value; | ||
bool exchanged; | ||
}; | ||
struct _atomic_compare_exchange_resultUint4_ { | ||
uint old_value; | ||
bool exchanged; | ||
}; | ||
|
||
namespace metal { | ||
template <typename A> | ||
_atomic_compare_exchange_resultSint4_ atomic_naga_atomic_compare_exchange_weak_explicit( | ||
volatile device A *atomic_ptr, | ||
int cmp, | ||
int v | ||
) { | ||
bool swapped = metal::atomic_compare_exchange_weak_explicit( | ||
atomic_ptr, &cmp, v, | ||
metal::memory_order_relaxed, metal::memory_order_relaxed | ||
); | ||
return _atomic_compare_exchange_resultSint4_{cmp, swapped}; | ||
} | ||
template <typename A> | ||
_atomic_compare_exchange_resultSint4_ atomic_naga_atomic_compare_exchange_weak_explicit( | ||
volatile threadgroup A *atomic_ptr, | ||
int cmp, | ||
int v | ||
) { | ||
bool swapped = metal::atomic_compare_exchange_weak_explicit( | ||
atomic_ptr, &cmp, v, | ||
metal::memory_order_relaxed, metal::memory_order_relaxed | ||
); | ||
return _atomic_compare_exchange_resultSint4_{cmp, swapped}; | ||
} | ||
} | ||
|
||
namespace metal { | ||
template <typename A> | ||
_atomic_compare_exchange_resultUint4_ atomic_naga_atomic_compare_exchange_weak_explicit( | ||
volatile device A *atomic_ptr, | ||
uint cmp, | ||
uint v | ||
) { | ||
bool swapped = metal::atomic_compare_exchange_weak_explicit( | ||
atomic_ptr, &cmp, v, | ||
metal::memory_order_relaxed, metal::memory_order_relaxed | ||
); | ||
return _atomic_compare_exchange_resultUint4_{cmp, swapped}; | ||
} | ||
template <typename A> | ||
_atomic_compare_exchange_resultUint4_ atomic_naga_atomic_compare_exchange_weak_explicit( | ||
volatile threadgroup A *atomic_ptr, | ||
uint cmp, | ||
uint v | ||
) { | ||
bool swapped = metal::atomic_compare_exchange_weak_explicit( | ||
atomic_ptr, &cmp, v, | ||
metal::memory_order_relaxed, metal::memory_order_relaxed | ||
); | ||
return _atomic_compare_exchange_resultUint4_{cmp, swapped}; | ||
} | ||
} | ||
constant uint SIZE = 128u; | ||
|
||
kernel void test_atomic_compare_exchange_i32_( | ||
device type_2& arr_i32_ [[user(fake0)]] | ||
) { | ||
uint i = 0u; | ||
int old = {}; | ||
bool exchanged = {}; | ||
bool loop_init = true; | ||
while(true) { | ||
if (!loop_init) { | ||
uint _e27 = i; | ||
i = _e27 + 1u; | ||
} | ||
loop_init = false; | ||
uint _e2 = i; | ||
if (_e2 < SIZE) { | ||
} else { | ||
break; | ||
} | ||
{ | ||
uint _e6 = i; | ||
int _e8 = metal::atomic_load_explicit(&arr_i32_.inner[_e6], metal::memory_order_relaxed); | ||
old = _e8; | ||
exchanged = false; | ||
while(true) { | ||
bool _e12 = exchanged; | ||
if (!(_e12)) { | ||
} else { | ||
break; | ||
} | ||
{ | ||
int _e14 = old; | ||
int new_ = as_type<int>(as_type<float>(_e14) + 1.0); | ||
uint _e20 = i; | ||
int _e22 = old; | ||
_atomic_compare_exchange_resultSint4_ _e23 = metal::atomic_naga_atomic_compare_exchange_weak_explicit(&arr_i32_.inner[_e20], _e22, new_); | ||
old = _e23.old_value; | ||
exchanged = _e23.exchanged; | ||
} | ||
} | ||
} | ||
} | ||
return; | ||
} | ||
|
||
|
||
kernel void test_atomic_compare_exchange_u32_( | ||
device type_4& arr_u32_ [[user(fake0)]] | ||
) { | ||
uint i_1 = 0u; | ||
uint old_1 = {}; | ||
bool exchanged_1 = {}; | ||
bool loop_init_1 = true; | ||
while(true) { | ||
if (!loop_init_1) { | ||
uint _e27 = i_1; | ||
i_1 = _e27 + 1u; | ||
} | ||
loop_init_1 = false; | ||
uint _e2 = i_1; | ||
if (_e2 < SIZE) { | ||
} else { | ||
break; | ||
} | ||
{ | ||
uint _e6 = i_1; | ||
uint _e8 = metal::atomic_load_explicit(&arr_u32_.inner[_e6], metal::memory_order_relaxed); | ||
old_1 = _e8; | ||
exchanged_1 = false; | ||
while(true) { | ||
bool _e12 = exchanged_1; | ||
if (!(_e12)) { | ||
} else { | ||
break; | ||
} | ||
{ | ||
uint _e14 = old_1; | ||
uint new_1 = as_type<uint>(as_type<float>(_e14) + 1.0); | ||
uint _e20 = i_1; | ||
uint _e22 = old_1; | ||
_atomic_compare_exchange_resultUint4_ _e23 = metal::atomic_naga_atomic_compare_exchange_weak_explicit(&arr_u32_.inner[_e20], _e22, new_1); | ||
old_1 = _e23.old_value; | ||
exchanged_1 = _e23.exchanged; | ||
} | ||
} | ||
} | ||
} | ||
return; | ||
} |
Oops, something went wrong.