diff --git a/src/webgpu/api/validation/render_pipeline/multisample_state.spec.ts b/src/webgpu/api/validation/render_pipeline/multisample_state.spec.ts index 9241e0071cdb..4c8db5041a59 100644 --- a/src/webgpu/api/validation/render_pipeline/multisample_state.spec.ts +++ b/src/webgpu/api/validation/render_pipeline/multisample_state.spec.ts @@ -3,7 +3,12 @@ This test dedicatedly tests validation of GPUMultisampleState of createRenderPip `; import { makeTestGroup } from '../../../../common/framework/test_group.js'; -import { kDefaultFragmentShaderCode } from '../../../util/shader.js'; +import { + kPossibleColorRenderableTextureFormats, + isColorTextureFormatWithAlpha, + isTextureFormatBlendable, +} from '../../../format_info.js'; +import { kDefaultVertexShaderCode, kDefaultFragmentShaderCode } from '../../../util/shader.js'; import * as vtu from '../validation_test_utils.js'; import { CreateRenderPipelineValidationTest } from './common.js'; @@ -47,6 +52,90 @@ g.test('alpha_to_coverage,count') vtu.doCreateRenderPipelineTest(t, isAsync, _success, descriptor); }); +g.test('alpha_to_coverage,fragment_stage_required') + .desc(`If multisample.alphaToCoverageEnabled is true, a fragment stage must be provided.`) + .params(u => + u + .combine('isAsync', [false, true]) + .combine('alphaToCoverageEnabled', [false, true]) + .beginSubcases() + .combine('noFragment', [false, true]) + ) + .fn(t => { + const { isAsync, alphaToCoverageEnabled, noFragment } = t.params; + + const descriptor = t.getDescriptor({ + multisample: { alphaToCoverageEnabled, count: 4 }, + noFragment, + depthStencil: { format: 'depth32float', depthWriteEnabled: false }, + }); + + const _success = !(alphaToCoverageEnabled && noFragment); + vtu.doCreateRenderPipelineTest(t, isAsync, _success, descriptor); + }); + +g.test('alpha_to_coverage,first_target_required') + .desc(`If multisample.alphaToCoverageEnabled is true, a fragment.targets[0] must exist.`) + .params(u => + u + .combine('isAsync', [false, true]) + .combine('alphaToCoverageEnabled', [false, true]) + .beginSubcases() + .combine('targetIndex', [0, 1]) + ) + .fn(t => { + const { isAsync, alphaToCoverageEnabled, targetIndex } = t.params; + + const targets = []; + targets[targetIndex] = { format: 'rgba8unorm' as const }; + + const descriptor = { + vertex: { module: t.device.createShaderModule({ code: kDefaultVertexShaderCode }) }, + fragment: { + module: t.device.createShaderModule({ + code: ` + @fragment fn fs() -> @location(${targetIndex}) vec4f { + return vec4f(); + } + `, + }), + targets, + }, + multisample: { alphaToCoverageEnabled, count: 4 }, + layout: 'auto' as const, + }; + + const _success = !(alphaToCoverageEnabled && targetIndex === 1); + vtu.doCreateRenderPipelineTest(t, isAsync, _success, descriptor); + }); + +g.test('alpha_to_coverage,first_format_blendable_and_has_alpha') + .desc( + `If multisample.alphaToCoverageEnabled is true, a fragment.targets[0].format must be blendable.` + ) + .params(u => + u + .combine('isAsync', [false, true]) + .combine('alphaToCoverageEnabled', [false, true]) + .beginSubcases() + .combine('format', kPossibleColorRenderableTextureFormats) + ) + .fn(t => { + const { isAsync, alphaToCoverageEnabled, format } = t.params; + t.skipIfTextureFormatNotSupported(format); + t.skipIfTextureFormatNotUsableAsRenderAttachment(format); + + const descriptor = t.getDescriptor({ + targets: [{ format }], + multisample: { alphaToCoverageEnabled, count: 4 }, + }); + + const blendableWithAlpha = + isTextureFormatBlendable(t.device.features, format) && isColorTextureFormatWithAlpha(format); + const _success = !alphaToCoverageEnabled || blendableWithAlpha; + vtu.doCreateRenderPipelineTest(t, isAsync, _success, descriptor); + }); + g.test('alpha_to_coverage,sample_mask') .desc( `If sample_mask builtin is a pipeline output of fragment, multisample.alphaToCoverageEnabled should be false.` diff --git a/src/webgpu/format_info.ts b/src/webgpu/format_info.ts index d2101305f7dd..8c09c3eb0f15 100644 --- a/src/webgpu/format_info.ts +++ b/src/webgpu/format_info.ts @@ -90,6 +90,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ r8unorm: { color: { type: 'float', + componentCount: 1, copySrc: true, copyDst: true, storage: false, @@ -103,6 +104,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ r8snorm: { color: { type: 'float', + componentCount: 1, copySrc: true, copyDst: true, storage: false, @@ -115,6 +117,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ r8uint: { color: { type: 'uint', + componentCount: 1, copySrc: true, copyDst: true, storage: false, @@ -128,6 +131,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ r8sint: { color: { type: 'sint', + componentCount: 1, copySrc: true, copyDst: true, storage: false, @@ -142,6 +146,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ rg8unorm: { color: { type: 'float', + componentCount: 2, copySrc: true, copyDst: true, storage: false, @@ -155,6 +160,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ rg8snorm: { color: { type: 'float', + componentCount: 2, copySrc: true, copyDst: true, storage: false, @@ -167,6 +173,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ rg8uint: { color: { type: 'uint', + componentCount: 2, copySrc: true, copyDst: true, storage: false, @@ -180,6 +187,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ rg8sint: { color: { type: 'sint', + componentCount: 2, copySrc: true, copyDst: true, storage: false, @@ -194,6 +202,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ rgba8unorm: { color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: true, @@ -208,6 +217,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ 'rgba8unorm-srgb': { color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -222,6 +232,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ rgba8snorm: { color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: true, @@ -234,6 +245,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ rgba8uint: { color: { type: 'uint', + componentCount: 4, copySrc: true, copyDst: true, storage: true, @@ -247,6 +259,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ rgba8sint: { color: { type: 'sint', + componentCount: 4, copySrc: true, copyDst: true, storage: true, @@ -260,6 +273,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ bgra8unorm: { color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -274,6 +288,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ 'bgra8unorm-srgb': { color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -291,6 +306,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ r16unorm: { color: { type: 'unfilterable-float', + componentCount: 1, copySrc: true, copyDst: true, storage: true, @@ -305,6 +321,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ r16snorm: { color: { type: 'unfilterable-float', + componentCount: 1, copySrc: true, copyDst: true, storage: true, @@ -319,6 +336,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ r16uint: { color: { type: 'uint', + componentCount: 1, copySrc: true, copyDst: true, storage: false, @@ -332,6 +350,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ r16sint: { color: { type: 'sint', + componentCount: 1, copySrc: true, copyDst: true, storage: false, @@ -345,6 +364,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ r16float: { color: { type: 'float', + componentCount: 1, copySrc: true, copyDst: true, storage: false, @@ -359,6 +379,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ rg16unorm: { color: { type: 'unfilterable-float', + componentCount: 2, copySrc: true, copyDst: true, storage: true, @@ -373,6 +394,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ rg16snorm: { color: { type: 'unfilterable-float', + componentCount: 2, copySrc: true, copyDst: true, storage: true, @@ -387,6 +409,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ rg16uint: { color: { type: 'uint', + componentCount: 2, copySrc: true, copyDst: true, storage: false, @@ -400,6 +423,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ rg16sint: { color: { type: 'sint', + componentCount: 2, copySrc: true, copyDst: true, storage: false, @@ -413,6 +437,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ rg16float: { color: { type: 'float', + componentCount: 2, copySrc: true, copyDst: true, storage: false, @@ -427,6 +452,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ rgba16unorm: { color: { type: 'unfilterable-float', + componentCount: 4, copySrc: true, copyDst: true, storage: true, @@ -441,6 +467,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ rgba16snorm: { color: { type: 'unfilterable-float', + componentCount: 4, copySrc: true, copyDst: true, storage: true, @@ -455,6 +482,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ rgba16uint: { color: { type: 'uint', + componentCount: 4, copySrc: true, copyDst: true, storage: true, @@ -468,6 +496,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ rgba16sint: { color: { type: 'sint', + componentCount: 4, copySrc: true, copyDst: true, storage: true, @@ -481,6 +510,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ rgba16float: { color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: true, @@ -497,6 +527,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ r32uint: { color: { type: 'uint', + componentCount: 1, copySrc: true, copyDst: true, storage: true, @@ -510,6 +541,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ r32sint: { color: { type: 'sint', + componentCount: 1, copySrc: true, copyDst: true, storage: true, @@ -523,6 +555,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ r32float: { color: { type: 'unfilterable-float', + componentCount: 1, copySrc: true, copyDst: true, storage: true, @@ -537,6 +570,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ rg32uint: { color: { type: 'uint', + componentCount: 2, copySrc: true, copyDst: true, storage: true, @@ -550,6 +584,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ rg32sint: { color: { type: 'sint', + componentCount: 2, copySrc: true, copyDst: true, storage: true, @@ -563,6 +598,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ rg32float: { color: { type: 'unfilterable-float', + componentCount: 2, copySrc: true, copyDst: true, storage: true, @@ -577,6 +613,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ rgba32uint: { color: { type: 'uint', + componentCount: 4, copySrc: true, copyDst: true, storage: true, @@ -590,6 +627,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ rgba32sint: { color: { type: 'sint', + componentCount: 4, copySrc: true, copyDst: true, storage: true, @@ -603,6 +641,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ rgba32float: { color: { type: 'unfilterable-float', + componentCount: 4, copySrc: true, copyDst: true, storage: true, @@ -619,6 +658,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ rgb10a2uint: { color: { type: 'uint', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -632,6 +672,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ rgb10a2unorm: { color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -645,6 +686,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ rg11b10ufloat: { color: { type: 'float', + componentCount: 3, copySrc: true, copyDst: true, storage: false, @@ -661,6 +703,7 @@ const kRegularTextureFormatInfo = formatTableWithDefaults({ rgb9e5ufloat: { color: { type: 'float', + componentCount: 3, copySrc: true, copyDst: true, storage: false, @@ -778,6 +821,7 @@ const kBCTextureFormatInfo = formatTableWithDefaults({ 'bc1-rgba-unorm': { color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -790,6 +834,7 @@ const kBCTextureFormatInfo = formatTableWithDefaults({ 'bc1-rgba-unorm-srgb': { color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -803,6 +848,7 @@ const kBCTextureFormatInfo = formatTableWithDefaults({ 'bc2-rgba-unorm': { color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -815,6 +861,7 @@ const kBCTextureFormatInfo = formatTableWithDefaults({ 'bc2-rgba-unorm-srgb': { color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -828,6 +875,7 @@ const kBCTextureFormatInfo = formatTableWithDefaults({ 'bc3-rgba-unorm': { color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -840,6 +888,7 @@ const kBCTextureFormatInfo = formatTableWithDefaults({ 'bc3-rgba-unorm-srgb': { color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -853,6 +902,7 @@ const kBCTextureFormatInfo = formatTableWithDefaults({ 'bc4-r-unorm': { color: { type: 'float', + componentCount: 1, copySrc: true, copyDst: true, storage: false, @@ -864,6 +914,7 @@ const kBCTextureFormatInfo = formatTableWithDefaults({ 'bc4-r-snorm': { color: { type: 'float', + componentCount: 1, copySrc: true, copyDst: true, storage: false, @@ -876,6 +927,7 @@ const kBCTextureFormatInfo = formatTableWithDefaults({ 'bc5-rg-unorm': { color: { type: 'float', + componentCount: 2, copySrc: true, copyDst: true, storage: false, @@ -887,6 +939,7 @@ const kBCTextureFormatInfo = formatTableWithDefaults({ 'bc5-rg-snorm': { color: { type: 'float', + componentCount: 2, copySrc: true, copyDst: true, storage: false, @@ -899,6 +952,7 @@ const kBCTextureFormatInfo = formatTableWithDefaults({ 'bc6h-rgb-ufloat': { color: { type: 'float', + componentCount: 3, copySrc: true, copyDst: true, storage: false, @@ -910,6 +964,7 @@ const kBCTextureFormatInfo = formatTableWithDefaults({ 'bc6h-rgb-float': { color: { type: 'float', + componentCount: 3, copySrc: true, copyDst: true, storage: false, @@ -922,6 +977,7 @@ const kBCTextureFormatInfo = formatTableWithDefaults({ 'bc7-rgba-unorm': { color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -934,6 +990,7 @@ const kBCTextureFormatInfo = formatTableWithDefaults({ 'bc7-rgba-unorm-srgb': { color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -957,6 +1014,7 @@ const kETC2TextureFormatInfo = formatTableWithDefaults({ 'etc2-rgb8unorm': { color: { type: 'float', + componentCount: 3, copySrc: true, copyDst: true, storage: false, @@ -969,6 +1027,7 @@ const kETC2TextureFormatInfo = formatTableWithDefaults({ 'etc2-rgb8unorm-srgb': { color: { type: 'float', + componentCount: 3, copySrc: true, copyDst: true, storage: false, @@ -982,6 +1041,7 @@ const kETC2TextureFormatInfo = formatTableWithDefaults({ 'etc2-rgb8a1unorm': { color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -994,6 +1054,7 @@ const kETC2TextureFormatInfo = formatTableWithDefaults({ 'etc2-rgb8a1unorm-srgb': { color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -1007,6 +1068,7 @@ const kETC2TextureFormatInfo = formatTableWithDefaults({ 'etc2-rgba8unorm': { color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -1019,6 +1081,7 @@ const kETC2TextureFormatInfo = formatTableWithDefaults({ 'etc2-rgba8unorm-srgb': { color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -1032,6 +1095,7 @@ const kETC2TextureFormatInfo = formatTableWithDefaults({ 'eac-r11unorm': { color: { type: 'float', + componentCount: 1, copySrc: true, copyDst: true, storage: false, @@ -1043,6 +1107,7 @@ const kETC2TextureFormatInfo = formatTableWithDefaults({ 'eac-r11snorm': { color: { type: 'float', + componentCount: 1, copySrc: true, copyDst: true, storage: false, @@ -1055,6 +1120,7 @@ const kETC2TextureFormatInfo = formatTableWithDefaults({ 'eac-rg11unorm': { color: { type: 'float', + componentCount: 2, copySrc: true, copyDst: true, storage: false, @@ -1066,6 +1132,7 @@ const kETC2TextureFormatInfo = formatTableWithDefaults({ 'eac-rg11snorm': { color: { type: 'float', + componentCount: 2, copySrc: true, copyDst: true, storage: false, @@ -1088,6 +1155,7 @@ const kASTCTextureFormatInfo = formatTableWithDefaults({ blockHeight: 4, color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -1102,6 +1170,7 @@ const kASTCTextureFormatInfo = formatTableWithDefaults({ blockHeight: 4, color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -1117,6 +1186,7 @@ const kASTCTextureFormatInfo = formatTableWithDefaults({ blockHeight: 4, color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -1131,6 +1201,7 @@ const kASTCTextureFormatInfo = formatTableWithDefaults({ blockHeight: 4, color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -1146,6 +1217,7 @@ const kASTCTextureFormatInfo = formatTableWithDefaults({ blockHeight: 5, color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -1160,6 +1232,7 @@ const kASTCTextureFormatInfo = formatTableWithDefaults({ blockHeight: 5, color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -1175,6 +1248,7 @@ const kASTCTextureFormatInfo = formatTableWithDefaults({ blockHeight: 5, color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -1189,6 +1263,7 @@ const kASTCTextureFormatInfo = formatTableWithDefaults({ blockHeight: 5, color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -1204,6 +1279,7 @@ const kASTCTextureFormatInfo = formatTableWithDefaults({ blockHeight: 6, color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -1218,6 +1294,7 @@ const kASTCTextureFormatInfo = formatTableWithDefaults({ blockHeight: 6, color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -1233,6 +1310,7 @@ const kASTCTextureFormatInfo = formatTableWithDefaults({ blockHeight: 5, color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -1247,6 +1325,7 @@ const kASTCTextureFormatInfo = formatTableWithDefaults({ blockHeight: 5, color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -1262,6 +1341,7 @@ const kASTCTextureFormatInfo = formatTableWithDefaults({ blockHeight: 6, color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -1276,6 +1356,7 @@ const kASTCTextureFormatInfo = formatTableWithDefaults({ blockHeight: 6, color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -1291,6 +1372,7 @@ const kASTCTextureFormatInfo = formatTableWithDefaults({ blockHeight: 8, color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -1305,6 +1387,7 @@ const kASTCTextureFormatInfo = formatTableWithDefaults({ blockHeight: 8, color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -1320,6 +1403,7 @@ const kASTCTextureFormatInfo = formatTableWithDefaults({ blockHeight: 5, color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -1334,6 +1418,7 @@ const kASTCTextureFormatInfo = formatTableWithDefaults({ blockHeight: 5, color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -1349,6 +1434,7 @@ const kASTCTextureFormatInfo = formatTableWithDefaults({ blockHeight: 6, color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -1363,6 +1449,7 @@ const kASTCTextureFormatInfo = formatTableWithDefaults({ blockHeight: 6, color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -1378,6 +1465,7 @@ const kASTCTextureFormatInfo = formatTableWithDefaults({ blockHeight: 8, color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -1392,6 +1480,7 @@ const kASTCTextureFormatInfo = formatTableWithDefaults({ blockHeight: 8, color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -1407,6 +1496,7 @@ const kASTCTextureFormatInfo = formatTableWithDefaults({ blockHeight: 10, color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -1421,6 +1511,7 @@ const kASTCTextureFormatInfo = formatTableWithDefaults({ blockHeight: 10, color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -1436,6 +1527,7 @@ const kASTCTextureFormatInfo = formatTableWithDefaults({ blockHeight: 10, color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -1450,6 +1542,7 @@ const kASTCTextureFormatInfo = formatTableWithDefaults({ blockHeight: 10, color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -1465,6 +1558,7 @@ const kASTCTextureFormatInfo = formatTableWithDefaults({ blockHeight: 12, color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -1479,6 +1573,7 @@ const kASTCTextureFormatInfo = formatTableWithDefaults({ blockHeight: 12, color: { type: 'float', + componentCount: 4, copySrc: true, copyDst: true, storage: false, @@ -1555,6 +1650,8 @@ interface TextureFormatColorAspectInfo extends TextureFormatAspectInfo { bytes: number; /** "Best" sample type of the format. "float" also implies "unfilterable-float". */ type: 'float' | 'uint' | 'sint' | 'unfilterable-float'; + /** The number of components specified in the format in the order R, G, B then A. */ + componentCount: number; } /** Per GPUTextureFormat-per-aspect info for depth aspects. */ interface TextureFormatDepthAspectInfo extends TextureFormatAspectInfo { @@ -1665,6 +1762,7 @@ type TextureFormatInfo_TypeCheck = { * These are also usable before or during a test * * * isColorTextureFormat + * * isColorTextureFormatWithAlpha * * isDepthTextureFormat * * isStencilTextureFormat * * isDepthOrStencilTextureFormat @@ -2328,6 +2426,10 @@ export function isColorTextureFormat(format: GPUTextureFormat) { return !!kTextureFormatInfo[format].color; } +export function isColorTextureFormatWithAlpha(format: GPUTextureFormat) { + return isColorTextureFormat(format) && kTextureFormatInfo[format].color?.componentCount === 4; +} + export function isDepthTextureFormat(format: GPUTextureFormat) { return !!kTextureFormatInfo[format].depth; } @@ -2397,6 +2499,9 @@ export function isTextureFormatBlendable( if (is32Float(format)) { return hasFeature(features, 'float32-blendable'); } + if (isTextureFormatTier1EnablesRenderAttachmentBlendableMultisample(format)) { + return hasFeature(features, 'texture-formats-tier1'); + } return !!kAllTextureFormatInfo[format].colorRender?.blend; }