Skip to content

Commit f6b22c0

Browse files
authored
Add tests for Tier1 read-only storage texture access (#4438)
Texture-formats-tier1 supports the read-only GPUStorageTextureAccess on below formats: r16unorm, r16snorm, rg16unorm, r16snorm, rgba16unorm, rgba16snorm, r8unorm, r8snorm, r8uint, r8sint, rg8unorm, rg8snorm, rg8uint, rg8sint, r16uint, r16sint, r16float, rg16uint, rg16sint, rg16float, rgb10a2uint, rgb10a2unorm, rg11b10ufloat. This commit added tests for these formats to be consistent with the spec.
1 parent 07f4412 commit f6b22c0

1 file changed

Lines changed: 186 additions & 67 deletions

File tree

src/webgpu/api/operation/storage_texture/read_only.spec.ts

Lines changed: 186 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,34 @@ import { kValidShaderStages, TValidShaderStage } from '../../../util/shader.js';
2121

2222
function getComponentCountForFormat(format: ColorTextureFormat): number {
2323
switch (format) {
24+
case 'r8unorm':
25+
case 'r8uint':
26+
case 'r8snorm':
27+
case 'r8sint':
28+
case 'r16unorm':
29+
case 'r16uint':
30+
case 'r16snorm':
31+
case 'r16sint':
32+
case 'r16float':
2433
case 'r32float':
2534
case 'r32sint':
2635
case 'r32uint':
2736
return 1;
37+
case 'rg8unorm':
38+
case 'rg8uint':
39+
case 'rg8snorm':
40+
case 'rg8sint':
41+
case 'rg16unorm':
42+
case 'rg16uint':
43+
case 'rg16snorm':
44+
case 'rg16sint':
45+
case 'rg16float':
2846
case 'rg32float':
2947
case 'rg32sint':
3048
case 'rg32uint':
3149
return 2;
50+
case 'rg11b10ufloat':
51+
return 3;
3252
case 'rgba32float':
3353
case 'rgba32sint':
3454
case 'rgba32uint':
@@ -40,6 +60,10 @@ function getComponentCountForFormat(format: ColorTextureFormat): number {
4060
case 'rgba16sint':
4161
case 'rgba16uint':
4262
case 'bgra8unorm':
63+
case 'rgba16unorm':
64+
case 'rgba16snorm':
65+
case 'rgb10a2uint':
66+
case 'rgb10a2unorm':
4367
return 4;
4468
default:
4569
unreachable();
@@ -86,74 +110,146 @@ class F extends AllFeaturesMaxLimitsGPUTest {
86110
outputBufferTypedData[4 * texelDataIndex] = 0;
87111
outputBufferTypedData[4 * texelDataIndex + 1] = 0;
88112
outputBufferTypedData[4 * texelDataIndex + 2] = 0;
89-
outputBufferTypedData[4 * texelDataIndex + 3] = 1;
90-
for (let component = 0; component < componentCount; ++component) {
91-
switch (format) {
92-
case 'r32uint':
93-
case 'rg32uint':
94-
case 'rgba16uint':
95-
case 'rgba32uint': {
96-
const texelValue = 4 * texelDataIndex + component + 1;
97-
setData(texelValue, texelValue, texelDataIndex, component);
98-
break;
113+
outputBufferTypedData[4 * texelDataIndex + 3] = 0;
114+
115+
// Packed formats like rgb10a2unorm, rg11b10ufloat, and rgb10a2uint store multiple color components within a single 32-bit integer.
116+
// This means their TypedArray uses a single element per texel, so they are handled separately from other formats
117+
if (format === 'rgb10a2unorm') {
118+
const texelValue = 4 * texelDataIndex + 1;
119+
const r = texelValue % 1024;
120+
const g = (texelValue * 2) % 1024;
121+
const b = (texelValue * 3) % 1024;
122+
const a = 3;
123+
const packedValue = (a << 30) | (b << 20) | (g << 10) | r;
124+
const texelComponentIndex = texelDataIndex;
125+
texelTypedDataView[texelComponentIndex] = packedValue;
126+
outputBufferTypedData[texelDataIndex * 4] = r / 1023.0;
127+
outputBufferTypedData[texelDataIndex * 4 + 1] = g / 1023.0;
128+
outputBufferTypedData[texelDataIndex * 4 + 2] = b / 1023.0;
129+
outputBufferTypedData[texelDataIndex * 4 + 3] = a / 3.0;
130+
} else if (format === 'rg11b10ufloat') {
131+
const kFloat11One = 0x3c0;
132+
const kFloat10Zero = 0;
133+
const r = kFloat11One;
134+
const g = kFloat11One;
135+
const b = kFloat10Zero;
136+
const packedValue = (b << 22) | (g << 11) | r;
137+
const texelComponentIndex = texelDataIndex;
138+
texelTypedDataView[texelComponentIndex] = packedValue;
139+
outputBufferTypedData[texelDataIndex * 4] = 1.0;
140+
outputBufferTypedData[texelDataIndex * 4 + 1] = 1.0;
141+
outputBufferTypedData[texelDataIndex * 4 + 2] = 0;
142+
} else if (format === 'rgb10a2uint') {
143+
const texelValue = 4 * texelDataIndex + 1;
144+
const texelComponentIndex = texelDataIndex;
145+
texelTypedDataView[texelComponentIndex] = texelValue;
146+
const outputTexelComponentIndex = texelDataIndex * 4;
147+
outputBufferTypedData[outputTexelComponentIndex] = texelValue;
148+
} else {
149+
for (let component = 0; component < componentCount; ++component) {
150+
switch (format) {
151+
case 'r32uint':
152+
case 'rg32uint':
153+
case 'rgba16uint':
154+
case 'rgba32uint':
155+
case 'r8uint':
156+
case 'rg8uint':
157+
case 'rgba8uint': {
158+
const texelValue = (4 * texelDataIndex + component + 1) % 256;
159+
setData(texelValue, texelValue, texelDataIndex, component);
160+
break;
161+
}
162+
case 'r16uint':
163+
case 'rg16uint': {
164+
const texelValue = (4 * texelDataIndex + component + 1) % 65536;
165+
setData(texelValue, texelValue, texelDataIndex, component);
166+
break;
167+
}
168+
case 'r8unorm':
169+
case 'rg8unorm':
170+
case 'rgba8unorm': {
171+
const texelValue = (4 * texelDataIndex + component + 1) % 256;
172+
const outputValue = texelValue / 255.0;
173+
setData(texelValue, outputValue, texelDataIndex, component);
174+
break;
175+
}
176+
case 'bgra8unorm': {
177+
const texelValue = (4 * texelDataIndex + component + 1) % 256;
178+
const outputValue = texelValue / 255.0;
179+
// BGRA -> RGBA
180+
assert(component < 4);
181+
const outputComponent = [2, 1, 0, 3][component];
182+
setData(texelValue, outputValue, texelDataIndex, component, outputComponent);
183+
break;
184+
}
185+
case 'r16unorm':
186+
case 'rg16unorm':
187+
case 'rgba16unorm': {
188+
const texelValue = (4 * texelDataIndex + component + 1) % 65536;
189+
const outputValue = texelValue / 65535.0;
190+
setData(texelValue, outputValue, texelDataIndex, component);
191+
break;
192+
}
193+
case 'r32sint':
194+
case 'rg32sint':
195+
case 'rgba16sint':
196+
case 'rgba32sint': {
197+
const texelValue =
198+
(texelDataIndex & 1 ? 1 : -1) * (4 * texelDataIndex + component + 1);
199+
setData(texelValue, texelValue, texelDataIndex, component);
200+
break;
201+
}
202+
case 'r8sint':
203+
case 'rg8sint':
204+
case 'rgba8sint': {
205+
const texelValue = ((4 * texelDataIndex + component + 1) % 256) - 128;
206+
setData(texelValue, texelValue, texelDataIndex, component);
207+
break;
208+
}
209+
case 'r16sint':
210+
case 'rg16sint': {
211+
const signedValue =
212+
(texelDataIndex & 1 ? 1 : -1) *
213+
(((4 * texelDataIndex + component + 1) % 65536) - 32768);
214+
setData(signedValue, signedValue, texelDataIndex, component);
215+
break;
216+
}
217+
case 'r8snorm':
218+
case 'rg8snorm':
219+
case 'rgba8snorm': {
220+
const texelValue = ((4 * texelDataIndex + component + 1) % 256) - 128;
221+
const outputValue = Math.max(texelValue / 127.0, -1.0);
222+
setData(texelValue, outputValue, texelDataIndex, component);
223+
break;
224+
}
225+
case 'r16snorm':
226+
case 'rg16snorm':
227+
case 'rgba16snorm': {
228+
const texelValue = ((4 * texelDataIndex + component + 1) % 65536) - 32768;
229+
const outputValue = Math.max(texelValue / 32767.0, -1.0);
230+
setData(texelValue, outputValue, texelDataIndex, component);
231+
break;
232+
}
233+
case 'r32float':
234+
case 'rg32float':
235+
case 'rgba32float': {
236+
const texelValue = (4 * texelDataIndex + component + 1) / 10.0;
237+
setData(texelValue, texelValue, texelDataIndex, component);
238+
break;
239+
}
240+
case 'r16float':
241+
case 'rg16float':
242+
case 'rgba16float': {
243+
const texelValue = (4 * texelDataIndex + component + 1) / 10.0;
244+
const f16Array = new Float16Array(1);
245+
f16Array[0] = texelValue;
246+
setData(texelValue, f16Array[0], texelDataIndex, component);
247+
break;
248+
}
249+
default:
250+
unreachable();
251+
break;
99252
}
100-
case 'rgba8uint': {
101-
const texelValue = (4 * texelDataIndex + component + 1) % 256;
102-
setData(texelValue, texelValue, texelDataIndex, component);
103-
break;
104-
}
105-
case 'rgba8unorm': {
106-
const texelValue = (4 * texelDataIndex + component + 1) % 256;
107-
const outputValue = texelValue / 255.0;
108-
setData(texelValue, outputValue, texelDataIndex, component);
109-
break;
110-
}
111-
case 'bgra8unorm': {
112-
const texelValue = (4 * texelDataIndex + component + 1) % 256;
113-
const outputValue = texelValue / 255.0;
114-
// BGRA -> RGBA
115-
assert(component < 4);
116-
const outputComponent = [2, 1, 0, 3][component];
117-
setData(texelValue, outputValue, texelDataIndex, component, outputComponent);
118-
break;
119-
}
120-
case 'r32sint':
121-
case 'rg32sint':
122-
case 'rgba16sint':
123-
case 'rgba32sint': {
124-
const texelValue =
125-
(texelDataIndex & 1 ? 1 : -1) * (4 * texelDataIndex + component + 1);
126-
setData(texelValue, texelValue, texelDataIndex, component);
127-
break;
128-
}
129-
case 'rgba8sint': {
130-
const texelValue = ((4 * texelDataIndex + component + 1) % 256) - 128;
131-
setData(texelValue, texelValue, texelDataIndex, component);
132-
break;
133-
}
134-
case 'rgba8snorm': {
135-
const texelValue = ((4 * texelDataIndex + component + 1) % 256) - 128;
136-
const outputValue = Math.max(texelValue / 127.0, -1.0);
137-
setData(texelValue, outputValue, texelDataIndex, component);
138-
break;
139-
}
140-
case 'r32float':
141-
case 'rg32float':
142-
case 'rgba32float': {
143-
const texelValue = (4 * texelDataIndex + component + 1) / 10.0;
144-
setData(texelValue, texelValue, texelDataIndex, component);
145-
break;
146-
}
147-
case 'rgba16float': {
148-
const texelValue = (4 * texelDataIndex + component + 1) / 10.0;
149-
const f16Array = new Float16Array(1);
150-
f16Array[0] = texelValue;
151-
setData(texelValue, f16Array[0], texelDataIndex, component);
152-
break;
153-
}
154-
default:
155-
unreachable();
156-
break;
157253
}
158254
}
159255
}
@@ -193,26 +289,49 @@ class F extends AllFeaturesMaxLimitsGPUTest {
193289
case 'r32uint':
194290
case 'rg32uint':
195291
case 'rgba32uint':
292+
case 'rgb10a2uint':
293+
case 'rgb10a2unorm':
196294
return new Uint32Array(arrayBuffer);
197295
case 'rgba8uint':
198296
case 'rgba8unorm':
199297
case 'bgra8unorm':
298+
case 'r8unorm':
299+
case 'r8uint':
300+
case 'rg8unorm':
301+
case 'rg8uint':
200302
return new Uint8Array(arrayBuffer);
201303
case 'rgba16uint':
304+
case 'r16unorm':
305+
case 'rg16unorm':
306+
case 'rgba16unorm':
307+
case 'r16uint':
308+
case 'rg16uint':
202309
return new Uint16Array(arrayBuffer);
203310
case 'r32sint':
204311
case 'rg32sint':
205312
case 'rgba32sint':
313+
case 'rg11b10ufloat':
206314
return new Int32Array(arrayBuffer);
207315
case 'rgba8sint':
208316
case 'rgba8snorm':
317+
case 'r8snorm':
318+
case 'r8sint':
319+
case 'rg8snorm':
320+
case 'rg8sint':
209321
return new Int8Array(arrayBuffer);
210322
case 'rgba16sint':
323+
case 'r16snorm':
324+
case 'rg16snorm':
325+
case 'rgba16snorm':
326+
case 'r16sint':
327+
case 'rg16sint':
211328
return new Int16Array(arrayBuffer);
212329
case 'r32float':
213330
case 'rg32float':
214331
case 'rgba32float':
215332
return new Float32Array(arrayBuffer);
333+
case 'r16float':
334+
case 'rg16float':
216335
case 'rgba16float':
217336
return new Float16Array(arrayBuffer);
218337
default:

0 commit comments

Comments
 (0)