首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >锈蚀WGPU原子织构操作

锈蚀WGPU原子织构操作
EN

Stack Overflow用户
提问于 2022-08-24 15:03:51
回答 2查看 125关注 0票数 0

TL;DR:

在WGSL中可以原子地访问纹理吗?原子性地说,我指的是*文档中的“原子操作”部分中指定的。

如果没有,将改为GLSL在WGPU工作吗?

背景:

嗨,最近我一直在试验WGPU和WGSL,特别是尝试创建一个元胞自动机并将它的数据存储在一个texture_storage_2d中。

我很难理解这样一个事实,即异步访问纹理会导致单元格消失的竞争条件(如果两个单元同时试图前进到同一点,它们将覆盖另一个单元格)。

我做了一些研究,但在WGSL规范中找不到任何解决我的问题的方法,但是我在OpenGL和GLSL中发现了类似的东西,它们被称为纹理上的原子操作(在WGSL中只存在于i32中)。

在WGSL中有类似于GL_TEXTURE_*的东西吗?还是有我不知道的其他选择?换到GLSL (和WGPU在一起时)是唯一的解决方案吗?它还能用吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-08-27 15:14:59

这个问题的解决办法

https://www.reddit.com/r/rust_gamedev/comments/wwllee/wgpu_atomic_texture_operations/

在做了一些测试之后,我确认了两件事:

  1. 我成功地实现了原子纹理(下面的代码)。
  2. 当纹理非常大时(我的测试是在2000×2000纹理上进行的),所描述的竞赛条件不会发生。这可能可以用银行冲突来解释,但我还没有对其进行足够的研究,无法确定。

代码

下面的代码片段是从我的原始代码中转换而来的,它不是经过测试的,而是应该工作的。

代码语言:javascript
复制
@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,然后在着色器调用之间重新设置锁:)

票数 0
EN

Stack Overflow用户

发布于 2022-08-24 17:25:43

为了回答第一部分,WGSL中没有原子纹理操作。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73475506

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档