-
Notifications
You must be signed in to change notification settings - Fork 86
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Start adding queue validation tests for buffers and textures
- Loading branch information
Showing
2 changed files
with
305 additions
and
0 deletions.
There are no files selected for viewing
147 changes: 147 additions & 0 deletions
147
src/webgpu/api/validation/queue/destroyed/buffer.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
export const description = ` | ||
Tests using a destroyed buffer on a queue. | ||
TODO: | ||
- test renderPass/renderBundle (setVertexBuffer, setIndexBuffer) | ||
- test renderPass (resolveQuerySet) | ||
- test renderPass/computePass (setBindGroup) | ||
`; | ||
|
||
import { makeTestGroup } from '../../../../../common/framework/test_group.js'; | ||
import { ValidationTest } from '../../validation_test.js'; | ||
|
||
export const g = makeTestGroup(ValidationTest); | ||
|
||
g.test('writeBuffer') | ||
.desc( | ||
` | ||
Tests that using a destroyed buffer in writeBuffer fails. | ||
- x= {destroyed, not destroyed (control case)} | ||
` | ||
) | ||
.paramsSubcasesOnly(u => u.combine('destroyed', [false, true] as const)) | ||
.fn(t => { | ||
const { destroyed } = t.params; | ||
const buffer = t.trackForCleanup( | ||
t.device.createBuffer({ | ||
size: 4, | ||
usage: GPUBufferUsage.COPY_DST, | ||
}) | ||
); | ||
|
||
if (destroyed) { | ||
buffer.destroy(); | ||
} | ||
|
||
t.expectValidationError(() => t.queue.writeBuffer(buffer, 0, new Uint8Array(4)), destroyed); | ||
}); | ||
|
||
g.test('copyBufferToBuffer') | ||
.desc( | ||
` | ||
Tests that using a destroyed buffer in copyBufferToBuffer fails. | ||
- x= {not destroyed (control case), src destroyed, dst destroyed} | ||
` | ||
) | ||
.paramsSubcasesOnly(u => u.combine('destroyed', ['none', 'src', 'dst', 'both'] as const)) | ||
.fn(t => { | ||
const src = t.trackForCleanup( | ||
t.device.createBuffer({ size: 4, usage: GPUBufferUsage.COPY_SRC }) | ||
); | ||
const dst = t.trackForCleanup( | ||
t.device.createBuffer({ size: 4, usage: GPUBufferUsage.COPY_DST }) | ||
); | ||
|
||
const encoder = t.device.createCommandEncoder(); | ||
encoder.copyBufferToBuffer(src, 0, dst, 0, dst.size); | ||
const commandBuffer = encoder.finish(); | ||
|
||
let shouldError = true; | ||
switch (t.params.destroyed) { | ||
case 'none': | ||
shouldError = false; | ||
break; | ||
case 'src': | ||
src.destroy(); | ||
break; | ||
case 'dst': | ||
dst.destroy(); | ||
break; | ||
case 'both': | ||
src.destroy(); | ||
dst.destroy(); | ||
break; | ||
} | ||
|
||
t.expectValidationError(() => { | ||
t.queue.submit([commandBuffer]); | ||
}, shouldError); | ||
}); | ||
|
||
g.test('copyBufferToTexture') | ||
.desc( | ||
` | ||
Tests that using a destroyed buffer in copyBufferToTexture fails. | ||
- x= {not destroyed (control case), src destroyed} | ||
` | ||
) | ||
.paramsSubcasesOnly(u => u.combine('destroyed', [false, true] as const)) | ||
.fn(t => { | ||
const { destroyed } = t.params; | ||
const buffer = t.trackForCleanup( | ||
t.device.createBuffer({ size: 4, usage: GPUBufferUsage.COPY_SRC }) | ||
); | ||
const texture = t.trackForCleanup( | ||
t.device.createTexture({ | ||
size: [1, 1, 1], | ||
format: 'rgba8unorm', | ||
usage: GPUTextureUsage.COPY_DST, | ||
}) | ||
); | ||
|
||
const encoder = t.device.createCommandEncoder(); | ||
encoder.copyBufferToTexture({ buffer }, { texture }, [1, 1, 1]); | ||
const commandBuffer = encoder.finish(); | ||
|
||
if (destroyed) { | ||
buffer.destroy(); | ||
} | ||
|
||
t.expectValidationError(() => { | ||
t.queue.submit([commandBuffer]); | ||
}, destroyed); | ||
}); | ||
|
||
g.test('copyTextureToBuffer') | ||
.desc( | ||
` | ||
Tests that using a destroyed buffer in copyTextureToBuffer fails. | ||
- x= {not destroyed (control case), dst destroyed} | ||
` | ||
) | ||
.paramsSubcasesOnly(u => u.combine('destroyed', [false, true] as const)) | ||
.fn(t => { | ||
const { destroyed } = t.params; | ||
const texture = t.trackForCleanup( | ||
t.device.createTexture({ | ||
size: [1, 1, 1], | ||
format: 'rgba8unorm', | ||
usage: GPUTextureUsage.COPY_SRC, | ||
}) | ||
); | ||
const buffer = t.trackForCleanup( | ||
t.device.createBuffer({ size: 4, usage: GPUBufferUsage.COPY_DST }) | ||
); | ||
|
||
const encoder = t.device.createCommandEncoder(); | ||
encoder.copyTextureToBuffer({ texture }, { buffer }, [1, 1, 1]); | ||
const commandBuffer = encoder.finish(); | ||
|
||
if (destroyed) { | ||
buffer.destroy(); | ||
} | ||
|
||
t.expectValidationError(() => { | ||
t.queue.submit([commandBuffer]); | ||
}, destroyed); | ||
}); |
158 changes: 158 additions & 0 deletions
158
src/webgpu/api/validation/queue/destroyed/texture.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
export const description = ` | ||
Tests using a destroyed texture on a queue. | ||
TODO: | ||
- test renderPass/computePass (setBindGroup) | ||
- test beginRenderPass target | ||
`; | ||
|
||
import { makeTestGroup } from '../../../../../common/framework/test_group.js'; | ||
import { ValidationTest } from '../../validation_test.js'; | ||
|
||
export const g = makeTestGroup(ValidationTest); | ||
|
||
g.test('writeTexture') | ||
.desc( | ||
` | ||
Tests that using a destroyed texture in writeTexture fails. | ||
- x= {destroyed, not destroyed (control case)} | ||
` | ||
) | ||
.paramsSubcasesOnly(u => u.combine('destroyed', [false, true] as const)) | ||
.fn(t => { | ||
const { destroyed } = t.params; | ||
const texture = t.trackForCleanup( | ||
t.device.createTexture({ | ||
size: [1, 1, 1], | ||
format: 'rgba8unorm', | ||
usage: GPUTextureUsage.COPY_DST, | ||
}) | ||
); | ||
|
||
if (destroyed) { | ||
texture.destroy(); | ||
} | ||
|
||
t.expectValidationError( | ||
() => t.queue.writeTexture({ texture }, new Uint8Array(4), { bytesPerRow: 4 }, [1, 1, 1]), | ||
destroyed | ||
); | ||
}); | ||
|
||
g.test('copyTextureToTexture') | ||
.desc( | ||
` | ||
Tests that using a destroyed texture in copyTextureToTexture fails. | ||
- x= {not destroyed (control case), src destroyed, dst destroyed} | ||
` | ||
) | ||
.paramsSubcasesOnly(u => u.combine('destroyed', ['none', 'src', 'dst', 'both'] as const)) | ||
.fn(t => { | ||
const src = t.trackForCleanup( | ||
t.device.createTexture({ | ||
size: [1, 1, 1], | ||
format: 'rgba8unorm', | ||
usage: GPUTextureUsage.COPY_SRC, | ||
}) | ||
); | ||
const dst = t.trackForCleanup( | ||
t.device.createTexture({ | ||
size: [1, 1, 1], | ||
format: 'rgba8unorm', | ||
usage: GPUTextureUsage.COPY_DST, | ||
}) | ||
); | ||
|
||
const encoder = t.device.createCommandEncoder(); | ||
encoder.copyTextureToTexture({ texture: src }, { texture: dst }, [1, 1, 1]); | ||
const commandBuffer = encoder.finish(); | ||
|
||
let shouldError = true; | ||
switch (t.params.destroyed) { | ||
case 'none': | ||
shouldError = false; | ||
break; | ||
case 'src': | ||
src.destroy(); | ||
break; | ||
case 'dst': | ||
dst.destroy(); | ||
break; | ||
case 'both': | ||
src.destroy(); | ||
dst.destroy(); | ||
break; | ||
} | ||
|
||
t.expectValidationError(() => { | ||
t.queue.submit([commandBuffer]); | ||
}, shouldError); | ||
}); | ||
|
||
g.test('copyBufferToTexture') | ||
.desc( | ||
` | ||
Tests that using a destroyed texture in copyBufferToTexture fails. | ||
- x= {not destroyed (control case), dst destroyed} | ||
` | ||
) | ||
.paramsSubcasesOnly(u => u.combine('destroyed', [false, true] as const)) | ||
.fn(t => { | ||
const { destroyed } = t.params; | ||
const buffer = t.trackForCleanup( | ||
t.device.createBuffer({ size: 4, usage: GPUBufferUsage.COPY_SRC }) | ||
); | ||
const texture = t.trackForCleanup( | ||
t.device.createTexture({ | ||
size: [1, 1, 1], | ||
format: 'rgba8unorm', | ||
usage: GPUTextureUsage.COPY_DST, | ||
}) | ||
); | ||
|
||
const encoder = t.device.createCommandEncoder(); | ||
encoder.copyBufferToTexture({ buffer }, { texture }, [1, 1, 1]); | ||
const commandBuffer = encoder.finish(); | ||
|
||
if (destroyed) { | ||
texture.destroy(); | ||
} | ||
|
||
t.expectValidationError(() => { | ||
t.queue.submit([commandBuffer]); | ||
}, destroyed); | ||
}); | ||
|
||
g.test('copyTextureToBuffer') | ||
.desc( | ||
` | ||
Tests that using a destroyed texture in copyTextureToBuffer fails. | ||
- x= {not destroyed (control case), src destroyed} | ||
` | ||
) | ||
.paramsSubcasesOnly(u => u.combine('destroyed', [false, true] as const)) | ||
.fn(t => { | ||
const { destroyed } = t.params; | ||
const texture = t.trackForCleanup( | ||
t.device.createTexture({ | ||
size: [1, 1, 1], | ||
format: 'rgba8unorm', | ||
usage: GPUTextureUsage.COPY_SRC, | ||
}) | ||
); | ||
const buffer = t.trackForCleanup( | ||
t.device.createBuffer({ size: 4, usage: GPUBufferUsage.COPY_DST }) | ||
); | ||
|
||
const encoder = t.device.createCommandEncoder(); | ||
encoder.copyTextureToBuffer({ texture }, { buffer }, [1, 1, 1]); | ||
const commandBuffer = encoder.finish(); | ||
|
||
if (destroyed) { | ||
texture.destroy(); | ||
} | ||
|
||
t.expectValidationError(() => { | ||
t.queue.submit([commandBuffer]); | ||
}, destroyed); | ||
}); |