Kai Ninomiya | 7c40d21 | 2022-01-04 14:25:02 -0800 | [diff] [blame] | 1 | // MAINTENANCE_TODO: The generated Typedoc for this file is hard to navigate because it's |
| 2 | // alphabetized. Consider using namespaces or renames to fix this? |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 3 | |
Kai Ninomiya | f0d24f3 | 2020-12-11 16:42:29 -0800 | [diff] [blame] | 4 | /* eslint-disable no-sparse-arrays */ |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 5 | |
Kai Ninomiya | 7cd9ff7 | 2021-06-30 20:24:01 -0700 | [diff] [blame] | 6 | import { keysOf, makeTable, numericKeysOf, valueof } from '../common/util/data_tables.js'; |
| 7 | import { assertTypeTrue, TypeEqual } from '../common/util/types.js'; |
Kai Ninomiya | 374a2c8 | 2021-06-08 18:44:42 -0700 | [diff] [blame] | 8 | import { assert, unreachable } from '../common/util/util.js'; |
Kai Ninomiya | f0d24f3 | 2020-12-11 16:42:29 -0800 | [diff] [blame] | 9 | |
Corentin Wallez | 27ca9f7 | 2022-03-30 21:01:47 +0100 | [diff] [blame] | 10 | import { GPUConst, kMaxUnsignedLongValue, kMaxUnsignedLongLongValue } from './constants.js'; |
Yunchao He | a975589 | 2021-08-19 16:49:29 -0700 | [diff] [blame] | 11 | import { ImageCopyType } from './util/texture/layout.js'; |
Kai Ninomiya | 04e404f | 2020-10-23 16:02:19 -0700 | [diff] [blame] | 12 | |
Kai Ninomiya | b61f76c | 2021-07-15 19:32:34 -0700 | [diff] [blame] | 13 | // Base device limits can be found in constants.ts. |
| 14 | |
Hao Li | ab18a1b | 2021-01-28 06:16:50 +0800 | [diff] [blame] | 15 | // Queries |
| 16 | |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 17 | /** Maximum number of queries in GPUQuerySet, by spec. */ |
Corentin Wallez | 861b209 | 2023-01-03 17:59:29 +0100 | [diff] [blame] | 18 | export const kMaxQueryCount = 4096; |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 19 | /** Per-GPUQueryType info. */ |
| 20 | export type QueryTypeInfo = { |
| 21 | /** Optional feature required to use this GPUQueryType. */ |
| 22 | readonly feature: GPUFeatureName | undefined; |
| 23 | // Add fields as needed |
| 24 | }; |
Hao Li | dceba5d | 2021-04-14 04:28:54 +0800 | [diff] [blame] | 25 | export const kQueryTypeInfo: { |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 26 | readonly [k in GPUQueryType]: QueryTypeInfo; |
Hao Li | dceba5d | 2021-04-14 04:28:54 +0800 | [diff] [blame] | 27 | } = /* prettier-ignore */ { |
Kai Ninomiya | 46b40ad | 2021-04-14 14:51:20 -0700 | [diff] [blame] | 28 | // Occlusion query does not require any features. |
| 29 | 'occlusion': { feature: undefined }, |
Kai Ninomiya | 46b40ad | 2021-04-14 14:51:20 -0700 | [diff] [blame] | 30 | 'timestamp': { feature: 'timestamp-query' }, |
Hao Li | dceba5d | 2021-04-14 04:28:54 +0800 | [diff] [blame] | 31 | }; |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 32 | /** List of all GPUQueryType values. */ |
Hao Li | dceba5d | 2021-04-14 04:28:54 +0800 | [diff] [blame] | 33 | export const kQueryTypes = keysOf(kQueryTypeInfo); |
Hao Li | ab18a1b | 2021-01-28 06:16:50 +0800 | [diff] [blame] | 34 | |
Kai Ninomiya | be420af | 2020-07-24 18:32:40 -0700 | [diff] [blame] | 35 | // Buffers |
| 36 | |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 37 | /** Required alignment of a GPUBuffer size, by spec. */ |
Kai Ninomiya | 84b7ab1 | 2020-11-20 12:33:12 -0800 | [diff] [blame] | 38 | export const kBufferSizeAlignment = 4; |
| 39 | |
Lokbondo Kung | 300c10c | 2022-03-22 10:53:42 -0700 | [diff] [blame] | 40 | /** Per-GPUBufferUsage copy info. */ |
| 41 | export const kBufferUsageCopyInfo: { |
| 42 | readonly [name: string]: GPUBufferUsageFlags; |
Kai Ninomiya | be420af | 2020-07-24 18:32:40 -0700 | [diff] [blame] | 43 | } = /* prettier-ignore */ { |
Lokbondo Kung | 300c10c | 2022-03-22 10:53:42 -0700 | [diff] [blame] | 44 | 'COPY_NONE': 0, |
| 45 | 'COPY_SRC': GPUConst.BufferUsage.COPY_SRC, |
| 46 | 'COPY_DST': GPUConst.BufferUsage.COPY_DST, |
| 47 | 'COPY_SRC_DST': GPUConst.BufferUsage.COPY_SRC | GPUConst.BufferUsage.COPY_DST, |
Kai Ninomiya | be420af | 2020-07-24 18:32:40 -0700 | [diff] [blame] | 48 | }; |
Lokbondo Kung | 300c10c | 2022-03-22 10:53:42 -0700 | [diff] [blame] | 49 | /** List of all GPUBufferUsage copy values. */ |
| 50 | export const kBufferUsageCopy = keysOf(kBufferUsageCopyInfo); |
| 51 | |
| 52 | /** Per-GPUBufferUsage keys and info. */ |
| 53 | type BufferUsageKey = keyof typeof GPUConst.BufferUsage; |
| 54 | export const kBufferUsageKeys = keysOf(GPUConst.BufferUsage); |
| 55 | export const kBufferUsageInfo: { |
| 56 | readonly [k in BufferUsageKey]: GPUBufferUsageFlags; |
| 57 | } = { |
| 58 | ...GPUConst.BufferUsage, |
| 59 | }; |
| 60 | |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 61 | /** List of all GPUBufferUsage values. */ |
Lokbondo Kung | 300c10c | 2022-03-22 10:53:42 -0700 | [diff] [blame] | 62 | export const kBufferUsages = Object.values(GPUConst.BufferUsage); |
jzm-intel | 6d8d853 | 2022-01-25 09:26:14 +0800 | [diff] [blame] | 63 | export const kAllBufferUsageBits = kBufferUsages.reduce( |
| 64 | (previousSet, currentUsage) => previousSet | currentUsage, |
| 65 | 0 |
| 66 | ); |
Kai Ninomiya | be420af | 2020-07-24 18:32:40 -0700 | [diff] [blame] | 67 | |
Lokbondo Kung | d82d4e1 | 2022-08-22 10:41:58 -0700 | [diff] [blame] | 68 | // Errors |
| 69 | |
| 70 | /** Per-GPUErrorFilter info. */ |
| 71 | export const kErrorScopeFilterInfo: { |
| 72 | readonly [k in GPUErrorFilter]: {}; |
| 73 | } = /* prettier-ignore */ { |
| 74 | 'out-of-memory': {}, |
Takahiro | cbdd47a | 2022-10-05 15:44:19 -0700 | [diff] [blame] | 75 | 'validation': {}, |
| 76 | 'internal': {}, |
Lokbondo Kung | d82d4e1 | 2022-08-22 10:41:58 -0700 | [diff] [blame] | 77 | }; |
Corentin Wallez | 0e790f3 | 2022-11-28 22:09:04 +0100 | [diff] [blame] | 78 | /** List of all GPUErrorFilter values. */ |
Lokbondo Kung | d82d4e1 | 2022-08-22 10:41:58 -0700 | [diff] [blame] | 79 | export const kErrorScopeFilters = keysOf(kErrorScopeFilterInfo); |
Corentin Wallez | 0e790f3 | 2022-11-28 22:09:04 +0100 | [diff] [blame] | 80 | export const kGeneratableErrorScopeFilters = kErrorScopeFilters.filter(e => e !== 'internal'); |
Lokbondo Kung | d82d4e1 | 2022-08-22 10:41:58 -0700 | [diff] [blame] | 81 | |
Justin Fan | 5d1b8c7 | 2020-01-15 16:03:37 -0800 | [diff] [blame] | 82 | // Textures |
| 83 | |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 84 | // Definitions for use locally. To access the table entries, use `kTextureFormatInfo`. |
| 85 | |
Yunchao He | aec5085 | 2021-03-12 15:49:18 -0800 | [diff] [blame] | 86 | // Note that we repeat the header multiple times in order to make it easier to read. |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 87 | const kRegularTextureFormatInfo = /* prettier-ignore */ makeTable( |
Lokbondo Kung | a7e54e7 | 2023-01-26 11:51:32 -0800 | [diff] [blame] | 88 | ['renderable', 'multisample', 'resolve', 'color', 'depth', 'stencil', 'storage', 'copySrc', 'copyDst', 'sampleType', 'bytesPerBlock', 'blockWidth', 'blockHeight', 'renderTargetPixelByteCost', 'renderTargetComponentAlignment', 'feature', 'baseFormat'] as const, |
| 89 | [ , , , true, false, false, , true, true, , , 1, 1, undefined, undefined, , undefined] as const, { |
Kai Ninomiya | ea9e36f | 2019-10-18 20:01:03 -0700 | [diff] [blame] | 90 | // 8-bit formats |
Lokbondo Kung | a7e54e7 | 2023-01-26 11:51:32 -0800 | [diff] [blame] | 91 | 'r8unorm': [ true, true, true, , , , false, , , 'float', 1, , , 1, 1], |
| 92 | 'r8snorm': [ false, false, false, , , , false, , , 'float', 1], |
| 93 | 'r8uint': [ true, true, false, , , , false, , , 'uint', 1, , , 1, 1], |
| 94 | 'r8sint': [ true, true, false, , , , false, , , 'sint', 1, , , 1, 1], |
Kai Ninomiya | ea9e36f | 2019-10-18 20:01:03 -0700 | [diff] [blame] | 95 | // 16-bit formats |
Lokbondo Kung | a7e54e7 | 2023-01-26 11:51:32 -0800 | [diff] [blame] | 96 | 'r16uint': [ true, true, false, , , , false, , , 'uint', 2, , , 2, 2], |
| 97 | 'r16sint': [ true, true, false, , , , false, , , 'sint', 2, , , 2, 2], |
| 98 | 'r16float': [ true, true, true, , , , false, , , 'float', 2, , , 2, 2], |
| 99 | 'rg8unorm': [ true, true, true, , , , false, , , 'float', 2, , , 2, 1], |
| 100 | 'rg8snorm': [ false, false, false, , , , false, , , 'float', 2], |
| 101 | 'rg8uint': [ true, true, false, , , , false, , , 'uint', 2, , , 2, 1], |
| 102 | 'rg8sint': [ true, true, false, , , , false, , , 'sint', 2, , , 2, 1], |
Kai Ninomiya | ea9e36f | 2019-10-18 20:01:03 -0700 | [diff] [blame] | 103 | // 32-bit formats |
Lokbondo Kung | a7e54e7 | 2023-01-26 11:51:32 -0800 | [diff] [blame] | 104 | 'r32uint': [ true, false, false, , , , true, , , 'uint', 4, , , 4, 4], |
| 105 | 'r32sint': [ true, false, false, , , , true, , , 'sint', 4, , , 4, 4], |
| 106 | 'r32float': [ true, true, false, , , , true, , , 'unfilterable-float', 4, , , 4, 4], |
| 107 | 'rg16uint': [ true, true, false, , , , false, , , 'uint', 4, , , 4, 2], |
| 108 | 'rg16sint': [ true, true, false, , , , false, , , 'sint', 4, , , 4, 2], |
| 109 | 'rg16float': [ true, true, true, , , , false, , , 'float', 4, , , 4, 2], |
| 110 | 'rgba8unorm': [ true, true, true, , , , true, , , 'float', 4, , , 8, 1, , 'rgba8unorm'], |
| 111 | 'rgba8unorm-srgb': [ true, true, true, , , , false, , , 'float', 4, , , 8, 1, , 'rgba8unorm'], |
| 112 | 'rgba8snorm': [ false, false, false, , , , true, , , 'float', 4], |
| 113 | 'rgba8uint': [ true, true, false, , , , true, , , 'uint', 4, , , 4, 1], |
| 114 | 'rgba8sint': [ true, true, false, , , , true, , , 'sint', 4, , , 4, 1], |
Jiawei Shao | bd8450c | 2023-01-31 11:01:28 +0800 | [diff] [blame] | 115 | 'bgra8unorm': [ true, true, true, , , , true, , , 'float', 4, , , 8, 1, , 'bgra8unorm'], |
Lokbondo Kung | a7e54e7 | 2023-01-26 11:51:32 -0800 | [diff] [blame] | 116 | 'bgra8unorm-srgb': [ true, true, true, , , , false, , , 'float', 4, , , 8, 1, , 'bgra8unorm'], |
Kai Ninomiya | ea9e36f | 2019-10-18 20:01:03 -0700 | [diff] [blame] | 117 | // Packed 32-bit formats |
Lokbondo Kung | a7e54e7 | 2023-01-26 11:51:32 -0800 | [diff] [blame] | 118 | 'rgb10a2unorm': [ true, true, true, , , , false, , , 'float', 4, , , 8, 4], |
| 119 | 'rg11b10ufloat': [ false, false, false, , , , false, , , 'float', 4, , , 8, 4], |
| 120 | 'rgb9e5ufloat': [ false, false, false, , , , false, , , 'float', 4], |
Kai Ninomiya | ea9e36f | 2019-10-18 20:01:03 -0700 | [diff] [blame] | 121 | // 64-bit formats |
Lokbondo Kung | a7e54e7 | 2023-01-26 11:51:32 -0800 | [diff] [blame] | 122 | 'rg32uint': [ true, false, false, , , , true, , , 'uint', 8, , , 8, 4], |
| 123 | 'rg32sint': [ true, false, false, , , , true, , , 'sint', 8, , , 8, 4], |
| 124 | 'rg32float': [ true, false, false, , , , true, , , 'unfilterable-float', 8, , , 8, 4], |
| 125 | 'rgba16uint': [ true, true, false, , , , true, , , 'uint', 8, , , 8, 2], |
| 126 | 'rgba16sint': [ true, true, false, , , , true, , , 'sint', 8, , , 8, 2], |
| 127 | 'rgba16float': [ true, true, true, , , , true, , , 'float', 8, , , 8, 2], |
Kai Ninomiya | ea9e36f | 2019-10-18 20:01:03 -0700 | [diff] [blame] | 128 | // 128-bit formats |
Lokbondo Kung | a7e54e7 | 2023-01-26 11:51:32 -0800 | [diff] [blame] | 129 | 'rgba32uint': [ true, false, false, , , , true, , , 'uint', 16, , , 16, 4], |
| 130 | 'rgba32sint': [ true, false, false, , , , true, , , 'sint', 16, , , 16, 4], |
| 131 | 'rgba32float': [ true, false, false, , , , true, , , 'unfilterable-float', 16, , , 16, 4], |
Kai Ninomiya | f0d24f3 | 2020-12-11 16:42:29 -0800 | [diff] [blame] | 132 | } as const); |
| 133 | /* prettier-ignore */ |
Lokbondo Kung | a7e54e7 | 2023-01-26 11:51:32 -0800 | [diff] [blame] | 134 | const kTexFmtInfoHeader = ['renderable', 'multisample', 'resolve', 'color', 'depth', 'stencil', 'storage', 'copySrc', 'copyDst', 'sampleType', 'bytesPerBlock', 'blockWidth', 'blockHeight', 'renderTargetPixelByteCost', 'renderTargetComponentAlignment', 'feature', 'baseFormat'] as const; |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 135 | const kSizedDepthStencilFormatInfo = /* prettier-ignore */ makeTable(kTexFmtInfoHeader, |
Lokbondo Kung | a7e54e7 | 2023-01-26 11:51:32 -0800 | [diff] [blame] | 136 | [ true, true, false, false, , , false, , , , , 1, 1, undefined, undefined, , undefined] as const, { |
| 137 | 'depth32float': [ , , , , true, false, , true, false, 'depth', 4], |
| 138 | 'depth16unorm': [ , , , , true, false, , true, true, 'depth', 2], |
| 139 | 'stencil8': [ , , , , false, true, , true, true, 'uint', 1], |
Kai Ninomiya | f0d24f3 | 2020-12-11 16:42:29 -0800 | [diff] [blame] | 140 | } as const); |
ShrekShao | 20aa931 | 2021-08-11 18:55:41 -0700 | [diff] [blame] | 141 | |
| 142 | // Multi aspect sample type are now set to their first aspect |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 143 | const kUnsizedDepthStencilFormatInfo = /* prettier-ignore */ makeTable(kTexFmtInfoHeader, |
Lokbondo Kung | a7e54e7 | 2023-01-26 11:51:32 -0800 | [diff] [blame] | 144 | [ true, true, false, false, , , false, false, false, , undefined, 1, 1, , , , undefined] as const, { |
| 145 | 'depth24plus': [ , , , , true, false, , , , 'depth'], |
| 146 | 'depth24plus-stencil8': [ , , , , true, true, , , , 'depth'], |
Kai Ninomiya | 7c40d21 | 2022-01-04 14:25:02 -0800 | [diff] [blame] | 147 | // MAINTENANCE_TODO: These should really be sized formats; see below MAINTENANCE_TODO about multi-aspect formats. |
Lokbondo Kung | a7e54e7 | 2023-01-26 11:51:32 -0800 | [diff] [blame] | 148 | 'depth32float-stencil8': [ , , , , true, true, , , , 'depth', , , , , , 'depth32float-stencil8'], |
Kai Ninomiya | f0d24f3 | 2020-12-11 16:42:29 -0800 | [diff] [blame] | 149 | } as const); |
Lokbondo Kung | 0e9ad2d | 2021-11-16 17:57:05 -0800 | [diff] [blame] | 150 | |
| 151 | // Separated compressed formats by type |
| 152 | const kBCTextureFormatInfo = /* prettier-ignore */ makeTable(kTexFmtInfoHeader, |
Lokbondo Kung | a7e54e7 | 2023-01-26 11:51:32 -0800 | [diff] [blame] | 153 | [ false, false, false, true, false, false, false, true, true, , , 4, 4, , , , undefined] as const, { |
Lokbondo Kung | 0e9ad2d | 2021-11-16 17:57:05 -0800 | [diff] [blame] | 154 | // Block Compression (BC) formats |
Lokbondo Kung | a7e54e7 | 2023-01-26 11:51:32 -0800 | [diff] [blame] | 155 | 'bc1-rgba-unorm': [ , , , , , , , , , 'float', 8, 4, 4, , , 'texture-compression-bc', 'bc1-rgba-unorm'], |
| 156 | 'bc1-rgba-unorm-srgb': [ , , , , , , , , , 'float', 8, 4, 4, , , 'texture-compression-bc', 'bc1-rgba-unorm'], |
| 157 | 'bc2-rgba-unorm': [ , , , , , , , , , 'float', 16, 4, 4, , , 'texture-compression-bc', 'bc2-rgba-unorm'], |
| 158 | 'bc2-rgba-unorm-srgb': [ , , , , , , , , , 'float', 16, 4, 4, , , 'texture-compression-bc', 'bc2-rgba-unorm'], |
| 159 | 'bc3-rgba-unorm': [ , , , , , , , , , 'float', 16, 4, 4, , , 'texture-compression-bc', 'bc3-rgba-unorm'], |
| 160 | 'bc3-rgba-unorm-srgb': [ , , , , , , , , , 'float', 16, 4, 4, , , 'texture-compression-bc', 'bc3-rgba-unorm'], |
| 161 | 'bc4-r-unorm': [ , , , , , , , , , 'float', 8, 4, 4, , , 'texture-compression-bc'], |
| 162 | 'bc4-r-snorm': [ , , , , , , , , , 'float', 8, 4, 4, , , 'texture-compression-bc'], |
| 163 | 'bc5-rg-unorm': [ , , , , , , , , , 'float', 16, 4, 4, , , 'texture-compression-bc'], |
| 164 | 'bc5-rg-snorm': [ , , , , , , , , , 'float', 16, 4, 4, , , 'texture-compression-bc'], |
| 165 | 'bc6h-rgb-ufloat': [ , , , , , , , , , 'float', 16, 4, 4, , , 'texture-compression-bc'], |
| 166 | 'bc6h-rgb-float': [ , , , , , , , , , 'float', 16, 4, 4, , , 'texture-compression-bc'], |
| 167 | 'bc7-rgba-unorm': [ , , , , , , , , , 'float', 16, 4, 4, , , 'texture-compression-bc', 'bc7-rgba-unorm'], |
| 168 | 'bc7-rgba-unorm-srgb': [ , , , , , , , , , 'float', 16, 4, 4, , , 'texture-compression-bc', 'bc7-rgba-unorm'], |
Kai Ninomiya | f0d24f3 | 2020-12-11 16:42:29 -0800 | [diff] [blame] | 169 | } as const); |
Lokbondo Kung | 0e9ad2d | 2021-11-16 17:57:05 -0800 | [diff] [blame] | 170 | const kETC2TextureFormatInfo = /* prettier-ignore */ makeTable(kTexFmtInfoHeader, |
Lokbondo Kung | a7e54e7 | 2023-01-26 11:51:32 -0800 | [diff] [blame] | 171 | [ false, false, false, true, false, false, false, true, true, , , 4, 4, , , , undefined] as const, { |
Lokbondo Kung | 0e9ad2d | 2021-11-16 17:57:05 -0800 | [diff] [blame] | 172 | // Ericsson Compression (ETC2) formats |
Lokbondo Kung | a7e54e7 | 2023-01-26 11:51:32 -0800 | [diff] [blame] | 173 | 'etc2-rgb8unorm': [ , , , , , , , , , 'float', 8, 4, 4, , , 'texture-compression-etc2', 'etc2-rgb8unorm'], |
| 174 | 'etc2-rgb8unorm-srgb': [ , , , , , , , , , 'float', 8, 4, 4, , , 'texture-compression-etc2', 'etc2-rgb8unorm'], |
| 175 | 'etc2-rgb8a1unorm': [ , , , , , , , , , 'float', 8, 4, 4, , , 'texture-compression-etc2', 'etc2-rgb8a1unorm'], |
| 176 | 'etc2-rgb8a1unorm-srgb': [ , , , , , , , , , 'float', 8, 4, 4, , , 'texture-compression-etc2', 'etc2-rgb8a1unorm'], |
| 177 | 'etc2-rgba8unorm': [ , , , , , , , , , 'float', 16, 4, 4, , , 'texture-compression-etc2', 'etc2-rgba8unorm'], |
| 178 | 'etc2-rgba8unorm-srgb': [ , , , , , , , , , 'float', 16, 4, 4, , , 'texture-compression-etc2', 'etc2-rgba8unorm'], |
| 179 | 'eac-r11unorm': [ , , , , , , , , , 'float', 8, 4, 4, , , 'texture-compression-etc2'], |
| 180 | 'eac-r11snorm': [ , , , , , , , , , 'float', 8, 4, 4, , , 'texture-compression-etc2'], |
| 181 | 'eac-rg11unorm': [ , , , , , , , , , 'float', 16, 4, 4, , , 'texture-compression-etc2'], |
| 182 | 'eac-rg11snorm': [ , , , , , , , , , 'float', 16, 4, 4, , , 'texture-compression-etc2'], |
Lokbondo Kung | 0e9ad2d | 2021-11-16 17:57:05 -0800 | [diff] [blame] | 183 | } as const); |
| 184 | const kASTCTextureFormatInfo = /* prettier-ignore */ makeTable(kTexFmtInfoHeader, |
Lokbondo Kung | a7e54e7 | 2023-01-26 11:51:32 -0800 | [diff] [blame] | 185 | [ false, false, false, true, false, false, false, true, true, , , , , , , , undefined] as const, { |
Lokbondo Kung | 0e9ad2d | 2021-11-16 17:57:05 -0800 | [diff] [blame] | 186 | // Adaptable Scalable Compression (ASTC) formats |
Lokbondo Kung | a7e54e7 | 2023-01-26 11:51:32 -0800 | [diff] [blame] | 187 | 'astc-4x4-unorm': [ , , , , , , , , , 'float', 16, 4, 4, , , 'texture-compression-astc', 'astc-4x4-unorm'], |
| 188 | 'astc-4x4-unorm-srgb': [ , , , , , , , , , 'float', 16, 4, 4, , , 'texture-compression-astc', 'astc-4x4-unorm'], |
| 189 | 'astc-5x4-unorm': [ , , , , , , , , , 'float', 16, 5, 4, , , 'texture-compression-astc', 'astc-5x4-unorm'], |
| 190 | 'astc-5x4-unorm-srgb': [ , , , , , , , , , 'float', 16, 5, 4, , , 'texture-compression-astc', 'astc-5x4-unorm'], |
| 191 | 'astc-5x5-unorm': [ , , , , , , , , , 'float', 16, 5, 5, , , 'texture-compression-astc', 'astc-5x5-unorm'], |
| 192 | 'astc-5x5-unorm-srgb': [ , , , , , , , , , 'float', 16, 5, 5, , , 'texture-compression-astc', 'astc-5x5-unorm'], |
| 193 | 'astc-6x5-unorm': [ , , , , , , , , , 'float', 16, 6, 5, , , 'texture-compression-astc', 'astc-6x5-unorm'], |
| 194 | 'astc-6x5-unorm-srgb': [ , , , , , , , , , 'float', 16, 6, 5, , , 'texture-compression-astc', 'astc-6x5-unorm'], |
| 195 | 'astc-6x6-unorm': [ , , , , , , , , , 'float', 16, 6, 6, , , 'texture-compression-astc', 'astc-6x6-unorm'], |
| 196 | 'astc-6x6-unorm-srgb': [ , , , , , , , , , 'float', 16, 6, 6, , , 'texture-compression-astc', 'astc-6x6-unorm'], |
| 197 | 'astc-8x5-unorm': [ , , , , , , , , , 'float', 16, 8, 5, , , 'texture-compression-astc', 'astc-8x5-unorm'], |
| 198 | 'astc-8x5-unorm-srgb': [ , , , , , , , , , 'float', 16, 8, 5, , , 'texture-compression-astc', 'astc-8x5-unorm'], |
| 199 | 'astc-8x6-unorm': [ , , , , , , , , , 'float', 16, 8, 6, , , 'texture-compression-astc', 'astc-8x6-unorm'], |
| 200 | 'astc-8x6-unorm-srgb': [ , , , , , , , , , 'float', 16, 8, 6, , , 'texture-compression-astc', 'astc-8x6-unorm'], |
| 201 | 'astc-8x8-unorm': [ , , , , , , , , , 'float', 16, 8, 8, , , 'texture-compression-astc', 'astc-8x8-unorm'], |
| 202 | 'astc-8x8-unorm-srgb': [ , , , , , , , , , 'float', 16, 8, 8, , , 'texture-compression-astc', 'astc-8x8-unorm'], |
| 203 | 'astc-10x5-unorm': [ , , , , , , , , , 'float', 16, 10, 5, , , 'texture-compression-astc', 'astc-10x5-unorm'], |
| 204 | 'astc-10x5-unorm-srgb': [ , , , , , , , , , 'float', 16, 10, 5, , , 'texture-compression-astc', 'astc-10x5-unorm'], |
| 205 | 'astc-10x6-unorm': [ , , , , , , , , , 'float', 16, 10, 6, , , 'texture-compression-astc', 'astc-10x6-unorm'], |
| 206 | 'astc-10x6-unorm-srgb': [ , , , , , , , , , 'float', 16, 10, 6, , , 'texture-compression-astc', 'astc-10x6-unorm'], |
| 207 | 'astc-10x8-unorm': [ , , , , , , , , , 'float', 16, 10, 8, , , 'texture-compression-astc', 'astc-10x8-unorm'], |
| 208 | 'astc-10x8-unorm-srgb': [ , , , , , , , , , 'float', 16, 10, 8, , , 'texture-compression-astc', 'astc-10x8-unorm'], |
| 209 | 'astc-10x10-unorm': [ , , , , , , , , , 'float', 16, 10, 10, , , 'texture-compression-astc', 'astc-10x10-unorm'], |
| 210 | 'astc-10x10-unorm-srgb': [ , , , , , , , , , 'float', 16, 10, 10, , , 'texture-compression-astc', 'astc-10x10-unorm'], |
| 211 | 'astc-12x10-unorm': [ , , , , , , , , , 'float', 16, 12, 10, , , 'texture-compression-astc', 'astc-12x10-unorm'], |
| 212 | 'astc-12x10-unorm-srgb': [ , , , , , , , , , 'float', 16, 12, 10, , , 'texture-compression-astc', 'astc-12x10-unorm'], |
| 213 | 'astc-12x12-unorm': [ , , , , , , , , , 'float', 16, 12, 12, , , 'texture-compression-astc', 'astc-12x12-unorm'], |
| 214 | 'astc-12x12-unorm-srgb': [ , , , , , , , , , 'float', 16, 12, 12, , , 'texture-compression-astc', 'astc-12x12-unorm'], |
Lokbondo Kung | 0e9ad2d | 2021-11-16 17:57:05 -0800 | [diff] [blame] | 215 | } as const); |
Kai Ninomiya | f0d24f3 | 2020-12-11 16:42:29 -0800 | [diff] [blame] | 216 | |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 217 | // Definitions for use locally. To access the table entries, use `kTextureFormatInfo`. |
Kai Ninomiya | a9ea59f | 2021-02-10 16:13:49 -0800 | [diff] [blame] | 218 | |
Kai Ninomiya | 7c40d21 | 2022-01-04 14:25:02 -0800 | [diff] [blame] | 219 | // MAINTENANCE_TODO: Consider generating the exports below programmatically by filtering the big list, instead |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 220 | // of using these local constants? Requires some type magic though. |
Lokbondo Kung | 0e9ad2d | 2021-11-16 17:57:05 -0800 | [diff] [blame] | 221 | /* prettier-ignore */ const kCompressedTextureFormatInfo = { ...kBCTextureFormatInfo, ...kETC2TextureFormatInfo, ...kASTCTextureFormatInfo } as const; |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 222 | /* prettier-ignore */ const kColorTextureFormatInfo = { ...kRegularTextureFormatInfo, ...kCompressedTextureFormatInfo } as const; |
| 223 | /* prettier-ignore */ const kEncodableTextureFormatInfo = { ...kRegularTextureFormatInfo, ...kSizedDepthStencilFormatInfo } as const; |
| 224 | /* prettier-ignore */ const kSizedTextureFormatInfo = { ...kRegularTextureFormatInfo, ...kSizedDepthStencilFormatInfo, ...kCompressedTextureFormatInfo } as const; |
| 225 | /* prettier-ignore */ const kDepthStencilFormatInfo = { ...kSizedDepthStencilFormatInfo, ...kUnsizedDepthStencilFormatInfo } as const; |
| 226 | /* prettier-ignore */ const kUncompressedTextureFormatInfo = { ...kRegularTextureFormatInfo, ...kSizedDepthStencilFormatInfo, ...kUnsizedDepthStencilFormatInfo } as const; |
| 227 | /* prettier-ignore */ const kAllTextureFormatInfo = { ...kUncompressedTextureFormatInfo, ...kCompressedTextureFormatInfo } as const; |
Kai Ninomiya | ebef147 | 2020-08-14 15:21:09 -0700 | [diff] [blame] | 228 | |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 229 | /** A "regular" texture format (uncompressed, sized, single-plane color formats). */ |
| 230 | /* prettier-ignore */ export type RegularTextureFormat = keyof typeof kRegularTextureFormatInfo; |
| 231 | /** A sized depth/stencil texture format. */ |
| 232 | /* prettier-ignore */ export type SizedDepthStencilFormat = keyof typeof kSizedDepthStencilFormatInfo; |
| 233 | /** An unsized depth/stencil texture format. */ |
| 234 | /* prettier-ignore */ export type UnsizedDepthStencilFormat = keyof typeof kUnsizedDepthStencilFormatInfo; |
| 235 | /** A compressed (block) texture format. */ |
| 236 | /* prettier-ignore */ export type CompressedTextureFormat = keyof typeof kCompressedTextureFormatInfo; |
Kai Ninomiya | ebef147 | 2020-08-14 15:21:09 -0700 | [diff] [blame] | 237 | |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 238 | /** A color texture format (regular | compressed). */ |
| 239 | /* prettier-ignore */ export type ColorTextureFormat = keyof typeof kColorTextureFormatInfo; |
| 240 | /** An encodable texture format (regular | sized depth/stencil). */ |
| 241 | /* prettier-ignore */ export type EncodableTextureFormat = keyof typeof kEncodableTextureFormatInfo; |
| 242 | /** A sized texture format (regular | sized depth/stencil | compressed). */ |
| 243 | /* prettier-ignore */ export type SizedTextureFormat = keyof typeof kSizedTextureFormatInfo; |
| 244 | /** A depth/stencil format (sized | unsized). */ |
| 245 | /* prettier-ignore */ export type DepthStencilFormat = keyof typeof kDepthStencilFormatInfo; |
| 246 | /** An uncompressed (block size 1x1) format (regular | depth/stencil). */ |
| 247 | /* prettier-ignore */ export type UncompressedTextureFormat = keyof typeof kUncompressedTextureFormatInfo; |
Kai Ninomiya | ebef147 | 2020-08-14 15:21:09 -0700 | [diff] [blame] | 248 | |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 249 | /* prettier-ignore */ export const kRegularTextureFormats: readonly RegularTextureFormat[] = keysOf( kRegularTextureFormatInfo); |
| 250 | /* prettier-ignore */ export const kSizedDepthStencilFormats: readonly SizedDepthStencilFormat[] = keysOf( kSizedDepthStencilFormatInfo); |
| 251 | /* prettier-ignore */ export const kUnsizedDepthStencilFormats: readonly UnsizedDepthStencilFormat[] = keysOf(kUnsizedDepthStencilFormatInfo); |
| 252 | /* prettier-ignore */ export const kCompressedTextureFormats: readonly CompressedTextureFormat[] = keysOf( kCompressedTextureFormatInfo); |
Kai Ninomiya | ebef147 | 2020-08-14 15:21:09 -0700 | [diff] [blame] | 253 | |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 254 | /* prettier-ignore */ export const kColorTextureFormats: readonly ColorTextureFormat[] = keysOf( kColorTextureFormatInfo); |
| 255 | /* prettier-ignore */ export const kEncodableTextureFormats: readonly EncodableTextureFormat[] = keysOf( kEncodableTextureFormatInfo); |
| 256 | /* prettier-ignore */ export const kSizedTextureFormats: readonly SizedTextureFormat[] = keysOf( kSizedTextureFormatInfo); |
| 257 | /* prettier-ignore */ export const kDepthStencilFormats: readonly DepthStencilFormat[] = keysOf( kDepthStencilFormatInfo); |
| 258 | /* prettier-ignore */ export const kUncompressedTextureFormats: readonly UncompressedTextureFormat[] = keysOf(kUncompressedTextureFormatInfo); |
Jiawei Shao | 6635a5c | 2021-10-26 08:45:16 +0800 | [diff] [blame] | 259 | /* prettier-ignore */ export const kAllTextureFormats: readonly GPUTextureFormat[] = keysOf( kAllTextureFormatInfo); |
Kai Ninomiya | ebef147 | 2020-08-14 15:21:09 -0700 | [diff] [blame] | 260 | |
ShrekShao | 20aa931 | 2021-08-11 18:55:41 -0700 | [diff] [blame] | 261 | // CompressedTextureFormat are unrenderable so filter from RegularTextureFormats for color targets is enough |
| 262 | export const kRenderableColorTextureFormats = kRegularTextureFormats.filter( |
| 263 | v => kColorTextureFormatInfo[v].renderable |
| 264 | ); |
Lokbondo Kung | a7e54e7 | 2023-01-26 11:51:32 -0800 | [diff] [blame] | 265 | assert( |
| 266 | kRenderableColorTextureFormats.every( |
| 267 | f => |
| 268 | kAllTextureFormatInfo[f].renderTargetComponentAlignment !== undefined && |
| 269 | kAllTextureFormatInfo[f].renderTargetPixelByteCost !== undefined |
| 270 | ) |
| 271 | ); |
ShrekShao | 20aa931 | 2021-08-11 18:55:41 -0700 | [diff] [blame] | 272 | |
Jie Chen | 77fbca4 | 2022-02-11 03:29:01 +0800 | [diff] [blame] | 273 | // The formats of GPUTextureFormat for canvas context. |
Jie Chen | c02319b | 2022-02-23 11:26:24 +0800 | [diff] [blame] | 274 | export const kCanvasTextureFormats = ['bgra8unorm', 'rgba8unorm', 'rgba16float'] as const; |
Jie Chen | 77fbca4 | 2022-02-11 03:29:01 +0800 | [diff] [blame] | 275 | |
ShrekShao | 94fd838 | 2022-07-29 15:54:56 -0700 | [diff] [blame] | 276 | // The alpha mode for canvas context. |
Gregg Tavares | 7e5c203 | 2023-01-17 16:30:14 -0800 | [diff] [blame] | 277 | export const kCanvasAlphaModesInfo: { |
| 278 | readonly [k in GPUCanvasAlphaMode]: {}; |
| 279 | } = /* prettier-ignore */ { |
| 280 | 'opaque': {}, |
| 281 | 'premultiplied': {}, |
| 282 | }; |
| 283 | export const kCanvasAlphaModes = keysOf(kCanvasAlphaModesInfo); |
| 284 | |
| 285 | // The color spaces for canvas context |
| 286 | export const kCanvasColorSpacesInfo: { |
| 287 | readonly [k in PredefinedColorSpace]: {}; |
| 288 | } = /* prettier-ignore */ { |
| 289 | 'srgb': {}, |
| 290 | 'display-p3': {}, |
| 291 | }; |
| 292 | export const kCanvasColorSpaces = keysOf(kCanvasColorSpacesInfo); |
ShrekShao | 94fd838 | 2022-07-29 15:54:56 -0700 | [diff] [blame] | 293 | |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 294 | /** Per-GPUTextureFormat info. */ |
| 295 | // Exists just for documentation. Otherwise could be inferred by `makeTable`. |
Kai Ninomiya | 7c40d21 | 2022-01-04 14:25:02 -0800 | [diff] [blame] | 296 | // MAINTENANCE_TODO: Refactor this to separate per-aspect data for multi-aspect formats. In particular: |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 297 | // - bytesPerBlock only makes sense on a per-aspect basis. But this table can't express that. |
Brandon Jones | 6ff5595 | 2022-06-07 12:19:06 -0700 | [diff] [blame] | 298 | // So we put depth32float-stencil8 to be an unsized format for now. |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 299 | export type TextureFormatInfo = { |
| 300 | /** Whether the format can be used as `RENDER_ATTACHMENT`. */ |
| 301 | renderable: boolean; |
| 302 | /** Whether the format can be used in a multisample texture. */ |
| 303 | multisample: boolean; |
Jiawei Shao | 008969e | 2022-03-01 09:25:12 +0800 | [diff] [blame] | 304 | /** Whether the texture with the format can be used as a resolve target. */ |
| 305 | resolve: boolean; |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 306 | /** Whether the format has a color aspect. */ |
| 307 | color: boolean; |
| 308 | /** Whether the format has a depth aspect. */ |
| 309 | depth: boolean; |
| 310 | /** Whether the format has a stencil aspect. */ |
| 311 | stencil: boolean; |
| 312 | /** Whether the format can be used as `STORAGE`. */ |
| 313 | storage: boolean; |
| 314 | /** Whether the format can be used as `COPY_SRC`. */ |
| 315 | copySrc: boolean; |
| 316 | /** Whether the format can be used as `COPY_DST`. */ |
| 317 | copyDst: boolean; |
| 318 | /** Byte size of one texel block, or `undefined` if the format is unsized. */ |
| 319 | bytesPerBlock: number | undefined; |
| 320 | /** Width, in texels, of one texel block. */ |
| 321 | blockWidth: number; |
| 322 | /** Height, in texels, of one texel block. */ |
| 323 | blockHeight: number; |
Lokbondo Kung | a7e54e7 | 2023-01-26 11:51:32 -0800 | [diff] [blame] | 324 | /** The raw, unaligned, byte cost towards the color attachment bytes per sample. |
| 325 | * (See https://www.w3.org/TR/webgpu/#abstract-opdef-calculating-color-attachment-bytes-per-sample). */ |
| 326 | renderTargetPixelByteCost: number | undefined; |
| 327 | /** The alignment used for the format when computing the color attachment bytes per sample. */ |
| 328 | renderTargetComponentAlignment: number | undefined; |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 329 | /** Optional feature required to use this format, or `undefined` if none. */ |
| 330 | feature: GPUFeatureName | undefined; |
| 331 | // Add fields as needed |
| 332 | }; |
| 333 | /** Per-GPUTextureFormat info. */ |
| 334 | export const kTextureFormatInfo: { |
| 335 | readonly [k in GPUTextureFormat]: TextureFormatInfo & |
| 336 | // TextureFormatInfo exists just for documentation (and verification of the table data types). |
| 337 | // The next line constrains the types so that accessing kTextureFormatInfo with |
| 338 | // a subtype of GPUTextureFormat actually returns nicely a constrained info type |
| 339 | // (e.g. with `bytesPerBlock: number` instead of `bytesPerBlock: number | undefined`). |
| 340 | typeof kAllTextureFormatInfo[k]; |
| 341 | } = kAllTextureFormatInfo; |
| 342 | /** List of all GPUTextureFormat values. */ |
| 343 | /* prettier-ignore */ export const kTextureFormats: readonly GPUTextureFormat[] = keysOf(kAllTextureFormatInfo); |
Kai Ninomiya | ebef147 | 2020-08-14 15:21:09 -0700 | [diff] [blame] | 344 | |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 345 | /** Valid GPUTextureFormats for `copyExternalImageToTexture`, by spec. */ |
Yan, Shaobo | c53abb7 | 2021-07-28 09:33:51 +0800 | [diff] [blame] | 346 | export const kValidTextureFormatsForCopyE2T = [ |
Yan, Shaobo | 027e339 | 2021-11-06 03:29:52 +0800 | [diff] [blame] | 347 | 'r8unorm', |
| 348 | 'r16float', |
| 349 | 'r32float', |
| 350 | 'rg8unorm', |
| 351 | 'rg16float', |
| 352 | 'rg32float', |
Yan, Shaobo | 7c0e4f9 | 2021-06-02 03:14:49 +0800 | [diff] [blame] | 353 | 'rgba8unorm', |
| 354 | 'rgba8unorm-srgb', |
| 355 | 'bgra8unorm', |
| 356 | 'bgra8unorm-srgb', |
| 357 | 'rgb10a2unorm', |
Yan, Shaobo | 027e339 | 2021-11-06 03:29:52 +0800 | [diff] [blame] | 358 | 'rgba16float', |
| 359 | 'rgba32float', |
Yan, Shaobo | 7c0e4f9 | 2021-06-02 03:14:49 +0800 | [diff] [blame] | 360 | ] as const; |
| 361 | |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 362 | /** Per-GPUTextureDimension info. */ |
Austin Eng | 212317f | 2020-04-16 17:22:27 -0700 | [diff] [blame] | 363 | export const kTextureDimensionInfo: { |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 364 | readonly [k in GPUTextureDimension]: {}; |
Austin Eng | 212317f | 2020-04-16 17:22:27 -0700 | [diff] [blame] | 365 | } = /* prettier-ignore */ { |
| 366 | '1d': {}, |
| 367 | '2d': {}, |
| 368 | '3d': {}, |
| 369 | }; |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 370 | /** List of all GPUTextureDimension values. */ |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 371 | export const kTextureDimensions = keysOf(kTextureDimensionInfo); |
Austin Eng | 212317f | 2020-04-16 17:22:27 -0700 | [diff] [blame] | 372 | |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 373 | /** Per-GPUTextureAspect info. */ |
Austin Eng | 212317f | 2020-04-16 17:22:27 -0700 | [diff] [blame] | 374 | export const kTextureAspectInfo: { |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 375 | readonly [k in GPUTextureAspect]: {}; |
Austin Eng | 212317f | 2020-04-16 17:22:27 -0700 | [diff] [blame] | 376 | } = /* prettier-ignore */ { |
| 377 | 'all': {}, |
| 378 | 'depth-only': {}, |
| 379 | 'stencil-only': {}, |
| 380 | }; |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 381 | /** List of all GPUTextureAspect values. */ |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 382 | export const kTextureAspects = keysOf(kTextureAspectInfo); |
| 383 | |
Yunchao He | 2370ee0 | 2022-01-07 18:15:44 -0800 | [diff] [blame] | 384 | /** Per-GPUCompareFunction info. */ |
| 385 | export const kCompareFunctionInfo: { |
| 386 | readonly [k in GPUCompareFunction]: {}; |
| 387 | } = /* prettier-ignore */ { |
| 388 | 'never': {}, |
| 389 | 'less': {}, |
| 390 | 'equal': {}, |
| 391 | 'less-equal': {}, |
| 392 | 'greater': {}, |
| 393 | 'not-equal': {}, |
| 394 | 'greater-equal': {}, |
| 395 | 'always': {}, |
| 396 | }; |
| 397 | /** List of all GPUCompareFunction values. */ |
| 398 | export const kCompareFunctions = keysOf(kCompareFunctionInfo); |
| 399 | |
| 400 | /** Per-GPUStencilOperation info. */ |
| 401 | export const kStencilOperationInfo: { |
| 402 | readonly [k in GPUStencilOperation]: {}; |
| 403 | } = /* prettier-ignore */ { |
| 404 | 'keep': {}, |
| 405 | 'zero': {}, |
| 406 | 'replace': {}, |
| 407 | 'invert': {}, |
| 408 | 'increment-clamp': {}, |
| 409 | 'decrement-clamp': {}, |
| 410 | 'increment-wrap': {}, |
| 411 | 'decrement-wrap': {}, |
| 412 | }; |
| 413 | /** List of all GPUStencilOperation values. */ |
| 414 | export const kStencilOperations = keysOf(kStencilOperationInfo); |
| 415 | |
Jiawei Shao | a9ac8c3 | 2021-03-04 02:53:13 +0800 | [diff] [blame] | 416 | const kDepthStencilFormatCapabilityInBufferTextureCopy = { |
| 417 | // kUnsizedDepthStencilFormats |
| 418 | depth24plus: { |
| 419 | CopyB2T: [], |
| 420 | CopyT2B: [], |
Jiawei Shao | 7aa3602 | 2021-03-12 16:46:06 +0800 | [diff] [blame] | 421 | texelAspectSize: { 'depth-only': -1, 'stencil-only': -1 }, |
Jiawei Shao | a9ac8c3 | 2021-03-04 02:53:13 +0800 | [diff] [blame] | 422 | }, |
| 423 | 'depth24plus-stencil8': { |
| 424 | CopyB2T: ['stencil-only'], |
| 425 | CopyT2B: ['stencil-only'], |
Jiawei Shao | 7aa3602 | 2021-03-12 16:46:06 +0800 | [diff] [blame] | 426 | texelAspectSize: { 'depth-only': -1, 'stencil-only': 1 }, |
Jiawei Shao | a9ac8c3 | 2021-03-04 02:53:13 +0800 | [diff] [blame] | 427 | }, |
| 428 | |
| 429 | // kSizedDepthStencilFormats |
| 430 | depth16unorm: { |
| 431 | CopyB2T: ['all', 'depth-only'], |
| 432 | CopyT2B: ['all', 'depth-only'], |
Jiawei Shao | 7aa3602 | 2021-03-12 16:46:06 +0800 | [diff] [blame] | 433 | texelAspectSize: { 'depth-only': 2, 'stencil-only': -1 }, |
Jiawei Shao | a9ac8c3 | 2021-03-04 02:53:13 +0800 | [diff] [blame] | 434 | }, |
| 435 | depth32float: { |
| 436 | CopyB2T: [], |
| 437 | CopyT2B: ['all', 'depth-only'], |
Jiawei Shao | 7aa3602 | 2021-03-12 16:46:06 +0800 | [diff] [blame] | 438 | texelAspectSize: { 'depth-only': 4, 'stencil-only': -1 }, |
Jiawei Shao | a9ac8c3 | 2021-03-04 02:53:13 +0800 | [diff] [blame] | 439 | }, |
Jiawei Shao | a9ac8c3 | 2021-03-04 02:53:13 +0800 | [diff] [blame] | 440 | 'depth32float-stencil8': { |
| 441 | CopyB2T: ['stencil-only'], |
| 442 | CopyT2B: ['depth-only', 'stencil-only'], |
Jiawei Shao | 7aa3602 | 2021-03-12 16:46:06 +0800 | [diff] [blame] | 443 | texelAspectSize: { 'depth-only': 4, 'stencil-only': 1 }, |
Jiawei Shao | a9ac8c3 | 2021-03-04 02:53:13 +0800 | [diff] [blame] | 444 | }, |
| 445 | stencil8: { |
| 446 | CopyB2T: ['all', 'stencil-only'], |
| 447 | CopyT2B: ['all', 'stencil-only'], |
Jiawei Shao | 7aa3602 | 2021-03-12 16:46:06 +0800 | [diff] [blame] | 448 | texelAspectSize: { 'depth-only': -1, 'stencil-only': 1 }, |
Jiawei Shao | a9ac8c3 | 2021-03-04 02:53:13 +0800 | [diff] [blame] | 449 | }, |
| 450 | } as const; |
| 451 | |
Corentin Wallez | 23afd04 | 2022-04-05 16:20:39 +0100 | [diff] [blame] | 452 | /** `kDepthStencilFormatResolvedAspect[format][aspect]` returns the aspect-specific format for a |
| 453 | * depth-stencil format, or `undefined` if the format doesn't have the aspect. |
| 454 | */ |
| 455 | export const kDepthStencilFormatResolvedAspect: { |
| 456 | readonly [k in DepthStencilFormat]: { |
| 457 | readonly [a in GPUTextureAspect]: DepthStencilFormat | undefined; |
| 458 | }; |
| 459 | } = { |
| 460 | // kUnsizedDepthStencilFormats |
| 461 | depth24plus: { |
| 462 | all: 'depth24plus', |
| 463 | 'depth-only': 'depth24plus', |
| 464 | 'stencil-only': undefined, |
| 465 | }, |
| 466 | 'depth24plus-stencil8': { |
| 467 | all: 'depth24plus-stencil8', |
| 468 | 'depth-only': 'depth24plus', |
| 469 | 'stencil-only': 'stencil8', |
| 470 | }, |
| 471 | |
| 472 | // kSizedDepthStencilFormats |
| 473 | depth16unorm: { |
| 474 | all: 'depth16unorm', |
| 475 | 'depth-only': 'depth16unorm', |
| 476 | 'stencil-only': undefined, |
| 477 | }, |
| 478 | depth32float: { |
| 479 | all: 'depth32float', |
| 480 | 'depth-only': 'depth32float', |
| 481 | 'stencil-only': undefined, |
| 482 | }, |
Corentin Wallez | 23afd04 | 2022-04-05 16:20:39 +0100 | [diff] [blame] | 483 | 'depth32float-stencil8': { |
| 484 | all: 'depth32float-stencil8', |
| 485 | 'depth-only': 'depth32float', |
| 486 | 'stencil-only': 'stencil8', |
| 487 | }, |
| 488 | stencil8: { |
| 489 | all: 'stencil8', |
| 490 | 'depth-only': undefined, |
| 491 | 'stencil-only': 'stencil8', |
| 492 | }, |
| 493 | } as const; |
| 494 | |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 495 | /** |
Corentin Wallez | f030b5f | 2022-04-08 22:31:28 +0100 | [diff] [blame] | 496 | * @returns the GPUTextureFormat corresponding to the @param aspect of @param format. |
| 497 | * This allows choosing the correct format for depth-stencil aspects when creating pipelines that |
| 498 | * will have to match the resolved format of views, or to get per-aspect information like the |
| 499 | * `blockByteSize`. |
| 500 | * |
| 501 | * Many helpers use an `undefined` `aspect` to means `'all'` so this is also the default for this |
| 502 | * function. |
| 503 | */ |
| 504 | export function resolvePerAspectFormat( |
| 505 | format: GPUTextureFormat, |
| 506 | aspect?: GPUTextureAspect |
| 507 | ): GPUTextureFormat { |
| 508 | if (aspect === 'all' || aspect === undefined) { |
| 509 | return format; |
| 510 | } |
| 511 | assert(kTextureFormatInfo[format].depth || kTextureFormatInfo[format].stencil); |
| 512 | const resolved = kDepthStencilFormatResolvedAspect[format as DepthStencilFormat][aspect ?? 'all']; |
| 513 | assert(resolved !== undefined); |
Kai Ninomiya | bd44734 | 2022-05-16 21:50:43 -0700 | [diff] [blame] | 514 | return resolved; |
Corentin Wallez | f030b5f | 2022-04-08 22:31:28 +0100 | [diff] [blame] | 515 | } |
| 516 | |
| 517 | /** |
Yunchao He | a975589 | 2021-08-19 16:49:29 -0700 | [diff] [blame] | 518 | * Gets all copyable aspects for copies between texture and buffer for specified depth/stencil format and copy type, by spec. |
| 519 | */ |
| 520 | export function depthStencilFormatCopyableAspects( |
| 521 | type: ImageCopyType, |
| 522 | format: DepthStencilFormat |
| 523 | ): readonly GPUTextureAspect[] { |
| 524 | const appliedType = type === 'WriteTexture' ? 'CopyB2T' : type; |
| 525 | return kDepthStencilFormatCapabilityInBufferTextureCopy[format][appliedType]; |
| 526 | } |
| 527 | |
| 528 | /** |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 529 | * Computes whether a copy between a depth/stencil texture aspect and a buffer is supported, by spec. |
| 530 | */ |
Jiawei Shao | a9ac8c3 | 2021-03-04 02:53:13 +0800 | [diff] [blame] | 531 | export function depthStencilBufferTextureCopySupported( |
Yunchao He | a975589 | 2021-08-19 16:49:29 -0700 | [diff] [blame] | 532 | type: ImageCopyType, |
Jiawei Shao | a9ac8c3 | 2021-03-04 02:53:13 +0800 | [diff] [blame] | 533 | format: DepthStencilFormat, |
| 534 | aspect: GPUTextureAspect |
| 535 | ): boolean { |
Yunchao He | a975589 | 2021-08-19 16:49:29 -0700 | [diff] [blame] | 536 | const supportedAspects: readonly GPUTextureAspect[] = depthStencilFormatCopyableAspects( |
| 537 | type, |
| 538 | format |
| 539 | ); |
Jiawei Shao | a9ac8c3 | 2021-03-04 02:53:13 +0800 | [diff] [blame] | 540 | return supportedAspects.includes(aspect); |
| 541 | } |
| 542 | |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 543 | /** |
| 544 | * Returns the byte size of the depth or stencil aspect of the specified depth/stencil format, |
| 545 | * or -1 if none. |
| 546 | */ |
Jiawei Shao | 7aa3602 | 2021-03-12 16:46:06 +0800 | [diff] [blame] | 547 | export function depthStencilFormatAspectSize( |
| 548 | format: DepthStencilFormat, |
| 549 | aspect: 'depth-only' | 'stencil-only' |
| 550 | ) { |
| 551 | const texelAspectSize = |
| 552 | kDepthStencilFormatCapabilityInBufferTextureCopy[format].texelAspectSize[aspect]; |
| 553 | assert(texelAspectSize > 0); |
| 554 | return texelAspectSize; |
| 555 | } |
| 556 | |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 557 | /** |
| 558 | * Returns true iff a texture can be created with the provided GPUTextureDimension |
| 559 | * (defaulting to 2d) and GPUTextureFormat, by spec. |
| 560 | */ |
Yunchao He | 6c9e376 | 2021-04-09 12:45:15 -0700 | [diff] [blame] | 561 | export function textureDimensionAndFormatCompatible( |
| 562 | dimension: undefined | GPUTextureDimension, |
| 563 | format: GPUTextureFormat |
| 564 | ): boolean { |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 565 | const info = kAllTextureFormatInfo[format]; |
Yunchao He | 6c9e376 | 2021-04-09 12:45:15 -0700 | [diff] [blame] | 566 | return !( |
| 567 | (dimension === '1d' || dimension === '3d') && |
| 568 | (info.blockWidth > 1 || info.depth || info.stencil) |
| 569 | ); |
| 570 | } |
| 571 | |
Lokbondo Kung | 300c10c | 2022-03-22 10:53:42 -0700 | [diff] [blame] | 572 | /** Per-GPUTextureUsage type info. */ |
| 573 | export const kTextureUsageTypeInfo: { |
| 574 | readonly [name: string]: number; |
| 575 | } = /* prettier-ignore */ { |
| 576 | 'texture': Number(GPUConst.TextureUsage.TEXTURE_BINDING), |
| 577 | 'storage': Number(GPUConst.TextureUsage.STORAGE_BINDING), |
| 578 | 'render': Number(GPUConst.TextureUsage.RENDER_ATTACHMENT), |
| 579 | }; |
| 580 | /** List of all GPUTextureUsage type values. */ |
| 581 | export const kTextureUsageType = keysOf(kTextureUsageTypeInfo); |
| 582 | |
| 583 | /** Per-GPUTextureUsage copy info. */ |
| 584 | export const kTextureUsageCopyInfo: { |
| 585 | readonly [name: string]: number; |
| 586 | } = /* prettier-ignore */ { |
| 587 | 'none': 0, |
| 588 | 'src': Number(GPUConst.TextureUsage.COPY_SRC), |
| 589 | 'dst': Number(GPUConst.TextureUsage.COPY_DST), |
| 590 | 'src-dest': Number(GPUConst.TextureUsage.COPY_SRC) | Number(GPUConst.TextureUsage.COPY_DST), |
| 591 | }; |
| 592 | /** List of all GPUTextureUsage copy values. */ |
| 593 | export const kTextureUsageCopy = keysOf(kTextureUsageCopyInfo); |
| 594 | |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 595 | /** Per-GPUTextureUsage info. */ |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 596 | export const kTextureUsageInfo: { |
Kai Ninomiya | 51682ed | 2021-04-13 19:23:48 -0700 | [diff] [blame] | 597 | readonly [k in valueof<typeof GPUConst.TextureUsage>]: {}; |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 598 | } = { |
Kai Ninomiya | 04e404f | 2020-10-23 16:02:19 -0700 | [diff] [blame] | 599 | [GPUConst.TextureUsage.COPY_SRC]: {}, |
| 600 | [GPUConst.TextureUsage.COPY_DST]: {}, |
Brandon Jones | 201435f | 2021-08-12 13:47:21 -0700 | [diff] [blame] | 601 | [GPUConst.TextureUsage.TEXTURE_BINDING]: {}, |
| 602 | [GPUConst.TextureUsage.STORAGE_BINDING]: {}, |
Brandon Jones | d048d11d | 2021-02-01 18:11:48 -0800 | [diff] [blame] | 603 | [GPUConst.TextureUsage.RENDER_ATTACHMENT]: {}, |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 604 | }; |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 605 | /** List of all GPUTextureUsage values. */ |
Kai Ninomiya | 51682ed | 2021-04-13 19:23:48 -0700 | [diff] [blame] | 606 | export const kTextureUsages = numericKeysOf<GPUTextureUsageFlags>(kTextureUsageInfo); |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 607 | |
Yunchao He | ad96054 | 2020-07-15 11:20:51 -0700 | [diff] [blame] | 608 | // Texture View |
| 609 | |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 610 | /** Per-GPUTextureViewDimension info. */ |
| 611 | export type TextureViewDimensionInfo = { |
| 612 | /** Whether a storage texture view can have this view dimension. */ |
| 613 | readonly storage: boolean; |
| 614 | // Add fields as needed |
| 615 | }; |
| 616 | /** Per-GPUTextureViewDimension info. */ |
Yunchao He | ad96054 | 2020-07-15 11:20:51 -0700 | [diff] [blame] | 617 | export const kTextureViewDimensionInfo: { |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 618 | readonly [k in GPUTextureViewDimension]: TextureViewDimensionInfo; |
Yunchao He | ad96054 | 2020-07-15 11:20:51 -0700 | [diff] [blame] | 619 | } = /* prettier-ignore */ { |
Yunchao He | cb0d5bb | 2020-07-27 11:01:12 -0700 | [diff] [blame] | 620 | '1d': { storage: true }, |
| 621 | '2d': { storage: true }, |
| 622 | '2d-array': { storage: true }, |
| 623 | 'cube': { storage: false }, |
| 624 | 'cube-array': { storage: false }, |
| 625 | '3d': { storage: true }, |
Yunchao He | ad96054 | 2020-07-15 11:20:51 -0700 | [diff] [blame] | 626 | }; |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 627 | /** List of all GPUTextureDimension values. */ |
Yunchao He | ad96054 | 2020-07-15 11:20:51 -0700 | [diff] [blame] | 628 | export const kTextureViewDimensions = keysOf(kTextureViewDimensionInfo); |
| 629 | |
Corentin Wallez | 056afcf | 2021-03-11 07:26:23 +0000 | [diff] [blame] | 630 | // Vertex formats |
| 631 | |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 632 | /** Per-GPUVertexFormat info. */ |
| 633 | // Exists just for documentation. Otherwise could be inferred by `makeTable`. |
| 634 | export type VertexFormatInfo = { |
| 635 | /** Number of bytes in each component. */ |
| 636 | readonly bytesPerComponent: 1 | 2 | 4; |
| 637 | /** The data encoding (float, normalized, or integer) for each component. */ |
| 638 | readonly type: 'float' | 'unorm' | 'snorm' | 'uint' | 'sint'; |
| 639 | /** Number of components. */ |
| 640 | readonly componentCount: 1 | 2 | 3 | 4; |
jzm-intel | 7829cf7 | 2021-08-25 09:27:06 +0800 | [diff] [blame] | 641 | /** The completely matching WGSL type for vertex format */ |
| 642 | readonly wgslType: |
| 643 | | 'f32' |
| 644 | | 'vec2<f32>' |
| 645 | | 'vec3<f32>' |
| 646 | | 'vec4<f32>' |
| 647 | | 'u32' |
| 648 | | 'vec2<u32>' |
| 649 | | 'vec3<u32>' |
| 650 | | 'vec4<u32>' |
| 651 | | 'i32' |
| 652 | | 'vec2<i32>' |
| 653 | | 'vec3<i32>' |
| 654 | | 'vec4<i32>'; |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 655 | // Add fields as needed |
| 656 | }; |
| 657 | /** Per-GPUVertexFormat info. */ |
| 658 | export const kVertexFormatInfo: { |
| 659 | readonly [k in GPUVertexFormat]: VertexFormatInfo; |
| 660 | } = /* prettier-ignore */ makeTable( |
jzm-intel | 7829cf7 | 2021-08-25 09:27:06 +0800 | [diff] [blame] | 661 | ['bytesPerComponent', 'type', 'componentCount', 'wgslType'] as const, |
| 662 | [ , , , ] as const, { |
Corentin Wallez | 056afcf | 2021-03-11 07:26:23 +0000 | [diff] [blame] | 663 | // 8 bit components |
jzm-intel | 7829cf7 | 2021-08-25 09:27:06 +0800 | [diff] [blame] | 664 | 'uint8x2': [ 1, 'uint', 2, 'vec2<u32>'], |
| 665 | 'uint8x4': [ 1, 'uint', 4, 'vec4<u32>'], |
| 666 | 'sint8x2': [ 1, 'sint', 2, 'vec2<i32>'], |
| 667 | 'sint8x4': [ 1, 'sint', 4, 'vec4<i32>'], |
| 668 | 'unorm8x2': [ 1, 'unorm', 2, 'vec2<f32>'], |
| 669 | 'unorm8x4': [ 1, 'unorm', 4, 'vec4<f32>'], |
| 670 | 'snorm8x2': [ 1, 'snorm', 2, 'vec2<f32>'], |
| 671 | 'snorm8x4': [ 1, 'snorm', 4, 'vec4<f32>'], |
Corentin Wallez | 056afcf | 2021-03-11 07:26:23 +0000 | [diff] [blame] | 672 | // 16 bit components |
jzm-intel | 7829cf7 | 2021-08-25 09:27:06 +0800 | [diff] [blame] | 673 | 'uint16x2': [ 2, 'uint', 2, 'vec2<u32>'], |
| 674 | 'uint16x4': [ 2, 'uint', 4, 'vec4<u32>'], |
| 675 | 'sint16x2': [ 2, 'sint', 2, 'vec2<i32>'], |
| 676 | 'sint16x4': [ 2, 'sint', 4, 'vec4<i32>'], |
| 677 | 'unorm16x2': [ 2, 'unorm', 2, 'vec2<f32>'], |
| 678 | 'unorm16x4': [ 2, 'unorm', 4, 'vec4<f32>'], |
| 679 | 'snorm16x2': [ 2, 'snorm', 2, 'vec2<f32>'], |
| 680 | 'snorm16x4': [ 2, 'snorm', 4, 'vec4<f32>'], |
| 681 | 'float16x2': [ 2, 'float', 2, 'vec2<f32>'], |
| 682 | 'float16x4': [ 2, 'float', 4, 'vec4<f32>'], |
Corentin Wallez | 056afcf | 2021-03-11 07:26:23 +0000 | [diff] [blame] | 683 | // 32 bit components |
jzm-intel | 7829cf7 | 2021-08-25 09:27:06 +0800 | [diff] [blame] | 684 | 'float32': [ 4, 'float', 1, 'f32'], |
| 685 | 'float32x2': [ 4, 'float', 2, 'vec2<f32>'], |
| 686 | 'float32x3': [ 4, 'float', 3, 'vec3<f32>'], |
| 687 | 'float32x4': [ 4, 'float', 4, 'vec4<f32>'], |
| 688 | 'uint32': [ 4, 'uint', 1, 'u32'], |
| 689 | 'uint32x2': [ 4, 'uint', 2, 'vec2<u32>'], |
| 690 | 'uint32x3': [ 4, 'uint', 3, 'vec3<u32>'], |
| 691 | 'uint32x4': [ 4, 'uint', 4, 'vec4<u32>'], |
| 692 | 'sint32': [ 4, 'sint', 1, 'i32'], |
| 693 | 'sint32x2': [ 4, 'sint', 2, 'vec2<i32>'], |
| 694 | 'sint32x3': [ 4, 'sint', 3, 'vec3<i32>'], |
| 695 | 'sint32x4': [ 4, 'sint', 4, 'vec4<i32>'] |
Corentin Wallez | 056afcf | 2021-03-11 07:26:23 +0000 | [diff] [blame] | 696 | } as const); |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 697 | /** List of all GPUVertexFormat values. */ |
Corentin Wallez | 056afcf | 2021-03-11 07:26:23 +0000 | [diff] [blame] | 698 | export const kVertexFormats = keysOf(kVertexFormatInfo); |
| 699 | |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 700 | // Typedefs for bindings |
| 701 | |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 702 | /** |
| 703 | * Classes of `PerShaderStage` binding limits. Two bindings with the same class |
| 704 | * count toward the same `PerShaderStage` limit(s) in the spec (if any). |
| 705 | */ |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 706 | export type PerStageBindingLimitClass = |
| 707 | | 'uniformBuf' |
| 708 | | 'storageBuf' |
| 709 | | 'sampler' |
| 710 | | 'sampledTex' |
| 711 | | 'storageTex'; |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 712 | /** |
| 713 | * Classes of `PerPipelineLayout` binding limits. Two bindings with the same class |
| 714 | * count toward the same `PerPipelineLayout` limit(s) in the spec (if any). |
| 715 | */ |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 716 | export type PerPipelineBindingLimitClass = PerStageBindingLimitClass; |
| 717 | |
Hao Li | afc14d1 | 2021-08-31 10:02:06 +0800 | [diff] [blame] | 718 | export type ValidBindableResource = |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 719 | | 'uniformBuf' |
| 720 | | 'storageBuf' |
Kai Ninomiya | ff91b74 | 2021-04-20 18:41:59 -0700 | [diff] [blame] | 721 | | 'filtSamp' |
| 722 | | 'nonFiltSamp' |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 723 | | 'compareSamp' |
| 724 | | 'sampledTex' |
Kai Ninomiya | 6c4d36b | 2020-12-18 13:40:50 -0800 | [diff] [blame] | 725 | | 'sampledTexMS' |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 726 | | 'storageTex'; |
| 727 | type ErrorBindableResource = 'errorBuf' | 'errorSamp' | 'errorTex'; |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 728 | |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 729 | /** |
| 730 | * Types of resource binding which have distinct binding rules, by spec |
| 731 | * (e.g. filtering vs non-filtering sampler, multisample vs non-multisample texture). |
| 732 | */ |
Kai Ninomiya | ff91b74 | 2021-04-20 18:41:59 -0700 | [diff] [blame] | 733 | export type BindableResource = ValidBindableResource | ErrorBindableResource; |
| 734 | export const kBindableResources = [ |
| 735 | 'uniformBuf', |
| 736 | 'storageBuf', |
| 737 | 'filtSamp', |
| 738 | 'nonFiltSamp', |
| 739 | 'compareSamp', |
| 740 | 'sampledTex', |
| 741 | 'sampledTexMS', |
| 742 | 'storageTex', |
| 743 | 'errorBuf', |
| 744 | 'errorSamp', |
| 745 | 'errorTex', |
| 746 | ] as const; |
| 747 | assertTypeTrue<TypeEqual<BindableResource, typeof kBindableResources[number]>>(); |
Austin Eng | 212317f | 2020-04-16 17:22:27 -0700 | [diff] [blame] | 748 | |
Justin Fan | 5d1b8c7 | 2020-01-15 16:03:37 -0800 | [diff] [blame] | 749 | // Bindings |
| 750 | |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 751 | /** Dynamic buffer offsets require offset to be divisible by 256, by spec. */ |
Enrico Galli | 340098b | 2021-03-24 02:24:02 -0700 | [diff] [blame] | 752 | export const kMinDynamicBufferOffsetAlignment = 256; |
| 753 | |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 754 | /** Default `PerShaderStage` binding limits, by spec. */ |
Justin Fan | 5d1b8c7 | 2020-01-15 16:03:37 -0800 | [diff] [blame] | 755 | export const kPerStageBindingLimits: { |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 756 | readonly [k in PerStageBindingLimitClass]: { |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 757 | /** Which `PerShaderStage` binding limit class. */ |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 758 | readonly class: k; |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 759 | /** Maximum number of allowed bindings in that class. */ |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 760 | readonly max: number; |
Kai Ninomiya | 86b055d | 2020-01-06 19:37:25 -0800 | [diff] [blame] | 761 | // Add fields as needed |
| 762 | }; |
| 763 | } = /* prettier-ignore */ { |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 764 | 'uniformBuf': { class: 'uniformBuf', max: 12, }, |
Corentin Wallez | 06e16c5 | 2021-06-03 23:18:02 +0200 | [diff] [blame] | 765 | 'storageBuf': { class: 'storageBuf', max: 8, }, |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 766 | 'sampler': { class: 'sampler', max: 16, }, |
| 767 | 'sampledTex': { class: 'sampledTex', max: 16, }, |
Ben Clayton | 7a9ca6e | 2021-10-01 18:49:00 +0100 | [diff] [blame] | 768 | 'storageTex': { class: 'storageTex', max: 4, }, |
Kai Ninomiya | 86b055d | 2020-01-06 19:37:25 -0800 | [diff] [blame] | 769 | }; |
Kai Ninomiya | 86b055d | 2020-01-06 19:37:25 -0800 | [diff] [blame] | 770 | |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 771 | /** |
| 772 | * Default `PerPipelineLayout` binding limits, by spec. |
| 773 | */ |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 774 | export const kPerPipelineBindingLimits: { |
| 775 | readonly [k in PerPipelineBindingLimitClass]: { |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 776 | /** Which `PerPipelineLayout` binding limit class. */ |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 777 | readonly class: k; |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 778 | /** Maximum number of allowed bindings with `hasDynamicOffset: true` in that class. */ |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 779 | readonly maxDynamic: number; |
| 780 | // Add fields as needed |
| 781 | }; |
| 782 | } = /* prettier-ignore */ { |
| 783 | 'uniformBuf': { class: 'uniformBuf', maxDynamic: 8, }, |
| 784 | 'storageBuf': { class: 'storageBuf', maxDynamic: 4, }, |
| 785 | 'sampler': { class: 'sampler', maxDynamic: 0, }, |
| 786 | 'sampledTex': { class: 'sampledTex', maxDynamic: 0, }, |
| 787 | 'storageTex': { class: 'storageTex', maxDynamic: 0, }, |
| 788 | }; |
| 789 | |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 790 | interface BindingKindInfo { |
| 791 | readonly resource: ValidBindableResource; |
| 792 | readonly perStageLimitClass: typeof kPerStageBindingLimits[PerStageBindingLimitClass]; |
| 793 | readonly perPipelineLimitClass: typeof kPerPipelineBindingLimits[PerPipelineBindingLimitClass]; |
| 794 | // Add fields as needed |
| 795 | } |
| 796 | |
| 797 | const kBindingKind: { |
| 798 | readonly [k in ValidBindableResource]: BindingKindInfo; |
| 799 | } = /* prettier-ignore */ { |
Kai Ninomiya | 6c4d36b | 2020-12-18 13:40:50 -0800 | [diff] [blame] | 800 | uniformBuf: { resource: 'uniformBuf', perStageLimitClass: kPerStageBindingLimits.uniformBuf, perPipelineLimitClass: kPerPipelineBindingLimits.uniformBuf, }, |
| 801 | storageBuf: { resource: 'storageBuf', perStageLimitClass: kPerStageBindingLimits.storageBuf, perPipelineLimitClass: kPerPipelineBindingLimits.storageBuf, }, |
Kai Ninomiya | ff91b74 | 2021-04-20 18:41:59 -0700 | [diff] [blame] | 802 | filtSamp: { resource: 'filtSamp', perStageLimitClass: kPerStageBindingLimits.sampler, perPipelineLimitClass: kPerPipelineBindingLimits.sampler, }, |
| 803 | nonFiltSamp: { resource: 'nonFiltSamp', perStageLimitClass: kPerStageBindingLimits.sampler, perPipelineLimitClass: kPerPipelineBindingLimits.sampler, }, |
Kai Ninomiya | 6c4d36b | 2020-12-18 13:40:50 -0800 | [diff] [blame] | 804 | compareSamp: { resource: 'compareSamp', perStageLimitClass: kPerStageBindingLimits.sampler, perPipelineLimitClass: kPerPipelineBindingLimits.sampler, }, |
| 805 | sampledTex: { resource: 'sampledTex', perStageLimitClass: kPerStageBindingLimits.sampledTex, perPipelineLimitClass: kPerPipelineBindingLimits.sampledTex, }, |
| 806 | sampledTexMS: { resource: 'sampledTexMS', perStageLimitClass: kPerStageBindingLimits.sampledTex, perPipelineLimitClass: kPerPipelineBindingLimits.sampledTex, }, |
| 807 | storageTex: { resource: 'storageTex', perStageLimitClass: kPerStageBindingLimits.storageTex, perPipelineLimitClass: kPerPipelineBindingLimits.storageTex, }, |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 808 | }; |
| 809 | |
| 810 | // Binding type info |
| 811 | |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 812 | const kValidStagesAll = { |
Kai Ninomiya | 04e404f | 2020-10-23 16:02:19 -0700 | [diff] [blame] | 813 | validStages: |
| 814 | GPUConst.ShaderStage.VERTEX | GPUConst.ShaderStage.FRAGMENT | GPUConst.ShaderStage.COMPUTE, |
Kai Ninomiya | ff91b74 | 2021-04-20 18:41:59 -0700 | [diff] [blame] | 815 | } as const; |
Kai Ninomiya | 04e404f | 2020-10-23 16:02:19 -0700 | [diff] [blame] | 816 | const kValidStagesStorageWrite = { |
| 817 | validStages: GPUConst.ShaderStage.FRAGMENT | GPUConst.ShaderStage.COMPUTE, |
Kai Ninomiya | ff91b74 | 2021-04-20 18:41:59 -0700 | [diff] [blame] | 818 | } as const; |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 819 | |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 820 | /** Binding type info (including class limits) for the specified GPUBufferBindingLayout. */ |
Kai Ninomiya | ff91b74 | 2021-04-20 18:41:59 -0700 | [diff] [blame] | 821 | export function bufferBindingTypeInfo(d: GPUBufferBindingLayout) { |
| 822 | /* prettier-ignore */ |
| 823 | switch (d.type ?? 'uniform') { |
| 824 | case 'uniform': return { usage: GPUConst.BufferUsage.UNIFORM, ...kBindingKind.uniformBuf, ...kValidStagesAll, }; |
| 825 | case 'storage': return { usage: GPUConst.BufferUsage.STORAGE, ...kBindingKind.storageBuf, ...kValidStagesStorageWrite, }; |
| 826 | case 'read-only-storage': return { usage: GPUConst.BufferUsage.STORAGE, ...kBindingKind.storageBuf, ...kValidStagesAll, }; |
| 827 | } |
| 828 | } |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 829 | /** List of all GPUBufferBindingType values. */ |
Kai Ninomiya | ff91b74 | 2021-04-20 18:41:59 -0700 | [diff] [blame] | 830 | export const kBufferBindingTypes = ['uniform', 'storage', 'read-only-storage'] as const; |
| 831 | assertTypeTrue<TypeEqual<GPUBufferBindingType, typeof kBufferBindingTypes[number]>>(); |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 832 | |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 833 | /** Binding type info (including class limits) for the specified GPUSamplerBindingLayout. */ |
Kai Ninomiya | ff91b74 | 2021-04-20 18:41:59 -0700 | [diff] [blame] | 834 | export function samplerBindingTypeInfo(d: GPUSamplerBindingLayout) { |
| 835 | /* prettier-ignore */ |
| 836 | switch (d.type ?? 'filtering') { |
| 837 | case 'filtering': return { ...kBindingKind.filtSamp, ...kValidStagesAll, }; |
| 838 | case 'non-filtering': return { ...kBindingKind.nonFiltSamp, ...kValidStagesAll, }; |
| 839 | case 'comparison': return { ...kBindingKind.compareSamp, ...kValidStagesAll, }; |
| 840 | } |
| 841 | } |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 842 | /** List of all GPUSamplerBindingType values. */ |
Kai Ninomiya | ff91b74 | 2021-04-20 18:41:59 -0700 | [diff] [blame] | 843 | export const kSamplerBindingTypes = ['filtering', 'non-filtering', 'comparison'] as const; |
| 844 | assertTypeTrue<TypeEqual<GPUSamplerBindingType, typeof kSamplerBindingTypes[number]>>(); |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 845 | |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 846 | /** Binding type info (including class limits) for the specified GPUTextureBindingLayout. */ |
Kai Ninomiya | ff91b74 | 2021-04-20 18:41:59 -0700 | [diff] [blame] | 847 | export function sampledTextureBindingTypeInfo(d: GPUTextureBindingLayout) { |
| 848 | /* prettier-ignore */ |
| 849 | if (d.multisampled) { |
Brandon Jones | 201435f | 2021-08-12 13:47:21 -0700 | [diff] [blame] | 850 | return { usage: GPUConst.TextureUsage.TEXTURE_BINDING, ...kBindingKind.sampledTexMS, ...kValidStagesAll, }; |
Kai Ninomiya | d2919ff | 2021-05-11 19:21:17 -0700 | [diff] [blame] | 851 | } else { |
Brandon Jones | 201435f | 2021-08-12 13:47:21 -0700 | [diff] [blame] | 852 | return { usage: GPUConst.TextureUsage.TEXTURE_BINDING, ...kBindingKind.sampledTex, ...kValidStagesAll, }; |
Kai Ninomiya | ff91b74 | 2021-04-20 18:41:59 -0700 | [diff] [blame] | 853 | } |
| 854 | } |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 855 | /** List of all GPUTextureSampleType values. */ |
Kai Ninomiya | ff91b74 | 2021-04-20 18:41:59 -0700 | [diff] [blame] | 856 | export const kTextureSampleTypes = [ |
| 857 | 'float', |
| 858 | 'unfilterable-float', |
| 859 | 'depth', |
| 860 | 'sint', |
| 861 | 'uint', |
| 862 | ] as const; |
| 863 | assertTypeTrue<TypeEqual<GPUTextureSampleType, typeof kTextureSampleTypes[number]>>(); |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 864 | |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 865 | /** Binding type info (including class limits) for the specified GPUStorageTextureBindingLayout. */ |
Kai Ninomiya | ff91b74 | 2021-04-20 18:41:59 -0700 | [diff] [blame] | 866 | export function storageTextureBindingTypeInfo(d: GPUStorageTextureBindingLayout) { |
Brandon Jones | 4f2c3b6 | 2021-12-06 13:00:51 -0800 | [diff] [blame] | 867 | return { |
| 868 | usage: GPUConst.TextureUsage.STORAGE_BINDING, |
| 869 | ...kBindingKind.storageTex, |
| 870 | ...kValidStagesStorageWrite, |
| 871 | }; |
Kai Ninomiya | ff91b74 | 2021-04-20 18:41:59 -0700 | [diff] [blame] | 872 | } |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 873 | /** List of all GPUStorageTextureAccess values. */ |
Brandon Jones | 4f2c3b6 | 2021-12-06 13:00:51 -0800 | [diff] [blame] | 874 | export const kStorageTextureAccessValues = ['write-only'] as const; |
Kai Ninomiya | ff91b74 | 2021-04-20 18:41:59 -0700 | [diff] [blame] | 875 | assertTypeTrue<TypeEqual<GPUStorageTextureAccess, typeof kStorageTextureAccessValues[number]>>(); |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 876 | |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 877 | /** GPUBindGroupLayoutEntry, but only the "union" fields, not the common fields. */ |
Kai Ninomiya | ff91b74 | 2021-04-20 18:41:59 -0700 | [diff] [blame] | 878 | export type BGLEntry = Omit<GPUBindGroupLayoutEntry, 'binding' | 'visibility'>; |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 879 | /** Binding type info (including class limits) for the specified BGLEntry. */ |
Kai Ninomiya | ff91b74 | 2021-04-20 18:41:59 -0700 | [diff] [blame] | 880 | export function texBindingTypeInfo(e: BGLEntry) { |
| 881 | if (e.texture !== undefined) return sampledTextureBindingTypeInfo(e.texture); |
| 882 | if (e.storageTexture !== undefined) return storageTextureBindingTypeInfo(e.storageTexture); |
| 883 | unreachable(); |
| 884 | } |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 885 | /** BindingTypeInfo (including class limits) for the specified BGLEntry. */ |
Kai Ninomiya | ff91b74 | 2021-04-20 18:41:59 -0700 | [diff] [blame] | 886 | export function bindingTypeInfo(e: BGLEntry) { |
| 887 | if (e.buffer !== undefined) return bufferBindingTypeInfo(e.buffer); |
| 888 | if (e.texture !== undefined) return sampledTextureBindingTypeInfo(e.texture); |
| 889 | if (e.sampler !== undefined) return samplerBindingTypeInfo(e.sampler); |
| 890 | if (e.storageTexture !== undefined) return storageTextureBindingTypeInfo(e.storageTexture); |
| 891 | unreachable('GPUBindGroupLayoutEntry has no BindingLayout'); |
| 892 | } |
| 893 | |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 894 | /** |
| 895 | * Generate a list of possible buffer-typed BGLEntry values. |
| 896 | * |
| 897 | * Note: Generates different `type` options, but not `hasDynamicOffset` options. |
| 898 | */ |
Kai Ninomiya | ff91b74 | 2021-04-20 18:41:59 -0700 | [diff] [blame] | 899 | export function bufferBindingEntries(includeUndefined: boolean): readonly BGLEntry[] { |
| 900 | return [ |
| 901 | ...(includeUndefined ? [{ buffer: { type: undefined } }] : []), |
| 902 | { buffer: { type: 'uniform' } }, |
| 903 | { buffer: { type: 'storage' } }, |
| 904 | { buffer: { type: 'read-only-storage' } }, |
| 905 | ] as const; |
| 906 | } |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 907 | /** Generate a list of possible sampler-typed BGLEntry values. */ |
Kai Ninomiya | ff91b74 | 2021-04-20 18:41:59 -0700 | [diff] [blame] | 908 | export function samplerBindingEntries(includeUndefined: boolean): readonly BGLEntry[] { |
| 909 | return [ |
| 910 | ...(includeUndefined ? [{ sampler: { type: undefined } }] : []), |
| 911 | { sampler: { type: 'comparison' } }, |
| 912 | { sampler: { type: 'filtering' } }, |
| 913 | { sampler: { type: 'non-filtering' } }, |
| 914 | ] as const; |
| 915 | } |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 916 | /** |
| 917 | * Generate a list of possible texture-typed BGLEntry values. |
| 918 | * |
| 919 | * Note: Generates different `multisampled` options, but not `sampleType` or `viewDimension` options. |
| 920 | */ |
Kai Ninomiya | ff91b74 | 2021-04-20 18:41:59 -0700 | [diff] [blame] | 921 | export function textureBindingEntries(includeUndefined: boolean): readonly BGLEntry[] { |
| 922 | return [ |
| 923 | ...(includeUndefined ? [{ texture: { multisampled: undefined } }] : []), |
| 924 | { texture: { multisampled: false } }, |
| 925 | { texture: { multisampled: true } }, |
| 926 | ] as const; |
| 927 | } |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 928 | /** |
| 929 | * Generate a list of possible storageTexture-typed BGLEntry values. |
| 930 | * |
| 931 | * Note: Generates different `access` options, but not `format` or `viewDimension` options. |
| 932 | */ |
Kai Ninomiya | ff91b74 | 2021-04-20 18:41:59 -0700 | [diff] [blame] | 933 | export function storageTextureBindingEntries(format: GPUTextureFormat): readonly BGLEntry[] { |
Ben Clayton | 96bf729 | 2021-10-01 17:41:15 +0100 | [diff] [blame] | 934 | return [{ storageTexture: { access: 'write-only', format } }] as const; |
Kai Ninomiya | ff91b74 | 2021-04-20 18:41:59 -0700 | [diff] [blame] | 935 | } |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 936 | /** Generate a list of possible texture-or-storageTexture-typed BGLEntry values. */ |
Kai Ninomiya | ff91b74 | 2021-04-20 18:41:59 -0700 | [diff] [blame] | 937 | export function sampledAndStorageBindingEntries( |
| 938 | includeUndefined: boolean, |
| 939 | storageTextureFormat: GPUTextureFormat = 'rgba8unorm' |
| 940 | ): readonly BGLEntry[] { |
| 941 | return [ |
| 942 | ...textureBindingEntries(includeUndefined), |
| 943 | ...storageTextureBindingEntries(storageTextureFormat), |
| 944 | ] as const; |
| 945 | } |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 946 | /** |
| 947 | * Generate a list of possible BGLEntry values of every type, but not variants with different: |
Kai Ninomiya | ff91b74 | 2021-04-20 18:41:59 -0700 | [diff] [blame] | 948 | * - buffer.hasDynamicOffset |
| 949 | * - texture.sampleType |
| 950 | * - texture.viewDimension |
| 951 | * - storageTexture.viewDimension |
| 952 | */ |
| 953 | export function allBindingEntries( |
| 954 | includeUndefined: boolean, |
| 955 | storageTextureFormat: GPUTextureFormat = 'rgba8unorm' |
| 956 | ): readonly BGLEntry[] { |
| 957 | return [ |
| 958 | ...bufferBindingEntries(includeUndefined), |
| 959 | ...samplerBindingEntries(includeUndefined), |
| 960 | ...sampledAndStorageBindingEntries(includeUndefined, storageTextureFormat), |
| 961 | ] as const; |
| 962 | } |
| 963 | |
| 964 | // Shader stages |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 965 | |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 966 | /** List of all GPUShaderStage values. */ |
Lokbondo Kung | 300c10c | 2022-03-22 10:53:42 -0700 | [diff] [blame] | 967 | export type ShaderStageKey = keyof typeof GPUConst.ShaderStage; |
| 968 | export const kShaderStageKeys = Object.keys(GPUConst.ShaderStage) as ShaderStageKey[]; |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 969 | export const kShaderStages: readonly GPUShaderStageFlags[] = [ |
Kai Ninomiya | 04e404f | 2020-10-23 16:02:19 -0700 | [diff] [blame] | 970 | GPUConst.ShaderStage.VERTEX, |
| 971 | GPUConst.ShaderStage.FRAGMENT, |
| 972 | GPUConst.ShaderStage.COMPUTE, |
Justin Fan | 5d1b8c7 | 2020-01-15 16:03:37 -0800 | [diff] [blame] | 973 | ]; |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 974 | /** List of all possible combinations of GPUShaderStage values. */ |
Kai Ninomiya | 3a50e8b | 2020-04-28 20:38:31 -0700 | [diff] [blame] | 975 | 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] | 976 | |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 977 | /** |
| 978 | * List of all possible texture sampleCount values. |
| 979 | * |
Kai Ninomiya | 7c40d21 | 2022-01-04 14:25:02 -0800 | [diff] [blame] | 980 | * MAINTENANCE_TODO: Switch existing tests to use kTextureSampleCounts |
Kai Ninomiya | 97c60c4 | 2021-06-14 16:55:24 -0700 | [diff] [blame] | 981 | */ |
Enrico Galli | 94e47e9 | 2020-12-16 14:31:50 -0800 | [diff] [blame] | 982 | export const kTextureSampleCounts = [1, 4] as const; |
| 983 | |
Jiawei Shao | 1b9e873 | 2022-02-09 09:18:23 +0800 | [diff] [blame] | 984 | // Blend factors and Blend components |
| 985 | |
| 986 | /** List of all GPUBlendFactor values. */ |
| 987 | export const kBlendFactors: readonly GPUBlendFactor[] = [ |
| 988 | 'zero', |
| 989 | 'one', |
| 990 | 'src', |
| 991 | 'one-minus-src', |
| 992 | 'src-alpha', |
| 993 | 'one-minus-src-alpha', |
| 994 | 'dst', |
| 995 | 'one-minus-dst', |
| 996 | 'dst-alpha', |
| 997 | 'one-minus-dst-alpha', |
| 998 | 'src-alpha-saturated', |
| 999 | 'constant', |
| 1000 | 'one-minus-constant', |
| 1001 | ]; |
| 1002 | |
| 1003 | /** List of all GPUBlendOperation values. */ |
| 1004 | export const kBlendOperations: readonly GPUBlendOperation[] = [ |
| 1005 | 'add', // |
| 1006 | 'subtract', |
| 1007 | 'reverse-subtract', |
| 1008 | 'min', |
| 1009 | 'max', |
| 1010 | ]; |
| 1011 | |
ShrekShao | aa6069d | 2022-06-14 16:04:30 -0700 | [diff] [blame] | 1012 | // Primitive topologies |
| 1013 | export const kPrimitiveTopology: readonly GPUPrimitiveTopology[] = [ |
| 1014 | 'point-list', |
| 1015 | 'line-list', |
| 1016 | 'line-strip', |
| 1017 | 'triangle-list', |
| 1018 | 'triangle-strip', |
| 1019 | ]; |
| 1020 | assertTypeTrue<TypeEqual<GPUPrimitiveTopology, typeof kPrimitiveTopology[number]>>(); |
| 1021 | |
| 1022 | export const kIndexFormat: readonly GPUIndexFormat[] = ['uint16', 'uint32']; |
| 1023 | assertTypeTrue<TypeEqual<GPUIndexFormat, typeof kIndexFormat[number]>>(); |
| 1024 | |
Corentin Wallez | 27ca9f7 | 2022-03-30 21:01:47 +0100 | [diff] [blame] | 1025 | /** Info for each entry of GPUSupportedLimits */ |
| 1026 | export const kLimitInfo = /* prettier-ignore */ makeTable( |
| 1027 | [ 'class', 'default', 'maximumValue'] as const, |
| 1028 | [ 'maximum', , kMaxUnsignedLongValue] as const, { |
| 1029 | 'maxTextureDimension1D': [ , 8192, ], |
| 1030 | 'maxTextureDimension2D': [ , 8192, ], |
| 1031 | 'maxTextureDimension3D': [ , 2048, ], |
| 1032 | 'maxTextureArrayLayers': [ , 256, ], |
| 1033 | |
| 1034 | 'maxBindGroups': [ , 4, ], |
Greggman | 17eafee | 2023-02-07 19:55:14 -0800 | [diff] [blame] | 1035 | 'maxBindingsPerBindGroup': [ , 640, ], |
Corentin Wallez | 27ca9f7 | 2022-03-30 21:01:47 +0100 | [diff] [blame] | 1036 | 'maxDynamicUniformBuffersPerPipelineLayout': [ , 8, ], |
| 1037 | 'maxDynamicStorageBuffersPerPipelineLayout': [ , 4, ], |
| 1038 | 'maxSampledTexturesPerShaderStage': [ , 16, ], |
| 1039 | 'maxSamplersPerShaderStage': [ , 16, ], |
| 1040 | 'maxStorageBuffersPerShaderStage': [ , 8, ], |
| 1041 | 'maxStorageTexturesPerShaderStage': [ , 4, ], |
| 1042 | 'maxUniformBuffersPerShaderStage': [ , 12, ], |
| 1043 | |
| 1044 | 'maxUniformBufferBindingSize': [ , 65536, kMaxUnsignedLongLongValue], |
| 1045 | 'maxStorageBufferBindingSize': [ , 134217728, kMaxUnsignedLongLongValue], |
| 1046 | 'minUniformBufferOffsetAlignment': ['alignment', 256, ], |
| 1047 | 'minStorageBufferOffsetAlignment': ['alignment', 256, ], |
| 1048 | |
| 1049 | 'maxVertexBuffers': [ , 8, ], |
Lokbondo Kung | 73a99fe | 2023-01-26 16:08:52 -0800 | [diff] [blame] | 1050 | 'maxBufferSize': [ , 268435456, kMaxUnsignedLongLongValue], |
Corentin Wallez | 27ca9f7 | 2022-03-30 21:01:47 +0100 | [diff] [blame] | 1051 | 'maxVertexAttributes': [ , 16, ], |
| 1052 | 'maxVertexBufferArrayStride': [ , 2048, ], |
| 1053 | 'maxInterStageShaderComponents': [ , 60, ], |
| 1054 | |
Lokbondo Kung | a7e54e7 | 2023-01-26 11:51:32 -0800 | [diff] [blame] | 1055 | 'maxColorAttachments': [ , 8, ], |
| 1056 | 'maxColorAttachmentBytesPerSample': [ , 32, ], |
| 1057 | |
Austin Eng | 8f2742e | 2022-05-18 09:29:13 -0700 | [diff] [blame] | 1058 | 'maxComputeWorkgroupStorageSize': [ , 16384, ], |
Corentin Wallez | 27ca9f7 | 2022-03-30 21:01:47 +0100 | [diff] [blame] | 1059 | 'maxComputeInvocationsPerWorkgroup': [ , 256, ], |
| 1060 | 'maxComputeWorkgroupSizeX': [ , 256, ], |
| 1061 | 'maxComputeWorkgroupSizeY': [ , 256, ], |
| 1062 | 'maxComputeWorkgroupSizeZ': [ , 64, ], |
| 1063 | 'maxComputeWorkgroupsPerDimension': [ , 65535, ], |
| 1064 | } as const); |
| 1065 | |
| 1066 | /** List of all entries of GPUSupportedLimits. */ |
| 1067 | export const kLimits = keysOf(kLimitInfo); |
Austin Eng | 901b0c9 | 2022-04-11 17:50:10 -0700 | [diff] [blame] | 1068 | |
Lokbondo Kung | a7e54e7 | 2023-01-26 11:51:32 -0800 | [diff] [blame] | 1069 | // Pipeline limits |
| 1070 | |
| 1071 | /** Maximum number of color attachments to a render pass, by spec. */ |
| 1072 | export const kMaxColorAttachments = kLimitInfo.maxColorAttachments.default; |
| 1073 | /** `maxVertexBuffers` per GPURenderPipeline, by spec. */ |
| 1074 | export const kMaxVertexBuffers = kLimitInfo.maxVertexBuffers.default; |
| 1075 | /** `maxVertexAttributes` per GPURenderPipeline, by spec. */ |
| 1076 | export const kMaxVertexAttributes = kLimitInfo.maxVertexAttributes.default; |
| 1077 | /** `maxVertexBufferArrayStride` in a vertex buffer in a GPURenderPipeline, by spec. */ |
| 1078 | export const kMaxVertexBufferArrayStride = kLimitInfo.maxVertexBufferArrayStride.default; |
| 1079 | |
| 1080 | /** The size of indirect draw parameters in the indirectBuffer of drawIndirect */ |
| 1081 | export const kDrawIndirectParametersSize = 4; |
| 1082 | /** The size of indirect drawIndexed parameters in the indirectBuffer of drawIndexedIndirect */ |
| 1083 | export const kDrawIndexedIndirectParametersSize = 5; |
| 1084 | |
Lokbondo Kung | 3c353f8 | 2022-08-29 19:19:24 -0700 | [diff] [blame] | 1085 | /** Per-GPUFeatureName info. */ |
| 1086 | export const kFeatureNameInfo: { |
| 1087 | readonly [k in GPUFeatureName]: {}; |
| 1088 | } = /* prettier-ignore */ { |
| 1089 | 'depth-clip-control': {}, |
| 1090 | 'depth32float-stencil8': {}, |
| 1091 | 'texture-compression-bc': {}, |
| 1092 | 'texture-compression-etc2': {}, |
| 1093 | 'texture-compression-astc': {}, |
| 1094 | 'timestamp-query': {}, |
| 1095 | 'indirect-first-instance': {}, |
| 1096 | 'shader-f16': {}, |
Takahiro | cbdd47a | 2022-10-05 15:44:19 -0700 | [diff] [blame] | 1097 | 'rg11b10ufloat-renderable': {}, |
Lokbondo Kung | 3c353f8 | 2022-08-29 19:19:24 -0700 | [diff] [blame] | 1098 | }; |
| 1099 | /** List of all GPUFeatureName values. */ |
| 1100 | export const kFeatureNames = keysOf(kFeatureNameInfo); |
| 1101 | |
Austin Eng | 901b0c9 | 2022-04-11 17:50:10 -0700 | [diff] [blame] | 1102 | /** |
| 1103 | * Check if two formats are view format compatible. |
| 1104 | * |
| 1105 | * This function may need to be generalized to use `baseFormat` from `kTextureFormatInfo`. |
| 1106 | */ |
| 1107 | export function viewCompatible(a: GPUTextureFormat, b: GPUTextureFormat): boolean { |
| 1108 | return a === b || a + '-srgb' === b || b + '-srgb' === a; |
| 1109 | } |
Austin Eng | 318d3d0 | 2022-05-03 07:10:10 -1000 | [diff] [blame] | 1110 | |
| 1111 | export function getFeaturesForFormats<T>( |
| 1112 | formats: readonly (T & (GPUTextureFormat | undefined))[] |
| 1113 | ): readonly (GPUFeatureName | undefined)[] { |
| 1114 | return Array.from(new Set(formats.map(f => (f ? kTextureFormatInfo[f].feature : undefined)))); |
| 1115 | } |
| 1116 | |
| 1117 | export function filterFormatsByFeature<T>( |
| 1118 | feature: GPUFeatureName | undefined, |
| 1119 | formats: readonly (T & (GPUTextureFormat | undefined))[] |
| 1120 | ): readonly (T & (GPUTextureFormat | undefined))[] { |
| 1121 | return formats.filter(f => f === undefined || kTextureFormatInfo[f].feature === feature); |
| 1122 | } |
| 1123 | |
| 1124 | export const kFeaturesForFormats = getFeaturesForFormats(kTextureFormats); |