| export const description = ` |
| Buffer tests in createBindGroup. |
| `; |
| |
| import { makeTestGroup } from '../../../../common/framework/test_group.js'; |
| import { AllFeaturesMaxLimitsGPUTest } from '../../../gpu_test.js'; |
| |
| export const g = makeTestGroup(AllFeaturesMaxLimitsGPUTest); |
| |
| g.test('buffer_binding_resource') |
| .desc( |
| `Validate the correctness of the buffer binding resource by filling the buffer with |
| testable data, clearing buffer in shader, and verifying the content of the whole buffer: |
| - covers the whole buffer |
| - covers the beginning of the buffer |
| - covers the end of the buffer |
| - covers neither the beginning nor the end of the buffer` |
| ) |
| .paramsSubcasesOnly(u => |
| u // |
| .combine('bindBufferResource', [false, true] as const) |
| .combine('offset', [0, 256, undefined]) |
| .combine('size', [4, 8, undefined]) |
| .combine('extraBufferSize', [0, 8]) |
| // offset and size don't matter if bindBufferResource is true |
| .filter(p => !p.bindBufferResource || (p.offset === undefined && p.size === undefined)) |
| ) |
| .fn(t => { |
| const { bindBufferResource, offset, size, extraBufferSize } = t.params; |
| |
| const bufferSize = (offset ?? 0) + (size ?? 16) + extraBufferSize; |
| const bufferData = new Uint8Array(bufferSize); |
| for (let i = 0; i < bufferSize; ++i) { |
| bufferData[i] = i + 1; |
| } |
| |
| const buffer = t.makeBufferWithContents( |
| bufferData, |
| GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC | GPUBufferUsage.STORAGE |
| ); |
| |
| const pipeline = t.device.createComputePipeline({ |
| layout: 'auto', |
| compute: { |
| module: t.device.createShaderModule({ |
| code: ` |
| @group(0) @binding(0) var<storage, read_write> buffer : array<u32>; |
| |
| @compute @workgroup_size(1) fn main() { |
| for (var i = 0u; i < arrayLength(&buffer); i = i + 1u) { |
| buffer[i] = 0; |
| } |
| return; |
| }`, |
| }), |
| }, |
| }); |
| |
| const resource = bindBufferResource ? buffer : { buffer, offset, size }; |
| const bg = t.device.createBindGroup({ |
| entries: [{ binding: 0, resource }], |
| layout: pipeline.getBindGroupLayout(0), |
| }); |
| |
| const encoder = t.device.createCommandEncoder(); |
| const pass = encoder.beginComputePass(); |
| pass.setPipeline(pipeline); |
| pass.setBindGroup(0, bg); |
| pass.dispatchWorkgroups(1); |
| pass.end(); |
| t.device.queue.submit([encoder.finish()]); |
| |
| const expectOffset = bindBufferResource ? 0 : offset ?? 0; |
| const expectSize = bindBufferResource ? bufferSize : size ?? bufferSize - expectOffset; |
| |
| for (let i = 0; i < expectSize; ++i) { |
| bufferData[expectOffset + i] = 0; |
| } |
| |
| t.expectGPUBufferValuesEqual(buffer, bufferData); |
| }); |