diff --git a/src/unittests/floating_point.spec.ts b/src/unittests/floating_point.spec.ts index e8f8525d7f83..0d843076d7f3 100644 --- a/src/unittests/floating_point.spec.ts +++ b/src/unittests/floating_point.spec.ts @@ -3536,19 +3536,27 @@ const kRoundIntervalCases = { f32: [ { input: 2 ** 30, expected: 2 ** 30 }, { input: -(2 ** 30), expected: -(2 ** 30) }, - { input: 0x80000000, expected: 0x80000000 }, // https://github.com/gpuweb/cts/issues/2766 + { input: 0x8000_0000, expected: 0x8000_0000 }, // https://github.com/gpuweb/cts/issues/2766 ], f16: [ { input: 2 ** 14, expected: 2 ** 14 }, { input: -(2 ** 14), expected: -(2 ** 14) }, { input: 0x8000, expected: 0x8000 }, // https://github.com/gpuweb/cts/issues/2766 ], + abstract: [ + { input: 2 ** 62, expected: 2 ** 62 }, + { input: -(2 ** 62), expected: -(2 ** 62) }, + { + input: 0x8000_0000_0000_0000, + expected: 0x8000_0000_0000_0000, + }, // https://github.com/gpuweb/cts/issues/2766 + ], } as const; g.test('roundInterval') .params(u => u - .combine('trait', ['f32', 'f16'] as const) + .combine('trait', ['f32', 'f16', 'abstract'] as const) .beginSubcases() .expandWithParams(p => { const constants = FP[p.trait].constants(); @@ -3579,7 +3587,7 @@ g.test('roundInterval') { input: constants.negative.max, expected: 0 }, ...kRoundIntervalCases[p.trait], - // 32-bit subnormals + // Subnormals { input: constants.positive.subnormal.max, expected: 0 }, { input: constants.positive.subnormal.min, expected: 0 }, { input: constants.negative.subnormal.min, expected: 0 }, diff --git a/src/webgpu/api/operation/command_buffer/image_copy.spec.ts b/src/webgpu/api/operation/command_buffer/image_copy.spec.ts index 4eebc3d611e4..beb87c02c38f 100644 --- a/src/webgpu/api/operation/command_buffer/image_copy.spec.ts +++ b/src/webgpu/api/operation/command_buffer/image_copy.spec.ts @@ -1413,6 +1413,7 @@ bytes in copy works for every format. .beforeAllSubcases(t => { const info = kTextureFormatInfo[t.params.format]; t.skipIfTextureFormatNotSupported(t.params.format); + t.skipIfCopyTextureToTextureNotSupportedForFormat(t.params.format); t.selectDeviceOrSkipTestCase(info.feature); }) .fn(t => { @@ -1510,6 +1511,7 @@ works for every format with 2d and 2d-array textures. .beforeAllSubcases(t => { const info = kTextureFormatInfo[t.params.format]; t.skipIfTextureFormatNotSupported(t.params.format); + t.skipIfCopyTextureToTextureNotSupportedForFormat(t.params.format); t.selectDeviceOrSkipTestCase(info.feature); }) .fn(t => { @@ -1590,6 +1592,7 @@ for all formats. We pass origin and copyExtent as [number, number, number].` .beforeAllSubcases(t => { const info = kTextureFormatInfo[t.params.format]; t.skipIfTextureFormatNotSupported(t.params.format); + t.skipIfCopyTextureToTextureNotSupportedForFormat(t.params.format); t.selectDeviceOrSkipTestCase(info.feature); }) .fn(t => { @@ -1790,6 +1793,7 @@ TODO: Make a variant for depth-stencil formats. .beforeAllSubcases(t => { const info = kTextureFormatInfo[t.params.format]; t.skipIfTextureFormatNotSupported(t.params.format); + t.skipIfCopyTextureToTextureNotSupportedForFormat(t.params.format); t.selectDeviceOrSkipTestCase(info.feature); }) .fn(t => { diff --git a/src/webgpu/api/validation/encoding/createRenderBundleEncoder.spec.ts b/src/webgpu/api/validation/encoding/createRenderBundleEncoder.spec.ts index 2eaa9b43fd23..b4beeb8fbe5d 100644 --- a/src/webgpu/api/validation/encoding/createRenderBundleEncoder.spec.ts +++ b/src/webgpu/api/validation/encoding/createRenderBundleEncoder.spec.ts @@ -196,10 +196,7 @@ g.test('valid_texture_formats') g.test('depth_stencil_readonly') .desc( ` - Tests that createRenderBundleEncoder validation of depthReadOnly and stencilReadOnly - - With depth-only formats - - With stencil-only formats - - With depth-stencil-combined formats + Test that allow combinations of depth-stencil format, depthReadOnly and stencilReadOnly are allowed. ` ) .params(u => @@ -215,44 +212,9 @@ g.test('depth_stencil_readonly') }) .fn(t => { const { depthStencilFormat, depthReadOnly, stencilReadOnly } = t.params; - - let shouldError = false; - if ( - kTextureFormatInfo[depthStencilFormat].depth && - kTextureFormatInfo[depthStencilFormat].stencil && - depthReadOnly !== stencilReadOnly - ) { - shouldError = true; - } - - t.expectValidationError(() => { - t.device.createRenderBundleEncoder({ - colorFormats: [], - depthStencilFormat, - depthReadOnly, - stencilReadOnly, - }); - }, shouldError); - }); - -g.test('depth_stencil_readonly_with_undefined_depth') - .desc( - ` - Tests that createRenderBundleEncoder validation of depthReadOnly and stencilReadOnly is ignored - if there is no depthStencilFormat set. - ` - ) - .params(u => - u // - .beginSubcases() - .combine('depthReadOnly', [false, true]) - .combine('stencilReadOnly', [false, true]) - ) - .fn(t => { - const { depthReadOnly, stencilReadOnly } = t.params; - t.device.createRenderBundleEncoder({ - colorFormats: ['bgra8unorm'], + colorFormats: [], + depthStencilFormat, depthReadOnly, stencilReadOnly, }); diff --git a/src/webgpu/api/validation/encoding/render_bundle.spec.ts b/src/webgpu/api/validation/encoding/render_bundle.spec.ts index 883b634446ce..35bdc9958388 100644 --- a/src/webgpu/api/validation/encoding/render_bundle.spec.ts +++ b/src/webgpu/api/validation/encoding/render_bundle.spec.ts @@ -3,7 +3,7 @@ Tests execution of render bundles. `; import { makeTestGroup } from '../../../../common/framework/test_group.js'; -import { kDepthStencilFormats, kTextureFormatInfo } from '../../../format_info.js'; +import { kDepthStencilFormats } from '../../../format_info.js'; import { ValidationTest } from '../validation_test.js'; export const g = makeTestGroup(ValidationTest); @@ -170,18 +170,6 @@ g.test('depth_stencil_readonly_mismatch') .combine('bundleStencilReadOnly', [false, true]) .combine('passDepthReadOnly', [false, true]) .combine('passStencilReadOnly', [false, true]) - .filter(p => { - // For combined depth/stencil formats the depth and stencil read only state must match - // in order to create a valid render bundle or render pass. - const depthStencilInfo = kTextureFormatInfo[p.depthStencilFormat]; - if (depthStencilInfo.depth && depthStencilInfo.stencil) { - return ( - p.passDepthReadOnly === p.passStencilReadOnly && - p.bundleDepthReadOnly === p.bundleStencilReadOnly - ); - } - return true; - }) ) .beforeAllSubcases(t => { t.selectDeviceForTextureFormatOrSkipTestCase(t.params.depthStencilFormat); diff --git a/src/webgpu/api/validation/render_pass/attachment_compatibility.spec.ts b/src/webgpu/api/validation/render_pass/attachment_compatibility.spec.ts index c0ab23b91c8e..241d576e396d 100644 --- a/src/webgpu/api/validation/render_pass/attachment_compatibility.spec.ts +++ b/src/webgpu/api/validation/render_pass/attachment_compatibility.spec.ts @@ -551,13 +551,6 @@ Test that the depth stencil read only state in render passes or bundles is compa .filter(p => { if (p.format) { const depthStencilInfo = kTextureFormatInfo[p.format]; - // For combined depth/stencil formats the depth and stencil read only state must match - // in order to create a valid render bundle or render pass. - if (depthStencilInfo.depth && depthStencilInfo.stencil) { - if (p.depthReadOnly !== p.stencilReadOnly) { - return false; - } - } // If the format has no depth aspect, the depthReadOnly, depthWriteEnabled of the pipeline must not be true // in order to create a valid render pipeline. if (!depthStencilInfo.depth && p.depthWriteEnabled) { diff --git a/src/webgpu/api/validation/render_pass/render_pass_descriptor.spec.ts b/src/webgpu/api/validation/render_pass/render_pass_descriptor.spec.ts index 9713beea5262..82e376567894 100644 --- a/src/webgpu/api/validation/render_pass/render_pass_descriptor.spec.ts +++ b/src/webgpu/api/validation/render_pass/render_pass_descriptor.spec.ts @@ -909,10 +909,8 @@ g.test('depth_stencil_attachment,loadOp_storeOp_match_depthReadOnly_stencilReadO const hasDepth = info.depth; const hasStencil = info.stencil; - const goodAspectCombo = - (hasDepth && hasStencil ? !depthReadOnly === !stencilReadOnly : true) && - (hasDepthSettings ? hasDepth : true) && - (hasStencilSettings ? hasStencil : true); + const goodAspectSettingsPresent = + (hasDepthSettings ? hasDepth : true) && (hasStencilSettings ? hasStencil : true); const hasBothDepthOps = !!depthLoadOp && !!depthStoreOp; const hasBothStencilOps = !!stencilLoadOp && !!stencilStoreOp; @@ -923,7 +921,7 @@ g.test('depth_stencil_attachment,loadOp_storeOp_match_depthReadOnly_stencilReadO const goodStencilCombo = hasStencil && !stencilReadOnly ? hasBothStencilOps : hasNeitherStencilOps; - const shouldError = !goodAspectCombo || !goodDepthCombo || !goodStencilCombo; + const shouldError = !goodAspectSettingsPresent || !goodDepthCombo || !goodStencilCombo; t.expectValidationError(() => { encoder.finish(); diff --git a/src/webgpu/listing_meta.json b/src/webgpu/listing_meta.json index 55d9e98f1a2e..c8396bab2ffc 100644 --- a/src/webgpu/listing_meta.json +++ b/src/webgpu/listing_meta.json @@ -517,7 +517,6 @@ "webgpu:api,validation,encoding,createRenderBundleEncoder:attachment_state,limits,maxColorAttachmentBytesPerSample,unaligned:*": { "subcaseMS": 0.750 }, "webgpu:api,validation,encoding,createRenderBundleEncoder:attachment_state,limits,maxColorAttachments:*": { "subcaseMS": 0.145 }, "webgpu:api,validation,encoding,createRenderBundleEncoder:depth_stencil_readonly:*": { "subcaseMS": 1.804 }, - "webgpu:api,validation,encoding,createRenderBundleEncoder:depth_stencil_readonly_with_undefined_depth:*": { "subcaseMS": 14.825 }, "webgpu:api,validation,encoding,createRenderBundleEncoder:valid_texture_formats:*": { "subcaseMS": 2.130 }, "webgpu:api,validation,encoding,encoder_open_state:compute_pass_commands:*": { "subcaseMS": 4.208 }, "webgpu:api,validation,encoding,encoder_open_state:non_pass_commands:*": { "subcaseMS": 26.191 }, @@ -1360,7 +1359,7 @@ "webgpu:shader,execution,expression,call,builtin,refract:f32_vec4:*": { "subcaseMS": 610.150 }, "webgpu:shader,execution,expression,call,builtin,reverseBits:i32:*": { "subcaseMS": 9.594 }, "webgpu:shader,execution,expression,call,builtin,reverseBits:u32:*": { "subcaseMS": 7.969 }, - "webgpu:shader,execution,expression,call,builtin,round:abstract_float:*": { "subcaseMS": 19.408 }, + "webgpu:shader,execution,expression,call,builtin,round:abstract_float:*": { "subcaseMS": 450.551 }, "webgpu:shader,execution,expression,call,builtin,round:f16:*": { "subcaseMS": 30.509 }, "webgpu:shader,execution,expression,call,builtin,round:f32:*": { "subcaseMS": 12.407 }, "webgpu:shader,execution,expression,call,builtin,saturate:abstract_float:*": { "subcaseMS": 527.425 }, diff --git a/src/webgpu/shader/execution/expression/call/builtin/round.spec.ts b/src/webgpu/shader/execution/expression/call/builtin/round.spec.ts index bd40ed4b2a3e..fe81af632660 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/round.spec.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/round.spec.ts @@ -12,13 +12,13 @@ Component-wise when T is a vector. import { makeTestGroup } from '../../../../../../common/framework/test_group.js'; import { GPUTest } from '../../../../../gpu_test.js'; -import { TypeF32, TypeF16 } from '../../../../../util/conversion.js'; +import { TypeF32, TypeF16, TypeAbstractFloat } from '../../../../../util/conversion.js'; import { FP } from '../../../../../util/floating_point.js'; -import { fullF32Range, fullF16Range } from '../../../../../util/math.js'; +import { fullF32Range, fullF16Range, fullF64Range } from '../../../../../util/math.js'; import { makeCaseCache } from '../../case_cache.js'; -import { allInputSources, run } from '../../expression.js'; +import { allInputSources, onlyConstInputSource, run } from '../../expression.js'; -import { builtin } from './builtin.js'; +import { abstractBuiltin, builtin } from './builtin.js'; export const g = makeTestGroup(GPUTest); @@ -43,15 +43,30 @@ export const d = makeCaseCache('round', { FP.f16.roundInterval ); }, + abstract: () => { + return FP.abstract.generateScalarToIntervalCases( + [ + 0x8000_0000_0000_0000, // https://github.com/gpuweb/cts/issues/2766 + ...fullF64Range(), + ], + 'unfiltered', + FP.abstract.roundInterval + ); + }, }); g.test('abstract_float') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') .desc(`abstract float tests`) .params(u => - u.combine('inputSource', allInputSources).combine('vectorize', [undefined, 2, 3, 4] as const) + u + .combine('inputSource', onlyConstInputSource) + .combine('vectorize', [undefined, 2, 3, 4] as const) ) - .unimplemented(); + .fn(async t => { + const cases = await d.get('abstract'); + await run(t, abstractBuiltin('round'), [TypeAbstractFloat], TypeAbstractFloat, t.params, cases); + }); g.test('f32') .specURL('https://www.w3.org/TR/WGSL/#float-builtin-functions') diff --git a/src/webgpu/util/floating_point.ts b/src/webgpu/util/floating_point.ts index e271e7db7a24..7662d6649cf0 100644 --- a/src/webgpu/util/floating_point.ts +++ b/src/webgpu/util/floating_point.ts @@ -5108,7 +5108,7 @@ class FPAbstractTraits extends FPTraits { public readonly remainderInterval = (x: number, y: number): FPInterval => { return this.toInterval(kF32Traits.remainderInterval(x, y)); }; - public readonly roundInterval = this.unimplementedScalarToInterval.bind(this, 'roundInterval'); + public readonly roundInterval = this.roundIntervalImpl.bind(this); public readonly saturateInterval = this.saturateIntervalImpl.bind(this); public readonly signInterval = this.signIntervalImpl.bind(this); public readonly sinInterval = this.unimplementedScalarToInterval.bind(this, 'sinInterval');