Kai Ninomiya | f0d24f3 | 2020-12-11 16:42:29 -0800 | [diff] [blame] | 1 | /* eslint-disable no-sparse-arrays */ |
| 2 | import { ResolveType, ZipKeysWithValues } from '../common/framework/util/types.js'; |
| 3 | |
Kai Ninomiya | 04e404f | 2020-10-23 16:02:19 -0700 | [diff] [blame] | 4 | import { GPUConst } from './constants.js'; |
| 5 | |
Kai Ninomiya | 21f8f99 | 2020-06-09 15:41:32 -0700 | [diff] [blame] | 6 | type valueof<K> = K[keyof K]; |
| 7 | type GPUTextureUsage = valueof<typeof GPUTextureUsage>; |
| 8 | type GPUBufferUsage = valueof<typeof GPUBufferUsage>; |
Justin Fan | 5d1b8c7 | 2020-01-15 16:03:37 -0800 | [diff] [blame] | 9 | |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 10 | function keysOf<T extends string>(obj: { [k in T]: unknown }): readonly T[] { |
| 11 | return (Object.keys(obj) as unknown[]) as T[]; |
| 12 | } |
| 13 | |
| 14 | function numericKeysOf<T>(obj: object): readonly T[] { |
| 15 | return (Object.keys(obj).map(n => Number(n)) as unknown[]) as T[]; |
| 16 | } |
| 17 | |
Kai Ninomiya | f0d24f3 | 2020-12-11 16:42:29 -0800 | [diff] [blame] | 18 | /** |
| 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 | */ |
| 23 | function 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 Li | ab18a1b | 2021-01-28 06:16:50 +0800 | [diff] [blame] | 46 | // Queries |
| 47 | |
| 48 | export const kMaxQueryCount = 8192; |
| 49 | export const kQueryTypes = ['occlusion', 'pipeline-statistics', 'timestamp'] as const; |
| 50 | |
Kai Ninomiya | be420af | 2020-07-24 18:32:40 -0700 | [diff] [blame] | 51 | // Buffers |
| 52 | |
Kai Ninomiya | 84b7ab1 | 2020-11-20 12:33:12 -0800 | [diff] [blame] | 53 | export const kBufferSizeAlignment = 4; |
| 54 | |
Kai Ninomiya | be420af | 2020-07-24 18:32:40 -0700 | [diff] [blame] | 55 | export const kBufferUsageInfo: { |
| 56 | readonly [k in GPUBufferUsage]: {}; |
| 57 | } = /* prettier-ignore */ { |
Kai Ninomiya | 04e404f | 2020-10-23 16:02:19 -0700 | [diff] [blame] | 58 | [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 Ninomiya | be420af | 2020-07-24 18:32:40 -0700 | [diff] [blame] | 68 | }; |
| 69 | export const kBufferUsages = numericKeysOf<GPUBufferUsage>(kBufferUsageInfo); |
| 70 | |
Justin Fan | 5d1b8c7 | 2020-01-15 16:03:37 -0800 | [diff] [blame] | 71 | // Textures |
| 72 | |
Kai Ninomiya | f0d24f3 | 2020-12-11 16:42:29 -0800 | [diff] [blame] | 73 | export const kRegularTextureFormatInfo = /* prettier-ignore */ makeTable( |
Yunchao He | 23f4271 | 2021-03-08 23:37:00 -0800 | [diff] [blame] | 74 | ['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 Ninomiya | ea9e36f | 2019-10-18 20:01:03 -0700 | [diff] [blame] | 76 | // 8-bit formats |
Yunchao He | 23f4271 | 2021-03-08 23:37:00 -0800 | [diff] [blame] | 77 | 'r8unorm': [ true, , , , , false, , , 1], |
| 78 | 'r8snorm': [ false, , , , , false, , , 1], |
| 79 | 'r8uint': [ true, , , , , false, , , 1], |
| 80 | 'r8sint': [ true, , , , , false, , , 1], |
Kai Ninomiya | ea9e36f | 2019-10-18 20:01:03 -0700 | [diff] [blame] | 81 | // 16-bit formats |
Yunchao He | 23f4271 | 2021-03-08 23:37:00 -0800 | [diff] [blame] | 82 | '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 Ninomiya | ea9e36f | 2019-10-18 20:01:03 -0700 | [diff] [blame] | 89 | // 32-bit formats |
Yunchao He | 23f4271 | 2021-03-08 23:37:00 -0800 | [diff] [blame] | 90 | '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 Ninomiya | ea9e36f | 2019-10-18 20:01:03 -0700 | [diff] [blame] | 103 | // Packed 32-bit formats |
Yunchao He | 23f4271 | 2021-03-08 23:37:00 -0800 | [diff] [blame] | 104 | 'rgb10a2unorm': [ true, , , , , false, , , 4], |
| 105 | 'rg11b10ufloat': [ false, , , , , false, , , 4], |
| 106 | 'rgb9e5ufloat': [ false, , , , , false, , , 4], |
Kai Ninomiya | ea9e36f | 2019-10-18 20:01:03 -0700 | [diff] [blame] | 107 | // 64-bit formats |
Yunchao He | 23f4271 | 2021-03-08 23:37:00 -0800 | [diff] [blame] | 108 | '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 Ninomiya | ea9e36f | 2019-10-18 20:01:03 -0700 | [diff] [blame] | 114 | // 128-bit formats |
Yunchao He | 23f4271 | 2021-03-08 23:37:00 -0800 | [diff] [blame] | 115 | 'rgba32uint': [ true, , , , , true, , , 16], |
| 116 | 'rgba32sint': [ true, , , , , true, , , 16], |
| 117 | 'rgba32float': [ true, , , , , true, , , 16], |
Kai Ninomiya | f0d24f3 | 2020-12-11 16:42:29 -0800 | [diff] [blame] | 118 | } as const); |
| 119 | /* prettier-ignore */ |
Yunchao He | 23f4271 | 2021-03-08 23:37:00 -0800 | [diff] [blame] | 120 | const kTexFmtInfoHeader = ['renderable', 'multisample', 'color', 'depth', 'stencil', 'storage', 'copySrc', 'copyDst', 'bytesPerBlock', 'blockWidth', 'blockHeight', 'extension'] as const; |
Kai Ninomiya | f0d24f3 | 2020-12-11 16:42:29 -0800 | [diff] [blame] | 121 | export const kSizedDepthStencilFormatInfo = /* prettier-ignore */ makeTable(kTexFmtInfoHeader, |
Yunchao He | 23f4271 | 2021-03-08 23:37:00 -0800 | [diff] [blame] | 122 | [ 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 Ninomiya | f0d24f3 | 2020-12-11 16:42:29 -0800 | [diff] [blame] | 126 | } as const); |
| 127 | export const kUnsizedDepthStencilFormatInfo = /* prettier-ignore */ makeTable(kTexFmtInfoHeader, |
Yunchao He | 23f4271 | 2021-03-08 23:37:00 -0800 | [diff] [blame] | 128 | [ true, true, false, , , false, , , undefined, 1, 1, ] as const, { |
| 129 | 'depth24plus': [ , , , true, false, , false, false], |
| 130 | 'depth24plus-stencil8': [ , , , true, true, , false, false], |
Yunchao He | d50dfc5 | 2021-02-25 16:35:07 -0800 | [diff] [blame] | 131 | // 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 He | 23f4271 | 2021-03-08 23:37:00 -0800 | [diff] [blame] | 132 | 'depth24unorm-stencil8': [ , , , true, true, , false, false, , , , 'depth24unorm-stencil8'], |
| 133 | 'depth32float-stencil8': [ , , , true, true, , false, false, , , , 'depth32float-stencil8'], |
Kai Ninomiya | f0d24f3 | 2020-12-11 16:42:29 -0800 | [diff] [blame] | 134 | } as const); |
| 135 | export const kCompressedTextureFormatInfo = /* prettier-ignore */ makeTable(kTexFmtInfoHeader, |
Yunchao He | 23f4271 | 2021-03-08 23:37:00 -0800 | [diff] [blame] | 136 | [ 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 Ninomiya | f0d24f3 | 2020-12-11 16:42:29 -0800 | [diff] [blame] | 151 | } as const); |
| 152 | |
Kai Ninomiya | a9ea59f | 2021-02-10 16:13:49 -0800 | [diff] [blame] | 153 | export type RegularTextureFormat = keyof typeof kRegularTextureFormatInfo; |
| 154 | export type SizedDepthStencilFormat = keyof typeof kSizedDepthStencilFormatInfo; |
| 155 | export type UnsizedDepthStencilFormat = keyof typeof kUnsizedDepthStencilFormatInfo; |
| 156 | export type CompressedTextureFormat = keyof typeof kCompressedTextureFormatInfo; |
| 157 | |
Kai Ninomiya | ebef147 | 2020-08-14 15:21:09 -0700 | [diff] [blame] | 158 | export const kRegularTextureFormats = keysOf(kRegularTextureFormatInfo); |
Kai Ninomiya | ebef147 | 2020-08-14 15:21:09 -0700 | [diff] [blame] | 159 | export const kSizedDepthStencilFormats = keysOf(kSizedDepthStencilFormatInfo); |
Kai Ninomiya | ebef147 | 2020-08-14 15:21:09 -0700 | [diff] [blame] | 160 | export const kUnsizedDepthStencilFormats = keysOf(kUnsizedDepthStencilFormatInfo); |
Kai Ninomiya | ebef147 | 2020-08-14 15:21:09 -0700 | [diff] [blame] | 161 | export const kCompressedTextureFormats = keysOf(kCompressedTextureFormatInfo); |
| 162 | |
| 163 | export const kColorTextureFormatInfo = { |
| 164 | ...kRegularTextureFormatInfo, |
| 165 | ...kCompressedTextureFormatInfo, |
| 166 | } as const; |
| 167 | export type ColorTextureFormat = keyof typeof kColorTextureFormatInfo; |
| 168 | export const kColorTextureFormats = keysOf(kColorTextureFormatInfo); |
| 169 | |
| 170 | export const kEncodableTextureFormatInfo = { |
| 171 | ...kRegularTextureFormatInfo, |
| 172 | ...kSizedDepthStencilFormatInfo, |
| 173 | } as const; |
| 174 | export type EncodableTextureFormat = keyof typeof kEncodableTextureFormatInfo; |
| 175 | export const kEncodableTextureFormats = keysOf(kEncodableTextureFormatInfo); |
| 176 | |
| 177 | export const kSizedTextureFormatInfo = { |
| 178 | ...kRegularTextureFormatInfo, |
| 179 | ...kSizedDepthStencilFormatInfo, |
| 180 | ...kCompressedTextureFormatInfo, |
| 181 | } as const; |
| 182 | export type SizedTextureFormat = keyof typeof kSizedTextureFormatInfo; |
| 183 | export const kSizedTextureFormats = keysOf(kSizedTextureFormatInfo); |
| 184 | |
| 185 | export const kDepthStencilFormatInfo = { |
| 186 | ...kSizedDepthStencilFormatInfo, |
| 187 | ...kUnsizedDepthStencilFormatInfo, |
| 188 | } as const; |
| 189 | export type DepthStencilFormat = keyof typeof kDepthStencilFormatInfo; |
| 190 | export const kDepthStencilFormats = keysOf(kDepthStencilFormatInfo); |
| 191 | |
| 192 | export const kUncompressedTextureFormatInfo = { |
| 193 | ...kRegularTextureFormatInfo, |
| 194 | ...kSizedDepthStencilFormatInfo, |
| 195 | ...kUnsizedDepthStencilFormatInfo, |
| 196 | } as const; |
| 197 | export type UncompressedTextureFormat = keyof typeof kUncompressedTextureFormatInfo; |
| 198 | export const kUncompressedTextureFormats = keysOf(kUncompressedTextureFormatInfo); |
| 199 | |
Kai Ninomiya | f0d24f3 | 2020-12-11 16:42:29 -0800 | [diff] [blame] | 200 | export const kAllTextureFormatInfo = { |
Kai Ninomiya | ebef147 | 2020-08-14 15:21:09 -0700 | [diff] [blame] | 201 | ...kUncompressedTextureFormatInfo, |
| 202 | ...kCompressedTextureFormatInfo, |
| 203 | } as const; |
| 204 | export const kAllTextureFormats = keysOf(kAllTextureFormatInfo); |
Kai Ninomiya | f0d24f3 | 2020-12-11 16:42:29 -0800 | [diff] [blame] | 205 | // Assert every GPUTextureFormat is covered by one of the tables. |
| 206 | ((x: { readonly [k in GPUTextureFormat]: {} }) => x)(kAllTextureFormatInfo); |
Kai Ninomiya | 86b055d | 2020-01-06 19:37:25 -0800 | [diff] [blame] | 207 | |
Austin Eng | 212317f | 2020-04-16 17:22:27 -0700 | [diff] [blame] | 208 | export const kTextureDimensionInfo: { |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 209 | readonly [k in GPUTextureDimension]: { |
Austin Eng | 212317f | 2020-04-16 17:22:27 -0700 | [diff] [blame] | 210 | // Add fields as needed |
| 211 | }; |
| 212 | } = /* prettier-ignore */ { |
| 213 | '1d': {}, |
| 214 | '2d': {}, |
| 215 | '3d': {}, |
| 216 | }; |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 217 | export const kTextureDimensions = keysOf(kTextureDimensionInfo); |
Austin Eng | 212317f | 2020-04-16 17:22:27 -0700 | [diff] [blame] | 218 | |
| 219 | export const kTextureAspectInfo: { |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 220 | readonly [k in GPUTextureAspect]: { |
Austin Eng | 212317f | 2020-04-16 17:22:27 -0700 | [diff] [blame] | 221 | // Add fields as needed |
| 222 | }; |
| 223 | } = /* prettier-ignore */ { |
| 224 | 'all': {}, |
| 225 | 'depth-only': {}, |
| 226 | 'stencil-only': {}, |
| 227 | }; |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 228 | export const kTextureAspects = keysOf(kTextureAspectInfo); |
| 229 | |
Jiawei Shao | a9ac8c3 | 2021-03-04 02:53:13 +0800 | [diff] [blame] | 230 | const 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 | |
| 264 | export 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 Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 274 | export const kTextureUsageInfo: { |
Kai Ninomiya | 21f8f99 | 2020-06-09 15:41:32 -0700 | [diff] [blame] | 275 | readonly [k in GPUTextureUsage]: {}; |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 276 | } = { |
Kai Ninomiya | 04e404f | 2020-10-23 16:02:19 -0700 | [diff] [blame] | 277 | [GPUConst.TextureUsage.COPY_SRC]: {}, |
| 278 | [GPUConst.TextureUsage.COPY_DST]: {}, |
| 279 | [GPUConst.TextureUsage.SAMPLED]: {}, |
| 280 | [GPUConst.TextureUsage.STORAGE]: {}, |
Brandon Jones | d048d11d | 2021-02-01 18:11:48 -0800 | [diff] [blame] | 281 | [GPUConst.TextureUsage.RENDER_ATTACHMENT]: {}, |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 282 | }; |
Kai Ninomiya | 21f8f99 | 2020-06-09 15:41:32 -0700 | [diff] [blame] | 283 | export const kTextureUsages = numericKeysOf<GPUTextureUsage>(kTextureUsageInfo); |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 284 | |
Yunchao He | ad96054 | 2020-07-15 11:20:51 -0700 | [diff] [blame] | 285 | export const kTextureComponentTypeInfo: { |
| 286 | readonly [k in GPUTextureComponentType]: { |
| 287 | // Add fields as needed |
| 288 | }; |
| 289 | } = /* prettier-ignore */ { |
| 290 | 'float': {}, |
| 291 | 'sint': {}, |
| 292 | 'uint': {}, |
Corentin Wallez | 1730ead | 2020-11-10 02:47:53 +0100 | [diff] [blame] | 293 | 'depth-comparison': {}, |
Yunchao He | ad96054 | 2020-07-15 11:20:51 -0700 | [diff] [blame] | 294 | }; |
| 295 | export const kTextureComponentTypes = keysOf(kTextureComponentTypeInfo); |
| 296 | |
| 297 | // Texture View |
| 298 | |
| 299 | export const kTextureViewDimensionInfo: { |
| 300 | readonly [k in GPUTextureViewDimension]: { |
Yunchao He | cb0d5bb | 2020-07-27 11:01:12 -0700 | [diff] [blame] | 301 | readonly storage: boolean; |
Yunchao He | ad96054 | 2020-07-15 11:20:51 -0700 | [diff] [blame] | 302 | // Add fields as needed |
| 303 | }; |
| 304 | } = /* prettier-ignore */ { |
Yunchao He | cb0d5bb | 2020-07-27 11:01:12 -0700 | [diff] [blame] | 305 | '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 He | ad96054 | 2020-07-15 11:20:51 -0700 | [diff] [blame] | 311 | }; |
| 312 | export const kTextureViewDimensions = keysOf(kTextureViewDimensionInfo); |
| 313 | |
Corentin Wallez | 056afcf | 2021-03-11 07:26:23 +0000 | [diff] [blame^] | 314 | // Vertex formats |
| 315 | |
| 316 | export 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); |
| 353 | export type VertexFormat = keyof typeof kVertexFormatInfo; |
| 354 | export const kVertexFormats = keysOf(kVertexFormatInfo); |
| 355 | |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 356 | // Typedefs for bindings |
| 357 | |
| 358 | export type PerStageBindingLimitClass = |
| 359 | | 'uniformBuf' |
| 360 | | 'storageBuf' |
| 361 | | 'sampler' |
| 362 | | 'sampledTex' |
| 363 | | 'storageTex'; |
| 364 | export type PerPipelineBindingLimitClass = PerStageBindingLimitClass; |
| 365 | |
| 366 | type ValidBindableResource = |
| 367 | | 'uniformBuf' |
| 368 | | 'storageBuf' |
| 369 | | 'plainSamp' |
| 370 | | 'compareSamp' |
| 371 | | 'sampledTex' |
Kai Ninomiya | 6c4d36b | 2020-12-18 13:40:50 -0800 | [diff] [blame] | 372 | | 'sampledTexMS' |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 373 | | 'storageTex'; |
| 374 | type ErrorBindableResource = 'errorBuf' | 'errorSamp' | 'errorTex'; |
| 375 | export type BindableResource = ValidBindableResource | ErrorBindableResource; |
| 376 | |
| 377 | type BufferBindingType = 'uniform-buffer' | 'storage-buffer' | 'readonly-storage-buffer'; |
| 378 | type SamplerBindingType = 'sampler' | 'comparison-sampler'; |
| 379 | type TextureBindingType = |
| 380 | | 'sampled-texture' |
Corentin Wallez | 1730ead | 2020-11-10 02:47:53 +0100 | [diff] [blame] | 381 | | 'multisampled-texture' |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 382 | | 'writeonly-storage-texture' |
| 383 | | 'readonly-storage-texture'; |
Austin Eng | 212317f | 2020-04-16 17:22:27 -0700 | [diff] [blame] | 384 | |
Justin Fan | 5d1b8c7 | 2020-01-15 16:03:37 -0800 | [diff] [blame] | 385 | // Bindings |
| 386 | |
| 387 | export const kMaxBindingsPerBindGroup = 16; |
| 388 | |
Justin Fan | 5d1b8c7 | 2020-01-15 16:03:37 -0800 | [diff] [blame] | 389 | export const kPerStageBindingLimits: { |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 390 | readonly [k in PerStageBindingLimitClass]: { |
| 391 | readonly class: k; |
| 392 | readonly max: number; |
Kai Ninomiya | 86b055d | 2020-01-06 19:37:25 -0800 | [diff] [blame] | 393 | // Add fields as needed |
| 394 | }; |
| 395 | } = /* prettier-ignore */ { |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 396 | '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 Ninomiya | 86b055d | 2020-01-06 19:37:25 -0800 | [diff] [blame] | 401 | }; |
Kai Ninomiya | 86b055d | 2020-01-06 19:37:25 -0800 | [diff] [blame] | 402 | |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 403 | export 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 | |
| 417 | const kBindableResource: { |
| 418 | readonly [k in BindableResource]: {}; |
| 419 | } = /* prettier-ignore */ { |
Kai Ninomiya | 6c4d36b | 2020-12-18 13:40:50 -0800 | [diff] [blame] | 420 | uniformBuf: {}, |
| 421 | storageBuf: {}, |
| 422 | plainSamp: {}, |
| 423 | compareSamp: {}, |
| 424 | sampledTex: {}, |
| 425 | sampledTexMS: {}, |
| 426 | storageTex: {}, |
| 427 | errorBuf: {}, |
| 428 | errorSamp: {}, |
| 429 | errorTex: {}, |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 430 | }; |
| 431 | export const kBindableResources = keysOf(kBindableResource); |
| 432 | |
| 433 | interface BindingKindInfo { |
| 434 | readonly resource: ValidBindableResource; |
| 435 | readonly perStageLimitClass: typeof kPerStageBindingLimits[PerStageBindingLimitClass]; |
| 436 | readonly perPipelineLimitClass: typeof kPerPipelineBindingLimits[PerPipelineBindingLimitClass]; |
| 437 | // Add fields as needed |
| 438 | } |
| 439 | |
| 440 | const kBindingKind: { |
| 441 | readonly [k in ValidBindableResource]: BindingKindInfo; |
| 442 | } = /* prettier-ignore */ { |
Kai Ninomiya | 6c4d36b | 2020-12-18 13:40:50 -0800 | [diff] [blame] | 443 | 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 Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 450 | }; |
| 451 | |
| 452 | // Binding type info |
| 453 | |
| 454 | interface BindingTypeInfo extends BindingKindInfo { |
| 455 | readonly validStages: GPUShaderStageFlags; |
| 456 | // Add fields as needed |
| 457 | } |
| 458 | const kValidStagesAll = { |
Kai Ninomiya | 04e404f | 2020-10-23 16:02:19 -0700 | [diff] [blame] | 459 | validStages: |
| 460 | GPUConst.ShaderStage.VERTEX | GPUConst.ShaderStage.FRAGMENT | GPUConst.ShaderStage.COMPUTE, |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 461 | }; |
Kai Ninomiya | 04e404f | 2020-10-23 16:02:19 -0700 | [diff] [blame] | 462 | const kValidStagesStorageWrite = { |
| 463 | validStages: GPUConst.ShaderStage.FRAGMENT | GPUConst.ShaderStage.COMPUTE, |
| 464 | }; |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 465 | |
| 466 | export const kBufferBindingTypeInfo: { |
| 467 | readonly [k in BufferBindingType]: { |
Kai Ninomiya | 21f8f99 | 2020-06-09 15:41:32 -0700 | [diff] [blame] | 468 | readonly usage: GPUBufferUsage; |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 469 | // Add fields as needed |
| 470 | } & BindingTypeInfo; |
| 471 | } = /* prettier-ignore */ { |
Kai Ninomiya | 04e404f | 2020-10-23 16:02:19 -0700 | [diff] [blame] | 472 | '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 Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 475 | }; |
| 476 | export const kBufferBindingTypes = keysOf(kBufferBindingTypeInfo); |
| 477 | |
| 478 | export 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 | }; |
| 486 | export const kSamplerBindingTypes = keysOf(kSamplerBindingTypeInfo); |
| 487 | |
| 488 | export const kTextureBindingTypeInfo: { |
| 489 | readonly [k in TextureBindingType]: { |
Kai Ninomiya | 21f8f99 | 2020-06-09 15:41:32 -0700 | [diff] [blame] | 490 | readonly usage: GPUTextureUsage; |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 491 | // Add fields as needed |
| 492 | } & BindingTypeInfo; |
| 493 | } = /* prettier-ignore */ { |
Kai Ninomiya | 6c4d36b | 2020-12-18 13:40:50 -0800 | [diff] [blame] | 494 | '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 Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 498 | }; |
| 499 | export const kTextureBindingTypes = keysOf(kTextureBindingTypeInfo); |
| 500 | |
| 501 | // All binding types (merged from above) |
| 502 | |
| 503 | export const kBindingTypeInfo: { |
| 504 | readonly [k in GPUBindingType]: BindingTypeInfo; |
| 505 | } = { |
| 506 | ...kBufferBindingTypeInfo, |
| 507 | ...kSamplerBindingTypeInfo, |
| 508 | ...kTextureBindingTypeInfo, |
| 509 | }; |
| 510 | export const kBindingTypes = keysOf(kBindingTypeInfo); |
| 511 | |
| 512 | export const kShaderStages: readonly GPUShaderStageFlags[] = [ |
Kai Ninomiya | 04e404f | 2020-10-23 16:02:19 -0700 | [diff] [blame] | 513 | GPUConst.ShaderStage.VERTEX, |
| 514 | GPUConst.ShaderStage.FRAGMENT, |
| 515 | GPUConst.ShaderStage.COMPUTE, |
Justin Fan | 5d1b8c7 | 2020-01-15 16:03:37 -0800 | [diff] [blame] | 516 | ]; |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 517 | export const kShaderStageCombinations: readonly GPUShaderStageFlags[] = [0, 1, 2, 3, 4, 5, 6, 7]; |
Enrico Galli | 94e47e9 | 2020-12-16 14:31:50 -0800 | [diff] [blame] | 518 | |
| 519 | // TODO: Update with all possible sample counts when defined |
| 520 | // TODO: Switch existing tests to use kTextureSampleCounts |
| 521 | export const kTextureSampleCounts = [1, 4] as const; |
| 522 | |
Corentin Wallez | 7aa4fda | 2021-03-09 04:17:33 +0100 | [diff] [blame] | 523 | // Pipeline limits |
| 524 | |
Enrico Galli | 94e47e9 | 2020-12-16 14:31:50 -0800 | [diff] [blame] | 525 | // TODO: Update maximum color attachments when defined |
| 526 | export const kMaxColorAttachments = 4; |
Corentin Wallez | 7aa4fda | 2021-03-09 04:17:33 +0100 | [diff] [blame] | 527 | |
| 528 | export const kMaxVertexBuffers = 8; |
| 529 | export const kMaxVertexAttributes = 16; |
| 530 | export const kMaxVertexBufferArrayStride = 2048; |