TL;DR:
在WGSL中可以原子地访问纹理吗?原子性地说,我指的是*文档中的“原子操作”部分中指定的。
如果没有,将改为GLSL在WGPU工作吗?
背景:
嗨,最近我一直在试验WGPU和WGSL,特别是尝试创建一个元胞自动机并将它的数据存储在一个texture_storage_2d中。
我很难理解这样一个事实,即异步访问纹理会导致单元格消失的竞争条件(如果两个单元同时试图前进到同一点,它们将覆盖另一个单元格)。
我做了一些研究,但在WGSL规范中找不到任何解决我的问题的方法,但是我在OpenGL和GLSL中发现了类似的东西,它们被称为纹理上的原子操作(在WGSL中只存在于i32中)。
在WGSL中有类似于GL_TEXTURE_*的东西吗?还是有我不知道的其他选择?换到GLSL (和WGPU在一起时)是唯一的解决方案吗?它还能用吗?
发布于 2022-08-27 15:14:59
这个问题的解决办法
https://www.reddit.com/r/rust_gamedev/comments/wwllee/wgpu_atomic_texture_operations/
在做了一些测试之后,我确认了两件事:
代码
下面的代码片段是从我的原始代码中转换而来的,它不是经过测试的,而是应该工作的。
@group(0) @binding(0) var texture: texture_storage_2d<rg32uint, read_write>;
struct Locks {
locks: array<array<atomic<u32>, 50>, 50>,
};
@group(0) @binding(1) var<storage, read_write> locks: Locks;
fn lock(location: vec2<u32>) -> bool {
let lock_ptr = &locks.locks[location.y][location.x];
let original_lock_value = atomicLoad(lock_ptr);
if (original_lock_value > 0u) {
return false;
}
return atomicAdd(lock_ptr, 1u) == original_lock_value;
}
fn unlock(location: vec2<u32>) {
atomicStore(&locks.locks[location.y][location.x], 0u);
}理想情况下,我应该使用atomicCompareExchangeWeak来代替lock中比较复杂的逻辑,但是atomicCompareExchangeWeak似乎无法在我的机器上工作,所以我自己创建了类似的逻辑。
为了澄清,任何时候都可以读取纹理,但是只有在location返回true时才能写入纹理。
不要忘记每次写完后调用unlock,然后在着色器调用之间重新设置锁:)
发布于 2022-08-24 17:25:43
为了回答第一部分,WGSL中没有原子纹理操作。
https://stackoverflow.com/questions/73475506
复制相似问题