Skip to content

Commit d6656eb

Browse files
committed
Add unit test of texelData util
This test uploads a single texel to encodable texture formats and then reads it back in a shader with textureLoad to check that the values are as expected.
1 parent 2feb998 commit d6656eb

File tree

4 files changed

+595
-64
lines changed

4 files changed

+595
-64
lines changed

src/webgpu/capability_info.ts

Lines changed: 43 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -102,56 +102,60 @@ type TextureFormatInfo = {
102102
// Add fields as needed
103103
};
104104

105+
export type TextureDataType = 'uint' | 'sint' | 'unorm' | 'snorm' | 'float' | 'ufloat';
106+
105107
export const kRegularTextureFormatInfo: {
106108
readonly [k in RegularTextureFormat]: {
107109
color: true;
108110
bytesPerBlock: number;
109111
blockWidth: 1;
110112
blockHeight: 1;
113+
dataType: TextureDataType;
114+
componentType: GPUTextureComponentType;
111115
} & TextureFormatInfo;
112116
} = /* prettier-ignore */ {
113117
// 8-bit formats
114-
'r8unorm': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 1, blockWidth: 1, blockHeight: 1 },
115-
'r8snorm': { renderable: false, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 1, blockWidth: 1, blockHeight: 1 },
116-
'r8uint': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 1, blockWidth: 1, blockHeight: 1 },
117-
'r8sint': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 1, blockWidth: 1, blockHeight: 1 },
118+
'r8unorm': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 1, blockWidth: 1, blockHeight: 1, dataType: 'unorm', componentType: 'float' },
119+
'r8snorm': { renderable: false, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 1, blockWidth: 1, blockHeight: 1, dataType: 'snorm', componentType: 'float' },
120+
'r8uint': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 1, blockWidth: 1, blockHeight: 1, dataType: 'uint', componentType: 'uint' },
121+
'r8sint': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 1, blockWidth: 1, blockHeight: 1, dataType: 'sint', componentType: 'sint' },
118122
// 16-bit formats
119-
'r16uint': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 2, blockWidth: 1, blockHeight: 1 },
120-
'r16sint': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 2, blockWidth: 1, blockHeight: 1 },
121-
'r16float': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 2, blockWidth: 1, blockHeight: 1 },
122-
'rg8unorm': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 2, blockWidth: 1, blockHeight: 1 },
123-
'rg8snorm': { renderable: false, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 2, blockWidth: 1, blockHeight: 1 },
124-
'rg8uint': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 2, blockWidth: 1, blockHeight: 1 },
125-
'rg8sint': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 2, blockWidth: 1, blockHeight: 1 },
123+
'r16uint': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 2, blockWidth: 1, blockHeight: 1, dataType: 'uint', componentType: 'uint' },
124+
'r16sint': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 2, blockWidth: 1, blockHeight: 1, dataType: 'sint', componentType: 'sint' },
125+
'r16float': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 2, blockWidth: 1, blockHeight: 1, dataType: 'float', componentType: 'float' },
126+
'rg8unorm': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 2, blockWidth: 1, blockHeight: 1, dataType: 'unorm', componentType: 'float' },
127+
'rg8snorm': { renderable: false, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 2, blockWidth: 1, blockHeight: 1, dataType: 'snorm', componentType: 'float' },
128+
'rg8uint': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 2, blockWidth: 1, blockHeight: 1, dataType: 'uint', componentType: 'uint' },
129+
'rg8sint': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 2, blockWidth: 1, blockHeight: 1, dataType: 'sint', componentType: 'sint' },
126130
// 32-bit formats
127-
'r32uint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
128-
'r32sint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
129-
'r32float': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
130-
'rg16uint': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
131-
'rg16sint': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
132-
'rg16float': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
133-
'rgba8unorm': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
134-
'rgba8unorm-srgb': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
135-
'rgba8snorm': { renderable: false, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
136-
'rgba8uint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
137-
'rgba8sint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
138-
'bgra8unorm': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
139-
'bgra8unorm-srgb': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
131+
'r32uint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'uint', componentType: 'uint' },
132+
'r32sint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'sint', componentType: 'sint' },
133+
'r32float': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'float', componentType: 'float' },
134+
'rg16uint': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'uint', componentType: 'uint' },
135+
'rg16sint': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'sint', componentType: 'sint' },
136+
'rg16float': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'float', componentType: 'float' },
137+
'rgba8unorm': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'unorm', componentType: 'float' },
138+
'rgba8unorm-srgb': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'unorm', componentType: 'float' },
139+
'rgba8snorm': { renderable: false, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'sint', componentType: 'float' },
140+
'rgba8uint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'uint', componentType: 'uint' },
141+
'rgba8sint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'sint', componentType: 'sint' },
142+
'bgra8unorm': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'unorm', componentType: 'float' },
143+
'bgra8unorm-srgb': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'unorm', componentType: 'float' },
140144
// Packed 32-bit formats
141-
'rgb10a2unorm': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
142-
'rg11b10ufloat': { renderable: false, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
143-
'rgb9e5ufloat': { renderable: false, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
145+
'rgb10a2unorm': { renderable: true, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'unorm', componentType: 'float' },
146+
'rg11b10ufloat': { renderable: false, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'ufloat', componentType: 'float' },
147+
'rgb9e5ufloat': { renderable: false, color: true, depth: false, stencil: false, storage: false, copySrc: true, copyDst: true, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'ufloat', componentType: 'float' },
144148
// 64-bit formats
145-
'rg32uint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 8, blockWidth: 1, blockHeight: 1 },
146-
'rg32sint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 8, blockWidth: 1, blockHeight: 1 },
147-
'rg32float': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 8, blockWidth: 1, blockHeight: 1 },
148-
'rgba16uint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 8, blockWidth: 1, blockHeight: 1 },
149-
'rgba16sint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 8, blockWidth: 1, blockHeight: 1 },
150-
'rgba16float': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 8, blockWidth: 1, blockHeight: 1 },
149+
'rg32uint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 8, blockWidth: 1, blockHeight: 1, dataType: 'uint', componentType: 'uint' },
150+
'rg32sint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 8, blockWidth: 1, blockHeight: 1, dataType: 'sint', componentType: 'sint' },
151+
'rg32float': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 8, blockWidth: 1, blockHeight: 1, dataType: 'float', componentType: 'float' },
152+
'rgba16uint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 8, blockWidth: 1, blockHeight: 1, dataType: 'uint', componentType: 'uint' },
153+
'rgba16sint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 8, blockWidth: 1, blockHeight: 1, dataType: 'sint', componentType: 'sint' },
154+
'rgba16float': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 8, blockWidth: 1, blockHeight: 1, dataType: 'float', componentType: 'float' },
151155
// 128-bit formats
152-
'rgba32uint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 16, blockWidth: 1, blockHeight: 1 },
153-
'rgba32sint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 16, blockWidth: 1, blockHeight: 1 },
154-
'rgba32float': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 16, blockWidth: 1, blockHeight: 1 },
156+
'rgba32uint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 16, blockWidth: 1, blockHeight: 1, dataType: 'uint', componentType: 'uint' },
157+
'rgba32sint': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 16, blockWidth: 1, blockHeight: 1, dataType: 'sint', componentType: 'sint' },
158+
'rgba32float': { renderable: true, color: true, depth: false, stencil: false, storage: true, copySrc: true, copyDst: true, bytesPerBlock: 16, blockWidth: 1, blockHeight: 1, dataType: 'float', componentType: 'float' },
155159
} as const;
156160
export const kRegularTextureFormats = keysOf(kRegularTextureFormatInfo);
157161

