export const description = 'checkPixels helpers behave as expected against real textures'; import { makeTestGroup } from '../../../common/framework/test_group.js'; import { getBlockInfoForColorTextureFormat } from '../../format_info.js'; import { AllFeaturesMaxLimitsGPUTest } from '../../gpu_test.js'; import { TexelView } from './texel_view.js'; import { textureContentIsOKByT2B } from './texture_ok.js'; export const g = makeTestGroup(AllFeaturesMaxLimitsGPUTest); g.test('float32') .desc(`Basic test that actual/expected must match, for float32.`) .params(u => u .combineWithParams([ { format: 'rgba32float' }, // { format: 'rg32float' }, ] as const) .beginSubcases() .combineWithParams([ // Expected data is 0.6 in all channels { data: 0.6, opts: { maxFractionalDiff: 0.0000001 }, _ok: true }, { data: 0.6, opts: { maxDiffULPsForFloatFormat: 1 }, _ok: true }, { data: 0.5999, opts: { maxFractionalDiff: 0 }, _ok: false }, { data: 0.5999, opts: { maxFractionalDiff: 0.0001001 }, _ok: true }, { data: 0.6001, opts: { maxFractionalDiff: 0 }, _ok: false }, { data: 0.6001, opts: { maxFractionalDiff: 0.0001001 }, _ok: true }, { data: 0.5999, opts: { maxDiffULPsForFloatFormat: 1677 }, _ok: false }, { data: 0.5999, opts: { maxDiffULPsForFloatFormat: 1678 }, _ok: true }, { data: 0.6001, opts: { maxDiffULPsForFloatFormat: 1676 }, _ok: false }, { data: 0.6001, opts: { maxDiffULPsForFloatFormat: 1677 }, _ok: true }, ]) ) .fn(async t => { const { format, data, opts, _ok } = t.params; const size = [1, 1]; const texture = t.createTextureTracked({ format, size, usage: GPUTextureUsage.COPY_DST | GPUTextureUsage.COPY_SRC, }); t.device.queue.writeTexture({ texture }, new Float32Array([data, data, data, data]), {}, size); const expColor = { R: 0.6, G: 0.6, B: 0.6, A: 0.6 }; const expTexelView = TexelView.fromTexelsAsColors(format, _coords => expColor); const result = await textureContentIsOKByT2B(t, { texture }, size, { expTexelView }, opts); t.expect((result === undefined) === _ok, `expected ${_ok}, got ${result === undefined}`); }); g.test('norm') .desc(`Basic test that actual/expected must match, for unorm/snorm.`) .params(u => u .combine('mode', ['bytes', 'colors'] as const) .combineWithParams([ { format: 'r8unorm', _maxValue: 255 }, { format: 'r8snorm', _maxValue: 127 }, { format: 'r16unorm', _maxValue: 65535 }, { format: 'r16snorm', _maxValue: 32767 }, ] as const) .beginSubcases() .combineWithParams([ // Expected data is [10, 10] { data: [10, 10], _ok: true }, { data: [10, 11], _ok: false }, { data: [11, 10], _ok: false }, { data: [11, 11], _ok: false }, ]) ) .fn(async t => { const { mode, format, _maxValue, data, _ok } = t.params; t.skipIfTextureFormatNotSupported(format); const size = [2, 1]; const texture = t.createTextureTracked({ format, size, usage: GPUTextureUsage.COPY_DST | GPUTextureUsage.COPY_SRC, }); const { bytesPerBlock } = getBlockInfoForColorTextureFormat(format); const [InputCtor, ExpectCtor] = bytesPerBlock === 1 ? [Int8Array, Uint8Array] : [Int16Array, Uint16Array]; t.device.queue.writeTexture({ texture }, new InputCtor(data), {}, size); let expTexelView; switch (mode) { case 'bytes': expTexelView = TexelView.fromTexelsAsBytes( format, _coords => new Uint8Array(new ExpectCtor([10]).buffer) ); break; case 'colors': expTexelView = TexelView.fromTexelsAsColors(format, _coords => ({ R: 10 / _maxValue })); break; } const result = await textureContentIsOKByT2B( t, { texture }, size, { expTexelView }, { maxDiffULPsForNormFormat: 0 } ); t.expect((result === undefined) === _ok, result?.message); }); g.test('snorm_min') .desc( `The minimum snorm value has two possible representations (e.g. -127 and -128). Ensure that actual/expected can mismatch in both directions and pass the test.` ) .params(u => u // .combine('mode', ['bytes', 'colors'] as const) .combineWithParams([ // { format: 'r8snorm', _maxValue: 127 }, ] as const) ) .fn(async t => { const { mode, format, _maxValue } = t.params; const data = [-_maxValue, -_maxValue - 1]; const size = [2, 1]; const texture = t.createTextureTracked({ format, size, usage: GPUTextureUsage.COPY_DST | GPUTextureUsage.COPY_SRC, }); t.device.queue.writeTexture({ texture }, new Int8Array(data), {}, size); let expTexelView; switch (mode) { case 'bytes': { // Actual value should be [-127,-128], expected value is [-128,-127], both should pass. const exp = [-_maxValue - 1, -_maxValue]; expTexelView = TexelView.fromTexelsAsBytes( format, coords => new Uint8Array([exp[coords.x]]) ); } break; case 'colors': expTexelView = TexelView.fromTexelsAsColors(format, _coords => ({ R: -1 })); break; } const result = await textureContentIsOKByT2B( t, { texture }, size, { expTexelView }, { maxDiffULPsForNormFormat: 0 } ); t.expectOK(result); });