blob: 130ac6659c3624a57c80f8ef49dbe5f8bf0ddd9a [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<script src="../resources/js-test-pre.js"></script>
</head>
<body>
<script>
const shaderSource = `
bool allEqual(float2x3 mat, float value)
{
for (uint i = 0; i < 2; i = i + 1) {
for (uint j = 0; j < 3; j = j + 1) {
if (mat[i][j] != value)
return false;
}
}
return true;
}
[numthreads(1, 1, 1)]
compute void computeShader(device float[] buffer : register(u0), float3 threadID : SV_DispatchThreadID) {
float2x3 foo;
if (!allEqual(foo, 0))
return;
foo = foo + 1.0;
if (!allEqual(foo, 1))
return;
foo = foo * 8.5;
if (!allEqual(foo, 8.5))
return;
foo = foo - 7.5;
if (!allEqual(foo, 1))
return;
foo = foo + 1.0;
if (!allEqual(foo, 2))
return;
foo = foo + foo;
if (!allEqual(foo, 4))
return;
foo = foo + foo;
if (!allEqual(foo, 8))
return;
float3 fourtyTwo;
fourtyTwo.x = 42;
fourtyTwo.y = 42;
fourtyTwo.z = 42;
foo[0] = fourtyTwo;
foo[1] = fourtyTwo;
if (!allEqual(foo, 42))
return;
foo[1337] = fourtyTwo;
if (!allEqual(foo, 42))
return;
foo[1000000] = fourtyTwo;
if (!allEqual(foo, 42))
return;
fourtyTwo[1337] = 50;
foo[1] = fourtyTwo;
if (!allEqual(foo, 42))
return;
fourtyTwo[1000000] = 50;
foo[1] = fourtyTwo;
if (!allEqual(foo, 42))
return;
float3 shouldBeZero = foo[100000];
if (shouldBeZero.x != 0 || shouldBeZero.y != 0 || shouldBeZero.z != 0)
return;
if (fourtyTwo[10000000] != 0)
return;
buffer[uint(threadID.x)] = buffer[uint(threadID.x)] * 2.0;
}
`;
let resultsFloat32Array;
async function start() {
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const shaderModule = device.createShaderModule({code: shaderSource, isWHLSL: true});
const computeStage = {module: shaderModule, entryPoint: "computeShader"};
const bindGroupLayoutDescriptor = {bindings: [{binding: 0, visibility: 7, type: "storage-buffer"}]};
const bindGroupLayout = device.createBindGroupLayout(bindGroupLayoutDescriptor);
const pipelineLayoutDescriptor = {bindGroupLayouts: [bindGroupLayout]};
const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor);
const computePipelineDescriptor = {computeStage, layout: pipelineLayout};
const computePipeline = device.createComputePipeline(computePipelineDescriptor);
const size = Float32Array.BYTES_PER_ELEMENT * 8;
const bufferDescriptor = {size, usage: GPUBufferUsage.MAP_WRITE | GPUBufferUsage.TRANSFER_SRC};
const buffer = device.createBuffer(bufferDescriptor);
const bufferArrayBuffer = await buffer.mapWriteAsync();
const bufferFloat32Array = new Float32Array(bufferArrayBuffer);
bufferFloat32Array[0] = 1;
bufferFloat32Array[1] = 2;
bufferFloat32Array[2] = 3;
bufferFloat32Array[3] = 4;
bufferFloat32Array[4] = 5;
bufferFloat32Array[5] = 6;
bufferFloat32Array[6] = 7;
bufferFloat32Array[7] = 8;
buffer.unmap();
const resultsBufferDescriptor = {size, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.TRANSFER_DST | GPUBufferUsage.MAP_READ};
const resultsBuffer = device.createBuffer(resultsBufferDescriptor);
const bufferBinding = {buffer: resultsBuffer, size};
const bindGroupBinding = {binding: 0, resource: bufferBinding};
const bindGroupDescriptor = {layout: bindGroupLayout, bindings: [bindGroupBinding]};
const bindGroup = device.createBindGroup(bindGroupDescriptor);
const commandEncoder = device.createCommandEncoder(); // {}
commandEncoder.copyBufferToBuffer(buffer, 0, resultsBuffer, 0, size);
const computePassEncoder = commandEncoder.beginComputePass();
computePassEncoder.setPipeline(computePipeline);
computePassEncoder.setBindGroup(0, bindGroup);
computePassEncoder.dispatch(4, 1, 1);
computePassEncoder.endPass();
const commandBuffer = commandEncoder.finish();
device.getQueue().submit([commandBuffer]);
const resultsArrayBuffer = await resultsBuffer.mapReadAsync();
resultsFloat32Array = new Float32Array(resultsArrayBuffer);
shouldBe("resultsFloat32Array[0]", "2");
shouldBe("resultsFloat32Array[1]", "4");
shouldBe("resultsFloat32Array[2]", "6");
shouldBe("resultsFloat32Array[3]", "8");
shouldBe("resultsFloat32Array[4]", "5");
shouldBe("resultsFloat32Array[5]", "6");
shouldBe("resultsFloat32Array[6]", "7");
shouldBe("resultsFloat32Array[7]", "8");
resultsBuffer.unmap();
}
if (window.testRunner)
testRunner.waitUntilDone();
window.addEventListener("load", function() {
start().then(function() {
if (window.testRunner)
testRunner.notifyDone();
}, function() {
if (window.testRunner)
testRunner.notifyDone();
});
});
</script>
<script src="../resources/js-test-post.js"></script>
</body>
</html>