Is usampler2DArray available in WebGPU?

Is usampler2DArray available in WebGPU ?

uniform highp usampler2DArray someTexture;

...
uvec4 rgba = texture(someTexture, vec3(0, 0, 0));
...

> Error: 'sampler2DArray' : sampler-constructor first argument must match type and dimensionality of constructor type 

webgl2 works fine, but webgpu doesn’t.

@mvaligursky

my guess is that as usamplers cannot be filtered on WebGPU, you need to use texelFetch instead of texture to read from it.

Unfortunately this didn’t help, can you test it?


I replaced the type using hot reloading of the javascript file and it helped.

It seems that your types are not being replaced automatically.

// TODO: check littleEndian
// Compress height by x coord [patch0, patch1] ...
// see: CompressedPatchedHeightMap file
export const terrainHeightFactorRGBA8X2VS =
`
    #define uTerrainHeightMap_HOTFIX usampler2DArray(${terrainHeightMapParamName}_texture, ${terrainHeightMapParamName}_sampler)

    float getTerrainHeightFactorFromTexture(ivec3 uv) {
        int level    = uv.b;
        int newLevel = level / 2;
        int chunkX   = level % HM_NUM_CHUNKS_X;
        int shift    = chunkX % 2;
        uvec4 rgba   = texelFetch(uTerrainHeightMap_HOTFIX, ivec3(uv.rg, newLevel), 0);
        uint value   = (shift == 0) ? rgba.r : rgba.g;
        return float(value) / 65535.0;
    }
`;

Could you put together a simple repro for this?

Yes, sure

1 Like

https://playcanvas.com/editor/scene/2116103

@mvaligursky

    uniform highp usampler2DArray ${textureParamName};

    float getSomeValuesFromTexture(ivec3 coord) {

        // HOT FIX FOR WEBGPU
        // We change the sampler type, because the standard handler textureParamName does not inherit the type ([U]sampler2DArray)
        #if defined(WEBGPU)
        uvec4 rgba = texelFetch(usampler2DArray(${textureParamName}_texture, ${textureParamName}_sampler), coord, 0);
        #else
        uvec4 rgba = texelFetch(${textureParamName}, coord, 0);
        #endif

        uint value = rgba.r + rgba.g;
        return float(value) / 65535.0;
    }

Replace it and you will see the error, this is only for WebGPU.

    uniform highp usampler2DArray ${textureParamName};

    float getSomeValuesFromTexture(ivec3 coord) {
        uvec4 rgba = texelFetch(${textureParamName}, coord, 0);
        uint value = rgba.r + rgba.g;
        return float(value) / 65535.0;
    }

Nice thanks! Got a fix here, that’ll be released with the next engine release: [Fix] Fixes handling uf (u/i)sampler2DArray shader translation for WebGPU by mvaligursky · Pull Request #7120 · playcanvas/engine · GitHub

This line

uniform highp usampler2DArray uTmpTexture;

used to be translated to this:

layout(set = 0, binding = 1) uniform utexture2DArray uTmpTexture_texture;
layout(set = 0, binding = 2) uniform sampler uTmpTexture_sampler;
#define uTmpTexture sampler2DArray(uTmpTexture_texture, uTmpTexture_sampler)

but now it’s correctly this:

layout(set = 0, binding = 1) uniform utexture2DArray uTmpTexture_texture;
layout(set = 0, binding = 2) uniform sampler uTmpTexture_sampler;
#define uTmpTexture usampler2DArray(uTmpTexture_texture, uTmpTexture_sampler)

see the usampler2DArray on the last line

1 Like