export const description = ` Test for texture_ok utils. `; import { makeTestGroup } from '../common/framework/test_group.js'; import { typedArrayFromParam, typedArrayParam } from '../common/util/util.js'; import { RegularTextureFormat } from '../webgpu/format_info.js'; import { TexelView } from '../webgpu/util/texture/texel_view.js'; import { findFailedPixels } from '../webgpu/util/texture/texture_ok.js'; import { UnitTest } from './unit_test.js'; class F extends UnitTest { test(act: string, exp: string): void { this.expect(act === exp, 'got: ' + act.replace('\n', '⏎')); } } export const g = makeTestGroup(F); g.test('findFailedPixels') .desc( ` Test findFailedPixels passes what is expected to pass and fails what is expected to fail. For example NaN === NaN should be true in a texture that allows NaN. 2 different representations of the same rgb9e5ufloat should compare as equal. etc... ` ) .params(u => u.combineWithParams([ // Sanity Check { format: 'rgba8unorm' as RegularTextureFormat, actual: typedArrayParam('Uint8Array', [0x00, 0x40, 0x80, 0xff]), expected: typedArrayParam('Uint8Array', [0x00, 0x40, 0x80, 0xff]), isSame: true, }, // Slightly different values { format: 'rgba8unorm' as RegularTextureFormat, actual: typedArrayParam('Uint8Array', [0x00, 0x40, 0x80, 0xff]), expected: typedArrayParam('Uint8Array', [0x00, 0x40, 0x81, 0xff]), isSame: false, }, // Different representations of the same value { format: 'rgb9e5ufloat' as RegularTextureFormat, actual: typedArrayParam('Uint8Array', [0x78, 0x56, 0x34, 0x12]), expected: typedArrayParam('Uint8Array', [0xf0, 0xac, 0x68, 0x0c]), isSame: true, }, // Slightly different values { format: 'rgb9e5ufloat' as RegularTextureFormat, actual: typedArrayParam('Uint8Array', [0x78, 0x56, 0x34, 0x12]), expected: typedArrayParam('Uint8Array', [0xf1, 0xac, 0x68, 0x0c]), isSame: false, }, // Test NaN === NaN { format: 'r32float' as RegularTextureFormat, actual: typedArrayParam('Float32Array', [parseFloat('abc')]), expected: typedArrayParam('Float32Array', [parseFloat('def')]), isSame: true, }, // Sanity Check { format: 'r32float' as RegularTextureFormat, actual: typedArrayParam('Float32Array', [1.23]), expected: typedArrayParam('Float32Array', [1.23]), isSame: true, }, // Slightly different values. { format: 'r32float' as RegularTextureFormat, actual: typedArrayParam('Uint32Array', [0x3f9d70a4]), expected: typedArrayParam('Uint32Array', [0x3f9d70a5]), isSame: false, }, // Slightly different { format: 'rg11b10ufloat' as RegularTextureFormat, actual: typedArrayParam('Uint32Array', [0x3ce]), expected: typedArrayParam('Uint32Array', [0x3cf]), isSame: false, }, // Positive.Infinity === Positive.Infinity (red) { format: 'rg11b10ufloat' as RegularTextureFormat, actual: typedArrayParam('Uint32Array', [0b11111000000]), expected: typedArrayParam('Uint32Array', [0b11111000000]), isSame: true, }, // Positive.Infinity === Positive.Infinity (green) { format: 'rg11b10ufloat' as RegularTextureFormat, actual: typedArrayParam('Uint32Array', [0b11111000000_00000000000]), expected: typedArrayParam('Uint32Array', [0b11111000000_00000000000]), isSame: true, }, // Positive.Infinity === Positive.Infinity (blue) { format: 'rg11b10ufloat' as RegularTextureFormat, actual: typedArrayParam('Uint32Array', [0b1111100000_00000000000_00000000000]), expected: typedArrayParam('Uint32Array', [0b1111100000_00000000000_00000000000]), isSame: true, }, // NaN === NaN (red) { format: 'rg11b10ufloat' as RegularTextureFormat, actual: typedArrayParam('Uint32Array', [0b11111000001]), expected: typedArrayParam('Uint32Array', [0b11111000010]), isSame: true, }, // NaN === NaN (green) { format: 'rg11b10ufloat' as RegularTextureFormat, actual: typedArrayParam('Uint32Array', [0b11111000100_00000000000]), expected: typedArrayParam('Uint32Array', [0b11111001000_00000000000]), isSame: true, }, // NaN === NaN (blue) { format: 'rg11b10ufloat' as RegularTextureFormat, actual: typedArrayParam('Uint32Array', [0b1111110000_00000000000_00000000000]), expected: typedArrayParam('Uint32Array', [0b1111101000_00000000000_00000000000]), isSame: true, }, ]) ) .fn(t => { const { format, actual, expected, isSame } = t.params; const actualData = new Uint8Array(typedArrayFromParam(actual).buffer); const expectedData = new Uint8Array(typedArrayFromParam(expected).buffer); const actTexelView = TexelView.fromTextureDataByReference(format, actualData, { bytesPerRow: actualData.byteLength, rowsPerImage: 1, subrectOrigin: [0, 0, 0], subrectSize: [1, 1, 1], }); const expTexelView = TexelView.fromTextureDataByReference(format, expectedData, { bytesPerRow: expectedData.byteLength, rowsPerImage: 1, subrectOrigin: [0, 0, 0], subrectSize: [1, 1, 1], }); const zero = { x: 0, y: 0, z: 0 }; const failedPixelsMessage = findFailedPixels( format, zero, { width: 1, height: 1, depthOrArrayLayers: 1 }, { actTexelView, expTexelView }, { maxFractionalDiff: 0, } ); t.expect(isSame === !failedPixelsMessage, failedPixelsMessage); });