Skip to content

Commit

Permalink
[WIP] update copyToTexture tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kainino0x committed Mar 15, 2022
1 parent a44939d commit 20404bf
Show file tree
Hide file tree
Showing 4 changed files with 201 additions and 329 deletions.
2 changes: 1 addition & 1 deletion src/common/framework/fixture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ export class Fixture {
* Wraps an async function, passing it an `Error` object recording the original stack trace.
* The async work will be implicitly waited upon before reporting a test status.
*/
protected eventualAsyncExpectation<T>(fn: (niceStack: Error) => Promise<T>): Promise<T> {
eventualAsyncExpectation<T>(fn: (niceStack: Error) => Promise<T>): Promise<T> {
const promise = fn(new Error());
this.eventualExpectations.push(promise);
return promise;
Expand Down
146 changes: 12 additions & 134 deletions src/webgpu/util/copy_to_texture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ import { assert, memcpy } from '../../common/util/util.js';
import { RegularTextureFormat, kTextureFormatInfo } from '../capability_info.js';
import { GPUTest } from '../gpu_test.js';

import { checkElementsEqual, checkElementsBetween } from './check_contents.js';
import { align } from './math.js';
import { kBytesPerRowAlignment } from './texture/layout.js';
import { checkPixelsByT2B } from './texture/check_pixels.js';
import { kTexelRepresentationInfo } from './texture/texel_data.js';
import { TexelView } from './texture/texel_view.js';

export function isFp16Format(format: GPUTextureFormat): boolean {
switch (format) {
Expand Down Expand Up @@ -44,36 +43,6 @@ export class CopyToTextureUtils extends GPUTest {
return dstPixels;
}

/**
* If the destination format specifies a transfer function,
* copyExternalImageToTexture (like B2T/T2T copies) should ignore it.
*/
formatForExpectedPixels(format: RegularTextureFormat): RegularTextureFormat {
return format === 'rgba8unorm-srgb'
? 'rgba8unorm'
: format === 'bgra8unorm-srgb'
? 'bgra8unorm'
: format;
}

getSourceImageBitmapPixels(
sourcePixels: Uint8ClampedArray,
width: number,
height: number,
isPremultiplied: boolean,
isFlipY: boolean
): Uint8ClampedArray {
return this.getExpectedPixels(
sourcePixels,
width,
height,
'rgba8unorm',
false,
isPremultiplied,
isFlipY
);
}

getExpectedPixels(
sourcePixels: Uint8ClampedArray,
width: number,
Expand Down Expand Up @@ -127,117 +96,26 @@ export class CopyToTextureUtils extends GPUTest {
return expectedPixels;
}

// MAINTENANCE_TODO(crbug.com/dawn/868): Should be possible to consolidate this along with texture checking
checkCopyExternalImageResult(
src: GPUBuffer,
expected: ArrayBufferView,
width: number,
height: number,
bytesPerPixel: number,
isFp16: boolean
): void {
const exp = new Uint8Array(expected.buffer, expected.byteOffset, expected.byteLength);
const rowPitch = align(width * bytesPerPixel, kBytesPerRowAlignment);

const readbackPromise = this.readGPUBufferRangeTyped(src, {
type: Uint8Array,
typedLength: rowPitch * height,
});

this.eventualAsyncExpectation(async niceStack => {
const readback = await readbackPromise;
const check = this.checkBufferWithRowPitch(
readback.data,
exp,
width,
height,
rowPitch,
bytesPerPixel,
isFp16
);
if (check !== undefined) {
niceStack.message = check;
this.rec.expectationFailed(niceStack);
}
readback.cleanup();
});
}

// MAINTENANCE_TODO(crbug.com/dawn/868): Should be possible to consolidate this along with texture checking
checkBufferWithRowPitch(
actual: Uint8Array,
exp: Uint8Array,
width: number,
height: number,
rowPitch: number,
bytesPerPixel: number,
isFp16: boolean
): string | undefined {
const bytesPerRow = width * bytesPerPixel;
// When dst format is fp16 formats, the expectation and real result always has 1 bit difference in the ending
// (e.g. CC vs CD) if there needs some alpha ops (if alpha channel is not 0.0 or 1.0). Suspect it is errors when
// doing encoding. We check fp16 dst texture format with 1-bit ULP tolerance.
if (isFp16) {
for (let y = 0; y < height; ++y) {
const expRow = exp.subarray(y * bytesPerRow, bytesPerRow);
const checkResult = checkElementsBetween(actual.subarray(y * rowPitch, bytesPerRow), [
i => (expRow[i] > 0 ? expRow[i] - 1 : expRow[i]),
i => expRow[i] + 1,
]);
if (checkResult !== undefined) return `on row ${y}: ${checkResult}`;
}
} else {
for (let y = 0; y < height; ++y) {
const checkResult = checkElementsEqual(
actual.subarray(y * rowPitch, bytesPerRow),
exp.subarray(y * bytesPerRow, bytesPerRow)
);
if (checkResult !== undefined) return `on row ${y}: ${checkResult}`;
}
}
return undefined;
}

doTestAndCheckResult(
imageCopyExternalImage: GPUImageCopyExternalImage,
dstTextureCopyView: GPUImageCopyTextureTagged,
copySize: GPUExtent3DDict,
bytesPerPixel: number,
expectedData: Uint8ClampedArray,
isFp16: boolean
expTexelView: TexelView,
copySize: Required<GPUExtent3DDict>
): void {
this.device.queue.copyExternalImageToTexture(
imageCopyExternalImage,
dstTextureCopyView,
copySize
);

const externalImage = imageCopyExternalImage.source;
const dstTexture = dstTextureCopyView.texture;

const bytesPerRow = align(externalImage.width * bytesPerPixel, kBytesPerRowAlignment);
const testBuffer = this.device.createBuffer({
size: bytesPerRow * externalImage.height,
usage: GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST,
this.eventualAsyncExpectation(async niceStack => {
this.expectOK(
await checkPixelsByT2B(this, { texture: dstTextureCopyView.texture }, copySize, {
maxDiffULPs: 0,
expTexelView,
}),
{ niceStack }
);
});
this.trackForCleanup(testBuffer);

const encoder = this.device.createCommandEncoder();

encoder.copyTextureToBuffer(
{ texture: dstTexture, mipLevel: 0, origin: { x: 0, y: 0, z: 0 } },
{ buffer: testBuffer, bytesPerRow },
{ width: externalImage.width, height: externalImage.height, depthOrArrayLayers: 1 }
);
this.device.queue.submit([encoder.finish()]);

this.checkCopyExternalImageResult(
testBuffer,
expectedData,
externalImage.width,
externalImage.height,
bytesPerPixel,
isFp16
);
}
}
Loading

0 comments on commit 20404bf

Please sign in to comment.