blob: b6827846a6ec52f319f7b8fcbb9c309a5d921988 [file] [log] [blame]
Kai Ninomiyaf0d24f32020-12-11 16:42:29 -08001/* eslint-disable no-sparse-arrays */
2import { ResolveType, ZipKeysWithValues } from '../common/framework/util/types.js';
3
Kai Ninomiya04e404f2020-10-23 16:02:19 -07004import { GPUConst } from './constants.js';
5
Kai Ninomiya21f8f992020-06-09 15:41:32 -07006type valueof<K> = K[keyof K];
7type GPUTextureUsage = valueof<typeof GPUTextureUsage>;
8type GPUBufferUsage = valueof<typeof GPUBufferUsage>;
Justin Fan5d1b8c72020-01-15 16:03:37 -08009
Kai Ninomiya3a50e8b2020-04-28 20:38:31 -070010function keysOf<T extends string>(obj: { [k in T]: unknown }): readonly T[] {
11 return (Object.keys(obj) as unknown[]) as T[];
12}
13
14function numericKeysOf<T>(obj: object): readonly T[] {
15 return (Object.keys(obj).map(n => Number(n)) as unknown[]) as T[];
16}
17
Kai Ninomiyaf0d24f32020-12-11 16:42:29 -080018/**
19 * Creates an info lookup object from a more nicely-formatted table. See below for examples.
20 *
21 * Note: Using `as const` on the arguments to this function is necessary to infer the correct type.
22 */
23function makeTable<
24 Members extends readonly string[],
25 Defaults extends readonly unknown[],
26 Table extends { readonly [k: string]: readonly unknown[] }
27>(
28 members: Members,
29 defaults: Defaults,
30 table: Table
31): {
32 readonly [k in keyof Table]: ResolveType<ZipKeysWithValues<Members, Table[k], Defaults>>;
33} {
34 const result: { [k: string]: { [m: string]: unknown } } = {};
35 for (const [k, v] of Object.entries<readonly unknown[]>(table)) {
36 const item: { [m: string]: unknown } = {};
37 for (let i = 0; i < members.length; ++i) {
38 item[members[i]] = v[i] ?? defaults[i];
39 }
40 result[k] = item;
41 }
42 /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
43 return result as any;
44}
45
Hao Liab18a1b2021-01-28 06:16:50 +080046// Queries
47
48export const kMaxQueryCount = 8192;
49export const kQueryTypes = ['occlusion', 'pipeline-statistics', 'timestamp'] as const;
50
Kai Ninomiyabe420af2020-07-24 18:32:40 -070051// Buffers
52
Kai Ninomiya84b7ab12020-11-20 12:33:12 -080053export const kBufferSizeAlignment = 4;
54
Kai Ninomiyabe420af2020-07-24 18:32:40 -070055export const kBufferUsageInfo: {
56 readonly [k in GPUBufferUsage]: {};
57} = /* prettier-ignore */ {
Kai Ninomiya04e404f2020-10-23 16:02:19 -070058 [GPUConst.BufferUsage.MAP_READ]: {},
59 [GPUConst.BufferUsage.MAP_WRITE]: {},
60 [GPUConst.BufferUsage.COPY_SRC]: {},
61 [GPUConst.BufferUsage.COPY_DST]: {},
62 [GPUConst.BufferUsage.INDEX]: {},
63 [GPUConst.BufferUsage.VERTEX]: {},
64 [GPUConst.BufferUsage.UNIFORM]: {},
65 [GPUConst.BufferUsage.STORAGE]: {},
66 [GPUConst.BufferUsage.INDIRECT]: {},
67 [GPUConst.BufferUsage.QUERY_RESOLVE]: {},
Kai Ninomiyabe420af2020-07-24 18:32:40 -070068};
69export const kBufferUsages = numericKeysOf<GPUBufferUsage>(kBufferUsageInfo);
70
Justin Fan5d1b8c72020-01-15 16:03:37 -080071// Textures
72
Kai Ninomiyaf0d24f32020-12-11 16:42:29 -080073export const kRegularTextureFormatInfo = /* prettier-ignore */ makeTable(
Yunchao He23f42712021-03-08 23:37:00 -080074 ['renderable', 'multisample', 'color', 'depth', 'stencil', 'storage', 'copySrc', 'copyDst', 'bytesPerBlock', 'blockWidth', 'blockHeight', 'extension'] as const,
75 [ , true, true, false, false, , true, true, , 1, 1, ] as const, {
Kai Ninomiyaea9e36f2019-10-18 20:01:03 -070076 // 8-bit formats
Yunchao He23f42712021-03-08 23:37:00 -080077 'r8unorm': [ true, , , , , false, , , 1],
78 'r8snorm': [ false, , , , , false, , , 1],
79 'r8uint': [ true, , , , , false, , , 1],
80 'r8sint': [ true, , , , , false, , , 1],
Kai Ninomiyaea9e36f2019-10-18 20:01:03 -070081 // 16-bit formats
Yunchao He23f42712021-03-08 23:37:00 -080082 'r16uint': [ true, , , , , false, , , 2],
83 'r16sint': [ true, , , , , false, , , 2],
84 'r16float': [ true, , , , , false, , , 2],
85 'rg8unorm': [ true, , , , , false, , , 2],
86 'rg8snorm': [ false, , , , , false, , , 2],
87 'rg8uint': [ true, , , , , false, , , 2],
88 'rg8sint': [ true, , , , , false, , , 2],
Kai Ninomiyaea9e36f2019-10-18 20:01:03 -070089 // 32-bit formats
Yunchao He23f42712021-03-08 23:37:00 -080090 'r32uint': [ true, , , , , true, , , 4],
91 'r32sint': [ true, , , , , true, , , 4],
92 'r32float': [ true, , , , , true, , , 4],
93 'rg16uint': [ true, , , , , false, , , 4],
94 'rg16sint': [ true, , , , , false, , , 4],
95 'rg16float': [ true, , , , , false, , , 4],
96 'rgba8unorm': [ true, , , , , true, , , 4],
97 'rgba8unorm-srgb': [ true, , , , , false, , , 4],
98 'rgba8snorm': [ false, , , , , true, , , 4],
99 'rgba8uint': [ true, , , , , true, , , 4],
100 'rgba8sint': [ true, , , , , true, , , 4],
101 'bgra8unorm': [ true, , , , , false, , , 4],
102 'bgra8unorm-srgb': [ true, , , , , false, , , 4],
Kai Ninomiyaea9e36f2019-10-18 20:01:03 -0700103 // Packed 32-bit formats
Yunchao He23f42712021-03-08 23:37:00 -0800104 'rgb10a2unorm': [ true, , , , , false, , , 4],
105 'rg11b10ufloat': [ false, , , , , false, , , 4],
106 'rgb9e5ufloat': [ false, , , , , false, , , 4],
Kai Ninomiyaea9e36f2019-10-18 20:01:03 -0700107 // 64-bit formats
Yunchao He23f42712021-03-08 23:37:00 -0800108 'rg32uint': [ true, , , , , true, , , 8],
109 'rg32sint': [ true, , , , , true, , , 8],
110 'rg32float': [ true, , , , , true, , , 8],
111 'rgba16uint': [ true, , , , , true, , , 8],
112 'rgba16sint': [ true, , , , , true, , , 8],
113 'rgba16float': [ true, , , , , true, , , 8],
Kai Ninomiyaea9e36f2019-10-18 20:01:03 -0700114 // 128-bit formats
Yunchao He23f42712021-03-08 23:37:00 -0800115 'rgba32uint': [ true, , , , , true, , , 16],
116 'rgba32sint': [ true, , , , , true, , , 16],
117 'rgba32float': [ true, , , , , true, , , 16],
Kai Ninomiyaf0d24f32020-12-11 16:42:29 -0800118} as const);
119/* prettier-ignore */
Yunchao He23f42712021-03-08 23:37:00 -0800120const kTexFmtInfoHeader = ['renderable', 'multisample', 'color', 'depth', 'stencil', 'storage', 'copySrc', 'copyDst', 'bytesPerBlock', 'blockWidth', 'blockHeight', 'extension'] as const;
Kai Ninomiyaf0d24f32020-12-11 16:42:29 -0800121export const kSizedDepthStencilFormatInfo = /* prettier-ignore */ makeTable(kTexFmtInfoHeader,
Yunchao He23f42712021-03-08 23:37:00 -0800122 [ true, true, false, , , false, , , , 1, 1, ] as const, {
123 'depth32float': [ true, , false, true, false, , false, false, 4],
124 'depth16unorm': [ true, , false, true, false, , false, false, 2],
125 'stencil8': [ true, , , false, true, , false, false, 1],
Kai Ninomiyaf0d24f32020-12-11 16:42:29 -0800126} as const);
127export const kUnsizedDepthStencilFormatInfo = /* prettier-ignore */ makeTable(kTexFmtInfoHeader,
Yunchao He23f42712021-03-08 23:37:00 -0800128 [ true, true, false, , , false, , , undefined, 1, 1, ] as const, {
129 'depth24plus': [ , , , true, false, , false, false],
130 'depth24plus-stencil8': [ , , , true, true, , false, false],
Yunchao Hed50dfc52021-02-25 16:35:07 -0800131 // bytesPerBlock only makes sense on a per-aspect basis. But this table can't express that. So we put depth24unorm-stencil8 and depth32float-stencil8 to be unsized formats for now.
Yunchao He23f42712021-03-08 23:37:00 -0800132 'depth24unorm-stencil8': [ , , , true, true, , false, false, , , , 'depth24unorm-stencil8'],
133 'depth32float-stencil8': [ , , , true, true, , false, false, , , , 'depth32float-stencil8'],
Kai Ninomiyaf0d24f32020-12-11 16:42:29 -0800134} as const);
135export const kCompressedTextureFormatInfo = /* prettier-ignore */ makeTable(kTexFmtInfoHeader,
Yunchao He23f42712021-03-08 23:37:00 -0800136 [ false, false, true, false, false, false, true, true, , 4, 4, ] as const, {
137 'bc1-rgba-unorm': [ , , , , , , , , 8, 4, 4, 'texture-compression-bc'],
138 'bc1-rgba-unorm-srgb': [ , , , , , , , , 8, 4, 4, 'texture-compression-bc'],
139 'bc2-rgba-unorm': [ , , , , , , , , 16, 4, 4, 'texture-compression-bc'],
140 'bc2-rgba-unorm-srgb': [ , , , , , , , , 16, 4, 4, 'texture-compression-bc'],
141 'bc3-rgba-unorm': [ , , , , , , , , 16, 4, 4, 'texture-compression-bc'],
142 'bc3-rgba-unorm-srgb': [ , , , , , , , , 16, 4, 4, 'texture-compression-bc'],
143 'bc4-r-unorm': [ , , , , , , , , 8, 4, 4, 'texture-compression-bc'],
144 'bc4-r-snorm': [ , , , , , , , , 8, 4, 4, 'texture-compression-bc'],
145 'bc5-rg-unorm': [ , , , , , , , , 16, 4, 4, 'texture-compression-bc'],
146 'bc5-rg-snorm': [ , , , , , , , , 16, 4, 4, 'texture-compression-bc'],
147 'bc6h-rgb-ufloat': [ , , , , , , , , 16, 4, 4, 'texture-compression-bc'],
148 'bc6h-rgb-float': [ , , , , , , , , 16, 4, 4, 'texture-compression-bc'],
149 'bc7-rgba-unorm': [ , , , , , , , , 16, 4, 4, 'texture-compression-bc'],
150 'bc7-rgba-unorm-srgb': [ , , , , , , , , 16, 4, 4, 'texture-compression-bc'],
Kai Ninomiyaf0d24f32020-12-11 16:42:29 -0800151} as const);
152
Kai Ninomiyaa9ea59f2021-02-10 16:13:49 -0800153export type RegularTextureFormat = keyof typeof kRegularTextureFormatInfo;
154export type SizedDepthStencilFormat = keyof typeof kSizedDepthStencilFormatInfo;
155export type UnsizedDepthStencilFormat = keyof typeof kUnsizedDepthStencilFormatInfo;
156export type CompressedTextureFormat = keyof typeof kCompressedTextureFormatInfo;
157
Kai Ninomiyaebef1472020-08-14 15:21:09 -0700158export const kRegularTextureFormats = keysOf(kRegularTextureFormatInfo);
Kai Ninomiyaebef1472020-08-14 15:21:09 -0700159export const kSizedDepthStencilFormats = keysOf(kSizedDepthStencilFormatInfo);
Kai Ninomiyaebef1472020-08-14 15:21:09 -0700160export const kUnsizedDepthStencilFormats = keysOf(kUnsizedDepthStencilFormatInfo);
Kai Ninomiyaebef1472020-08-14 15:21:09 -0700161export const kCompressedTextureFormats = keysOf(kCompressedTextureFormatInfo);
162
163export const kColorTextureFormatInfo = {
164 ...kRegularTextureFormatInfo,
165 ...kCompressedTextureFormatInfo,
166} as const;
167export type ColorTextureFormat = keyof typeof kColorTextureFormatInfo;
168export const kColorTextureFormats = keysOf(kColorTextureFormatInfo);
169
170export const kEncodableTextureFormatInfo = {
171 ...kRegularTextureFormatInfo,
172 ...kSizedDepthStencilFormatInfo,
173} as const;
174export type EncodableTextureFormat = keyof typeof kEncodableTextureFormatInfo;
175export const kEncodableTextureFormats = keysOf(kEncodableTextureFormatInfo);
176
177export const kSizedTextureFormatInfo = {
178 ...kRegularTextureFormatInfo,
179 ...kSizedDepthStencilFormatInfo,
180 ...kCompressedTextureFormatInfo,
181} as const;
182export type SizedTextureFormat = keyof typeof kSizedTextureFormatInfo;
183export const kSizedTextureFormats = keysOf(kSizedTextureFormatInfo);
184
185export const kDepthStencilFormatInfo = {
186 ...kSizedDepthStencilFormatInfo,
187 ...kUnsizedDepthStencilFormatInfo,
188} as const;
189export type DepthStencilFormat = keyof typeof kDepthStencilFormatInfo;
190export const kDepthStencilFormats = keysOf(kDepthStencilFormatInfo);
191
192export const kUncompressedTextureFormatInfo = {
193 ...kRegularTextureFormatInfo,
194 ...kSizedDepthStencilFormatInfo,
195 ...kUnsizedDepthStencilFormatInfo,
196} as const;
197export type UncompressedTextureFormat = keyof typeof kUncompressedTextureFormatInfo;
198export const kUncompressedTextureFormats = keysOf(kUncompressedTextureFormatInfo);
199
Kai Ninomiyaf0d24f32020-12-11 16:42:29 -0800200export const kAllTextureFormatInfo = {
Kai Ninomiyaebef1472020-08-14 15:21:09 -0700201 ...kUncompressedTextureFormatInfo,
202 ...kCompressedTextureFormatInfo,
203} as const;
204export const kAllTextureFormats = keysOf(kAllTextureFormatInfo);
Kai Ninomiyaf0d24f32020-12-11 16:42:29 -0800205// Assert every GPUTextureFormat is covered by one of the tables.
206((x: { readonly [k in GPUTextureFormat]: {} }) => x)(kAllTextureFormatInfo);
Kai Ninomiya86b055d2020-01-06 19:37:25 -0800207
Austin Eng212317f2020-04-16 17:22:27 -0700208export const kTextureDimensionInfo: {
Kai Ninomiya3a50e8b2020-04-28 20:38:31 -0700209 readonly [k in GPUTextureDimension]: {
Austin Eng212317f2020-04-16 17:22:27 -0700210 // Add fields as needed
211 };
212} = /* prettier-ignore */ {
213 '1d': {},
214 '2d': {},
215 '3d': {},
216};
Kai Ninomiya3a50e8b2020-04-28 20:38:31 -0700217export const kTextureDimensions = keysOf(kTextureDimensionInfo);
Austin Eng212317f2020-04-16 17:22:27 -0700218
219export const kTextureAspectInfo: {
Kai Ninomiya3a50e8b2020-04-28 20:38:31 -0700220 readonly [k in GPUTextureAspect]: {
Austin Eng212317f2020-04-16 17:22:27 -0700221 // Add fields as needed
222 };
223} = /* prettier-ignore */ {
224 'all': {},
225 'depth-only': {},
226 'stencil-only': {},
227};
Kai Ninomiya3a50e8b2020-04-28 20:38:31 -0700228export const kTextureAspects = keysOf(kTextureAspectInfo);
229
Jiawei Shaoa9ac8c32021-03-04 02:53:13 +0800230const kDepthStencilFormatCapabilityInBufferTextureCopy = {
231 // kUnsizedDepthStencilFormats
232 depth24plus: {
233 CopyB2T: [],
234 CopyT2B: [],
235 },
236 'depth24plus-stencil8': {
237 CopyB2T: ['stencil-only'],
238 CopyT2B: ['stencil-only'],
239 },
240
241 // kSizedDepthStencilFormats
242 depth16unorm: {
243 CopyB2T: ['all', 'depth-only'],
244 CopyT2B: ['all', 'depth-only'],
245 },
246 depth32float: {
247 CopyB2T: [],
248 CopyT2B: ['all', 'depth-only'],
249 },
250 'depth24unorm-stencil8': {
251 CopyB2T: ['stencil-only'],
252 CopyT2B: ['depth-only', 'stencil-only'],
253 },
254 'depth32float-stencil8': {
255 CopyB2T: ['stencil-only'],
256 CopyT2B: ['depth-only', 'stencil-only'],
257 },
258 stencil8: {
259 CopyB2T: ['all', 'stencil-only'],
260 CopyT2B: ['all', 'stencil-only'],
261 },
262} as const;
263
264export function depthStencilBufferTextureCopySupported(
265 type: 'CopyB2T' | 'CopyT2B',
266 format: DepthStencilFormat,
267 aspect: GPUTextureAspect
268): boolean {
269 const supportedAspects: readonly GPUTextureAspect[] =
270 kDepthStencilFormatCapabilityInBufferTextureCopy[format][type];
271 return supportedAspects.includes(aspect);
272}
273
Kai Ninomiya3a50e8b2020-04-28 20:38:31 -0700274export const kTextureUsageInfo: {
Kai Ninomiya21f8f992020-06-09 15:41:32 -0700275 readonly [k in GPUTextureUsage]: {};
Kai Ninomiya3a50e8b2020-04-28 20:38:31 -0700276} = {
Kai Ninomiya04e404f2020-10-23 16:02:19 -0700277 [GPUConst.TextureUsage.COPY_SRC]: {},
278 [GPUConst.TextureUsage.COPY_DST]: {},
279 [GPUConst.TextureUsage.SAMPLED]: {},
280 [GPUConst.TextureUsage.STORAGE]: {},
Brandon Jonesd048d11d2021-02-01 18:11:48 -0800281 [GPUConst.TextureUsage.RENDER_ATTACHMENT]: {},
Kai Ninomiya3a50e8b2020-04-28 20:38:31 -0700282};
Kai Ninomiya21f8f992020-06-09 15:41:32 -0700283export const kTextureUsages = numericKeysOf<GPUTextureUsage>(kTextureUsageInfo);
Kai Ninomiya3a50e8b2020-04-28 20:38:31 -0700284
Yunchao Head960542020-07-15 11:20:51 -0700285export const kTextureComponentTypeInfo: {
286 readonly [k in GPUTextureComponentType]: {
287 // Add fields as needed
288 };
289} = /* prettier-ignore */ {
290 'float': {},
291 'sint': {},
292 'uint': {},
Corentin Wallez1730ead2020-11-10 02:47:53 +0100293 'depth-comparison': {},
Yunchao Head960542020-07-15 11:20:51 -0700294};
295export const kTextureComponentTypes = keysOf(kTextureComponentTypeInfo);
296
297// Texture View
298
299export const kTextureViewDimensionInfo: {
300 readonly [k in GPUTextureViewDimension]: {
Yunchao Hecb0d5bb2020-07-27 11:01:12 -0700301 readonly storage: boolean;
Yunchao Head960542020-07-15 11:20:51 -0700302 // Add fields as needed
303 };
304} = /* prettier-ignore */ {
Yunchao Hecb0d5bb2020-07-27 11:01:12 -0700305 '1d': { storage: true },
306 '2d': { storage: true },
307 '2d-array': { storage: true },
308 'cube': { storage: false },
309 'cube-array': { storage: false },
310 '3d': { storage: true },
Yunchao Head960542020-07-15 11:20:51 -0700311};
312export const kTextureViewDimensions = keysOf(kTextureViewDimensionInfo);
313
Corentin Wallez056afcf2021-03-11 07:26:23 +0000314// Vertex formats
315
316export const kVertexFormatInfo = /* prettier-ignore */ makeTable(
317 ['bytesPerComponent', 'type', 'componentCount'] as const,
318 [ , , ] as const, {
319 // 8 bit components
320 'uint8x2': [ 1, 'uint', 2],
321 'uint8x4': [ 1, 'uint', 4],
322 'sint8x2': [ 1, 'sint', 2],
323 'sint8x4': [ 1, 'sint', 4],
324 'unorm8x2': [ 1, 'unorm', 2],
325 'unorm8x4': [ 1, 'unorm', 4],
326 'snorm8x2': [ 1, 'snorm', 2],
327 'snorm8x4': [ 1, 'snorm', 4],
328 // 16 bit components
329 'uint16x2': [ 2, 'uint', 2],
330 'uint16x4': [ 2, 'uint', 4],
331 'sint16x2': [ 2, 'sint', 2],
332 'sint16x4': [ 2, 'sint', 4],
333 'unorm16x2': [ 2, 'unorm', 2],
334 'unorm16x4': [ 2, 'unorm', 4],
335 'snorm16x2': [ 2, 'snorm', 2],
336 'snorm16x4': [ 2, 'snorm', 4],
337 'float16x2': [ 2, 'float', 2],
338 'float16x4': [ 2, 'float', 4],
339 // 32 bit components
340 'float32': [ 4, 'float', 1],
341 'float32x2': [ 4, 'float', 2],
342 'float32x3': [ 4, 'float', 3],
343 'float32x4': [ 4, 'float', 4],
344 'uint32': [ 4, 'uint', 1],
345 'uint32x2': [ 4, 'uint', 2],
346 'uint32x3': [ 4, 'uint', 3],
347 'uint32x4': [ 4, 'uint', 4],
348 'sint32': [ 4, 'sint', 1],
349 'sint32x2': [ 4, 'sint', 2],
350 'sint32x3': [ 4, 'sint', 3],
351 'sint32x4': [ 4, 'sint', 4]
352} as const);
353export type VertexFormat = keyof typeof kVertexFormatInfo;
354export const kVertexFormats = keysOf(kVertexFormatInfo);
355
Kai Ninomiya3a50e8b2020-04-28 20:38:31 -0700356// Typedefs for bindings
357
358export type PerStageBindingLimitClass =
359 | 'uniformBuf'
360 | 'storageBuf'
361 | 'sampler'
362 | 'sampledTex'
363 | 'storageTex';
364export type PerPipelineBindingLimitClass = PerStageBindingLimitClass;
365
366type ValidBindableResource =
367 | 'uniformBuf'
368 | 'storageBuf'
369 | 'plainSamp'
370 | 'compareSamp'
371 | 'sampledTex'
Kai Ninomiya6c4d36b2020-12-18 13:40:50 -0800372 | 'sampledTexMS'
Kai Ninomiya3a50e8b2020-04-28 20:38:31 -0700373 | 'storageTex';
374type ErrorBindableResource = 'errorBuf' | 'errorSamp' | 'errorTex';
375export type BindableResource = ValidBindableResource | ErrorBindableResource;
376
377type BufferBindingType = 'uniform-buffer' | 'storage-buffer' | 'readonly-storage-buffer';
378type SamplerBindingType = 'sampler' | 'comparison-sampler';
379type TextureBindingType =
380 | 'sampled-texture'
Corentin Wallez1730ead2020-11-10 02:47:53 +0100381 | 'multisampled-texture'
Kai Ninomiya3a50e8b2020-04-28 20:38:31 -0700382 | 'writeonly-storage-texture'
383 | 'readonly-storage-texture';
Austin Eng212317f2020-04-16 17:22:27 -0700384
Justin Fan5d1b8c72020-01-15 16:03:37 -0800385// Bindings
386
387export const kMaxBindingsPerBindGroup = 16;
388
Justin Fan5d1b8c72020-01-15 16:03:37 -0800389export const kPerStageBindingLimits: {
Kai Ninomiya3a50e8b2020-04-28 20:38:31 -0700390 readonly [k in PerStageBindingLimitClass]: {
391 readonly class: k;
392 readonly max: number;
Kai Ninomiya86b055d2020-01-06 19:37:25 -0800393 // Add fields as needed
394 };
395} = /* prettier-ignore */ {
Kai Ninomiya3a50e8b2020-04-28 20:38:31 -0700396 'uniformBuf': { class: 'uniformBuf', max: 12, },
397 'storageBuf': { class: 'storageBuf', max: 4, },
398 'sampler': { class: 'sampler', max: 16, },
399 'sampledTex': { class: 'sampledTex', max: 16, },
400 'storageTex': { class: 'storageTex', max: 4, },
Kai Ninomiya86b055d2020-01-06 19:37:25 -0800401};
Kai Ninomiya86b055d2020-01-06 19:37:25 -0800402
Kai Ninomiya3a50e8b2020-04-28 20:38:31 -0700403export const kPerPipelineBindingLimits: {
404 readonly [k in PerPipelineBindingLimitClass]: {
405 readonly class: k;
406 readonly maxDynamic: number;
407 // Add fields as needed
408 };
409} = /* prettier-ignore */ {
410 'uniformBuf': { class: 'uniformBuf', maxDynamic: 8, },
411 'storageBuf': { class: 'storageBuf', maxDynamic: 4, },
412 'sampler': { class: 'sampler', maxDynamic: 0, },
413 'sampledTex': { class: 'sampledTex', maxDynamic: 0, },
414 'storageTex': { class: 'storageTex', maxDynamic: 0, },
415};
416
417const kBindableResource: {
418 readonly [k in BindableResource]: {};
419} = /* prettier-ignore */ {
Kai Ninomiya6c4d36b2020-12-18 13:40:50 -0800420 uniformBuf: {},
421 storageBuf: {},
422 plainSamp: {},
423 compareSamp: {},
424 sampledTex: {},
425 sampledTexMS: {},
426 storageTex: {},
427 errorBuf: {},
428 errorSamp: {},
429 errorTex: {},
Kai Ninomiya3a50e8b2020-04-28 20:38:31 -0700430};
431export const kBindableResources = keysOf(kBindableResource);
432
433interface BindingKindInfo {
434 readonly resource: ValidBindableResource;
435 readonly perStageLimitClass: typeof kPerStageBindingLimits[PerStageBindingLimitClass];
436 readonly perPipelineLimitClass: typeof kPerPipelineBindingLimits[PerPipelineBindingLimitClass];
437 // Add fields as needed
438}
439
440const kBindingKind: {
441 readonly [k in ValidBindableResource]: BindingKindInfo;
442} = /* prettier-ignore */ {
Kai Ninomiya6c4d36b2020-12-18 13:40:50 -0800443 uniformBuf: { resource: 'uniformBuf', perStageLimitClass: kPerStageBindingLimits.uniformBuf, perPipelineLimitClass: kPerPipelineBindingLimits.uniformBuf, },
444 storageBuf: { resource: 'storageBuf', perStageLimitClass: kPerStageBindingLimits.storageBuf, perPipelineLimitClass: kPerPipelineBindingLimits.storageBuf, },
445 plainSamp: { resource: 'plainSamp', perStageLimitClass: kPerStageBindingLimits.sampler, perPipelineLimitClass: kPerPipelineBindingLimits.sampler, },
446 compareSamp: { resource: 'compareSamp', perStageLimitClass: kPerStageBindingLimits.sampler, perPipelineLimitClass: kPerPipelineBindingLimits.sampler, },
447 sampledTex: { resource: 'sampledTex', perStageLimitClass: kPerStageBindingLimits.sampledTex, perPipelineLimitClass: kPerPipelineBindingLimits.sampledTex, },
448 sampledTexMS: { resource: 'sampledTexMS', perStageLimitClass: kPerStageBindingLimits.sampledTex, perPipelineLimitClass: kPerPipelineBindingLimits.sampledTex, },
449 storageTex: { resource: 'storageTex', perStageLimitClass: kPerStageBindingLimits.storageTex, perPipelineLimitClass: kPerPipelineBindingLimits.storageTex, },
Kai Ninomiya3a50e8b2020-04-28 20:38:31 -0700450};
451
452// Binding type info
453
454interface BindingTypeInfo extends BindingKindInfo {
455 readonly validStages: GPUShaderStageFlags;
456 // Add fields as needed
457}
458const kValidStagesAll = {
Kai Ninomiya04e404f2020-10-23 16:02:19 -0700459 validStages:
460 GPUConst.ShaderStage.VERTEX | GPUConst.ShaderStage.FRAGMENT | GPUConst.ShaderStage.COMPUTE,
Kai Ninomiya3a50e8b2020-04-28 20:38:31 -0700461};
Kai Ninomiya04e404f2020-10-23 16:02:19 -0700462const kValidStagesStorageWrite = {
463 validStages: GPUConst.ShaderStage.FRAGMENT | GPUConst.ShaderStage.COMPUTE,
464};
Kai Ninomiya3a50e8b2020-04-28 20:38:31 -0700465
466export const kBufferBindingTypeInfo: {
467 readonly [k in BufferBindingType]: {
Kai Ninomiya21f8f992020-06-09 15:41:32 -0700468 readonly usage: GPUBufferUsage;
Kai Ninomiya3a50e8b2020-04-28 20:38:31 -0700469 // Add fields as needed
470 } & BindingTypeInfo;
471} = /* prettier-ignore */ {
Kai Ninomiya04e404f2020-10-23 16:02:19 -0700472 'uniform-buffer': { usage: GPUConst.BufferUsage.UNIFORM, ...kBindingKind.uniformBuf, ...kValidStagesAll, },
473 'storage-buffer': { usage: GPUConst.BufferUsage.STORAGE, ...kBindingKind.storageBuf, ...kValidStagesStorageWrite, },
474 'readonly-storage-buffer': { usage: GPUConst.BufferUsage.STORAGE, ...kBindingKind.storageBuf, ...kValidStagesAll, },
Kai Ninomiya3a50e8b2020-04-28 20:38:31 -0700475};
476export const kBufferBindingTypes = keysOf(kBufferBindingTypeInfo);
477
478export const kSamplerBindingTypeInfo: {
479 readonly [k in SamplerBindingType]: {
480 // Add fields as needed
481 } & BindingTypeInfo;
482} = /* prettier-ignore */ {
483 'sampler': { ...kBindingKind.plainSamp, ...kValidStagesAll, },
484 'comparison-sampler': { ...kBindingKind.compareSamp, ...kValidStagesAll, },
485};
486export const kSamplerBindingTypes = keysOf(kSamplerBindingTypeInfo);
487
488export const kTextureBindingTypeInfo: {
489 readonly [k in TextureBindingType]: {
Kai Ninomiya21f8f992020-06-09 15:41:32 -0700490 readonly usage: GPUTextureUsage;
Kai Ninomiya3a50e8b2020-04-28 20:38:31 -0700491 // Add fields as needed
492 } & BindingTypeInfo;
493} = /* prettier-ignore */ {
Kai Ninomiya6c4d36b2020-12-18 13:40:50 -0800494 'sampled-texture': { usage: GPUConst.TextureUsage.SAMPLED, ...kBindingKind.sampledTex, ...kValidStagesAll, },
495 'multisampled-texture': { usage: GPUConst.TextureUsage.SAMPLED, ...kBindingKind.sampledTexMS, ...kValidStagesAll, },
496 'writeonly-storage-texture': { usage: GPUConst.TextureUsage.STORAGE, ...kBindingKind.storageTex, ...kValidStagesStorageWrite, },
497 'readonly-storage-texture': { usage: GPUConst.TextureUsage.STORAGE, ...kBindingKind.storageTex, ...kValidStagesAll, },
Kai Ninomiya3a50e8b2020-04-28 20:38:31 -0700498};
499export const kTextureBindingTypes = keysOf(kTextureBindingTypeInfo);
500
501// All binding types (merged from above)
502
503export const kBindingTypeInfo: {
504 readonly [k in GPUBindingType]: BindingTypeInfo;
505} = {
506 ...kBufferBindingTypeInfo,
507 ...kSamplerBindingTypeInfo,
508 ...kTextureBindingTypeInfo,
509};
510export const kBindingTypes = keysOf(kBindingTypeInfo);
511
512export const kShaderStages: readonly GPUShaderStageFlags[] = [
Kai Ninomiya04e404f2020-10-23 16:02:19 -0700513 GPUConst.ShaderStage.VERTEX,
514 GPUConst.ShaderStage.FRAGMENT,
515 GPUConst.ShaderStage.COMPUTE,
Justin Fan5d1b8c72020-01-15 16:03:37 -0800516];
Kai Ninomiya3a50e8b2020-04-28 20:38:31 -0700517export const kShaderStageCombinations: readonly GPUShaderStageFlags[] = [0, 1, 2, 3, 4, 5, 6, 7];
Enrico Galli94e47e92020-12-16 14:31:50 -0800518
519// TODO: Update with all possible sample counts when defined
520// TODO: Switch existing tests to use kTextureSampleCounts
521export const kTextureSampleCounts = [1, 4] as const;
522
Corentin Wallez7aa4fda2021-03-09 04:17:33 +0100523// Pipeline limits
524
Enrico Galli94e47e92020-12-16 14:31:50 -0800525// TODO: Update maximum color attachments when defined
526export const kMaxColorAttachments = 4;
Corentin Wallez7aa4fda2021-03-09 04:17:33 +0100527
528export const kMaxVertexBuffers = 8;
529export const kMaxVertexAttributes = 16;
530export const kMaxVertexBufferArrayStride = 2048;