|
| 1 | +export const description = ` |
| 2 | +Buffer tests in createBindGroup. |
| 3 | +`; |
| 4 | + |
| 5 | +import { makeTestGroup } from '../../../../common/framework/test_group.js'; |
| 6 | +import { AllFeaturesMaxLimitsGPUTest } from '../../../gpu_test.js'; |
| 7 | + |
| 8 | +export const g = makeTestGroup(AllFeaturesMaxLimitsGPUTest); |
| 9 | + |
| 10 | +g.test('buffer_binding_resource') |
| 11 | + .desc( |
| 12 | + `Validate the correctness of the buffer binding resource by filling the buffer with |
| 13 | + testable data, clearing buffer in shader, and verifying the content of the whole buffer: |
| 14 | + - covers the whole buffer |
| 15 | + - covers the beginning of the buffer |
| 16 | + - covers the end of the buffer |
| 17 | + - covers neither the beginning nor the end of the buffer` |
| 18 | + ) |
| 19 | + .paramsSubcasesOnly(u => |
| 20 | + u // |
| 21 | + .combine('bindBufferResource', [false, true] as const) |
| 22 | + .combine('offset', [0, 256, undefined]) |
| 23 | + .combine('size', [4, 8, undefined]) |
| 24 | + .combine('extraBufferSize', [0, 8]) |
| 25 | + // offset and size don't matter if bindBufferResource is true |
| 26 | + .filter(p => !p.bindBufferResource || (p.offset === undefined && p.size === undefined)) |
| 27 | + ) |
| 28 | + .fn(t => { |
| 29 | + const { bindBufferResource, offset, size, extraBufferSize } = t.params; |
| 30 | + |
| 31 | + const bufferSize = (offset ?? 0) + (size ?? 16) + extraBufferSize; |
| 32 | + const bufferData = new Uint8Array(bufferSize); |
| 33 | + for (let i = 0; i < bufferSize; ++i) { |
| 34 | + bufferData[i] = i + 1; |
| 35 | + } |
| 36 | + |
| 37 | + const buffer = t.makeBufferWithContents( |
| 38 | + bufferData, |
| 39 | + GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC | GPUBufferUsage.STORAGE |
| 40 | + ); |
| 41 | + |
| 42 | + const pipeline = t.device.createComputePipeline({ |
| 43 | + layout: 'auto', |
| 44 | + compute: { |
| 45 | + module: t.device.createShaderModule({ |
| 46 | + code: ` |
| 47 | + @group(0) @binding(0) var<storage, read_write> buffer : array<u32>; |
| 48 | +
|
| 49 | + @compute @workgroup_size(1) fn main() { |
| 50 | + for (var i = 0u; i < arrayLength(&buffer); i = i + 1u) { |
| 51 | + buffer[i] = 0; |
| 52 | + } |
| 53 | + return; |
| 54 | + }`, |
| 55 | + }), |
| 56 | + }, |
| 57 | + }); |
| 58 | + |
| 59 | + const resource = bindBufferResource ? buffer : { buffer, offset, size }; |
| 60 | + const bg = t.device.createBindGroup({ |
| 61 | + entries: [{ binding: 0, resource }], |
| 62 | + layout: pipeline.getBindGroupLayout(0), |
| 63 | + }); |
| 64 | + |
| 65 | + const encoder = t.device.createCommandEncoder(); |
| 66 | + const pass = encoder.beginComputePass(); |
| 67 | + pass.setPipeline(pipeline); |
| 68 | + pass.setBindGroup(0, bg); |
| 69 | + pass.dispatchWorkgroups(1); |
| 70 | + pass.end(); |
| 71 | + t.device.queue.submit([encoder.finish()]); |
| 72 | + |
| 73 | + const expectOffset = bindBufferResource ? 0 : offset ?? 0; |
| 74 | + const expectSize = bindBufferResource ? bufferSize : size ?? bufferSize - expectOffset; |
| 75 | + |
| 76 | + for (let i = 0; i < expectSize; ++i) { |
| 77 | + bufferData[expectOffset + i] = 0; |
| 78 | + } |
| 79 | + |
| 80 | + t.expectGPUBufferValuesEqual(buffer, bufferData); |
| 81 | + }); |
0 commit comments