@@ -162,9 +166,11 @@ export const kSizedDepthStencilFormatInfo: {
162166
readonly bytesPerBlock: number;
163167
readonly blockWidth: 1;
164168
readonly blockHeight: 1;
169+
dataType: TextureDataType;
170+
componentType: GPUTextureComponentType;
165171
} & TextureFormatInfo;
166172
} = /* prettier-ignore */ {
167-
'depth32float': { renderable: true, color: false, depth: true, stencil: false, storage: false, copySrc: true, copyDst: false, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1 },
173+
'depth32float': { renderable: true, color: false, depth: true, stencil: false, storage: false, copySrc: true, copyDst: false, bytesPerBlock: 4, blockWidth: 1, blockHeight: 1, dataType: 'float', componentType: 'float' },
168174
};
169175
export const kSizedDepthStencilFormats = keysOf(kSizedDepthStencilFormatInfo);
170176

src/webgpu/util/conversion.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,21 @@ export function floatAsNormalizedInteger(float: number, bits: number, signed: bo
1212
}
1313
}
1414

15+
export function normalizedIntegerAsFloat(integer: number, bits: number, signed: boolean): number {
16+
if (signed) {
17+
const max = Math.pow(2, bits - 1) - 1;
18+
assert(integer >= -max - 1 && integer <= max);
19+
if (integer === -max - 1) {
20+
integer = -max;
21+
}
22+
return integer / max;
23+
} else {
24+
const max = Math.pow(2, bits) - 1;
25+
assert(integer >= 0 && integer <= max);
26+
return integer / max;
27+
}
28+
}
29+
1530
// Does not handle clamping, underflow, overflow, denormalized numbers
1631
export function float32ToFloatBits(
1732
n: number,
@@ -127,6 +142,11 @@ export function assertInIntegerRange(n: number, bits: number, signed: boolean):
127142
}
128143

129144
export function gammaCompress(n: number): number {
130-
n = n <= 0.0031308 ? 12.92 * n : 1.055 * Math.pow(n, 1 / 2.4) - 0.055;
145+
n = n <= 0.0031308 ? (323 * n) / 25 : (211 * Math.pow(n, 5 / 12) - 11) / 200;
146+
return n < 0 ? 0 : n > 1 ? 1 : n;
147+
}
148+
149+
export function gammaDecompress(n: number): number {
150+
n = n <= 0.04045 ? (n * 25) / 323 : Math.pow((200 * n + 11) / 211, 12 / 5);
131151
return n < 0 ? 0 : n > 1 ? 1 : n;
132152
}

0 commit comments

Comments
 (0)