Diff
Modified: trunk/LayoutTests/ChangeLog (246874 => 246875)
--- trunk/LayoutTests/ChangeLog 2019-06-27 08:14:30 UTC (rev 246874)
+++ trunk/LayoutTests/ChangeLog 2019-06-27 08:19:54 UTC (rev 246875)
@@ -1,3 +1,19 @@
+2019-06-27 Saam Barati <[email protected]>
+
+ [WHLSL] Implement arrays and MakeArrayReference
+ https://bugs.webkit.org/show_bug.cgi?id=198414
+
+ Reviewed by Myles C. Maxfield.
+
+ * webgpu/whlsl-huge-array-expected.txt: Added.
+ * webgpu/whlsl-huge-array.html: Added.
+ * webgpu/whlsl-make-array-reference-expected.txt: Added.
+ * webgpu/whlsl-make-array-reference.html: Added.
+ * webgpu/whlsl-simple-arrays-expected.txt: Added.
+ * webgpu/whlsl-simple-arrays.html: Added.
+ * webgpu/whlsl-two-dimensional-array-expected.txt: Added.
+ * webgpu/whlsl-two-dimensional-array.html: Added.
+
2019-06-26 Simon Fraser <[email protected]>
[Async overflow scrolling] Fix missing or misplaced content inside overflow:scroll
Added: trunk/LayoutTests/webgpu/whlsl-huge-array-expected.txt (0 => 246875)
--- trunk/LayoutTests/webgpu/whlsl-huge-array-expected.txt (rev 0)
+++ trunk/LayoutTests/webgpu/whlsl-huge-array-expected.txt 2019-06-27 08:19:54 UTC (rev 246875)
@@ -0,0 +1,5 @@
+PASS
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/webgpu/whlsl-huge-array.html (0 => 246875)
--- trunk/LayoutTests/webgpu/whlsl-huge-array.html (rev 0)
+++ trunk/LayoutTests/webgpu/whlsl-huge-array.html 2019-06-27 08:19:54 UTC (rev 246875)
@@ -0,0 +1,115 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+<script>
+const shaderSource = `
+void fill(thread float[] array, float value) {
+ for (uint i = 0; i < array.length; i++) {
+ array[i] = value;
+ }
+}
+
+[numthreads(1, 1, 1)]
+compute void computeShader(device int[] buffer : register(u0), float3 threadID : SV_DispatchThreadID) {
+ float[1000] array;
+ if (array.length != 1000)
+ return;
+ for (uint i = 0; i < array.length; ++i) {
+ if (array[i] != 0)
+ return;
+ }
+
+ array[0] = 0.1337;
+ if (array[0] != 0.1337)
+ return;
+
+ thread float[] arrayPtr = @array;
+ if (arrayPtr.length != 1000)
+ return;
+
+ fill(arrayPtr, 0.1010);
+ for (uint i = 0; i < arrayPtr.length; ++i) {
+ if (arrayPtr[i] != 0.1010)
+ return;
+ if (array[i] != 0.1010)
+ return;
+ }
+
+ fill(@array, 0.0101);
+ for (uint i = 0; i < array.length; ++i) {
+ if (arrayPtr[i] != 0.0101)
+ return;
+ if (array[i] != 0.0101)
+ return;
+ }
+
+ buffer[0] = 1;
+}
+`;
+async function start(device) {
+ 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 = Int32Array.BYTES_PER_ELEMENT * 1;
+
+ const bufferDescriptor = {size, usage: GPUBufferUsage.MAP_WRITE | GPUBufferUsage.TRANSFER_SRC};
+ const buffer = device.createBuffer(bufferDescriptor);
+ const bufferArrayBuffer = await buffer.mapWriteAsync();
+ const bufferFloat32Array = new Int32Array(bufferArrayBuffer);
+ bufferFloat32Array[0] = 0;
+ 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(1, 1, 1);
+ computePassEncoder.endPass();
+ const commandBuffer = commandEncoder.finish();
+ device.getQueue().submit([commandBuffer]);
+
+ const resultsArrayBuffer = await resultsBuffer.mapReadAsync();
+ let resultsInt32Array = new Int32Array(resultsArrayBuffer);
+ if (resultsInt32Array[0] === 1)
+ testPassed("");
+ else
+ testFailed("");
+ resultsBuffer.unmap();
+}
+window.jsTestIsAsync = true;
+getBasicDevice().then(function(device) {
+ start(device).then(function() {
+ finishJSTest();
+ }, function() {
+ testFailed("");
+ finishJSTest();
+ });
+}, function() {
+ testPassed("");
+ finishJSTest();
+});
+</script>
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/webgpu/whlsl-make-array-reference-expected.txt (0 => 246875)
--- trunk/LayoutTests/webgpu/whlsl-make-array-reference-expected.txt (rev 0)
+++ trunk/LayoutTests/webgpu/whlsl-make-array-reference-expected.txt 2019-06-27 08:19:54 UTC (rev 246875)
@@ -0,0 +1,5 @@
+PASS
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/webgpu/whlsl-make-array-reference.html (0 => 246875)
--- trunk/LayoutTests/webgpu/whlsl-make-array-reference.html (rev 0)
+++ trunk/LayoutTests/webgpu/whlsl-make-array-reference.html 2019-06-27 08:19:54 UTC (rev 246875)
@@ -0,0 +1,184 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+<script>
+const shaderSource = `
+bool test1() {
+ int value = 42;
+ thread int[] array = @value;
+ if (array.length != 1)
+ return false;
+ if (array[0] != 42)
+ return false;
+ if (array[120213] != 0)
+ return false;
+
+ array[0] = 1337;
+ if (value != 1337)
+ return false;
+
+ return true;
+}
+
+bool test2() {
+ int value = 42;
+ thread int* ptr = &value;
+ if (*ptr != 42)
+ return false;
+
+ thread int[] array = @ptr;
+ if (array.length != 1)
+ return false;
+ if (array[0] != 42)
+ return false;
+ if (array[12374217] != 0)
+ return false;
+
+ *ptr = 666;
+ if (*ptr != 666)
+ return false;
+ if (value != 666)
+ return false;
+ if (array.length != 1)
+ return false;
+ if (array[0] != 666)
+ return false;
+
+ array[0] = 4242;
+ if (*ptr != 4242)
+ return false;
+ if (value != 4242)
+ return false;
+ if (array[0] != 4242)
+ return false;
+ if (array.length != 1)
+ return false;
+
+ return true;
+}
+
+bool test3() {
+ int[42] x;
+ thread int[42]* arrayPtr = &x;
+ if (arrayPtr->length != 42)
+ return false;
+
+ x[41] = 666;
+ if ((*arrayPtr)[41] != 666)
+ return false;
+ if ((*arrayPtr)[0] != 0)
+ return false;
+
+ thread int[] array = @x;
+ if (array.length != 42)
+ return false;
+
+ array[0] = 1337;
+ if (x[0] != 1337)
+ return false;
+ if ((*arrayPtr)[0] != 1337)
+ return false;
+
+ return true;
+}
+
+bool test4() {
+ thread int* ptr = null;
+
+ thread int[] array = @ptr;
+ if (array.length != 0)
+ return false;
+
+ if (array[0] != 0)
+ return false;
+
+ if (array[100000] != 0)
+ return false;
+
+ return true;
+}
+
+[numthreads(1, 1, 1)]
+compute void computeShader(device int[] buffer : register(u0), float3 threadID : SV_DispatchThreadID) {
+ if (!test1())
+ return;
+
+ if (!test2())
+ return;
+
+ if (!test3())
+ return;
+
+ if (!test4())
+ return;
+
+ buffer[0] = 1;
+}
+`;
+async function start(device) {
+ 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 = Int32Array.BYTES_PER_ELEMENT * 1;
+
+ const bufferDescriptor = {size, usage: GPUBufferUsage.MAP_WRITE | GPUBufferUsage.TRANSFER_SRC};
+ const buffer = device.createBuffer(bufferDescriptor);
+ const bufferArrayBuffer = await buffer.mapWriteAsync();
+ const bufferFloat32Array = new Int32Array(bufferArrayBuffer);
+ bufferFloat32Array[0] = 0;
+ 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(1, 1, 1);
+ computePassEncoder.endPass();
+ const commandBuffer = commandEncoder.finish();
+ device.getQueue().submit([commandBuffer]);
+
+ const resultsArrayBuffer = await resultsBuffer.mapReadAsync();
+ let resultsInt32Array = new Int32Array(resultsArrayBuffer);
+ if (resultsInt32Array[0] === 1)
+ testPassed("");
+ else
+ testFailed("");
+ resultsBuffer.unmap();
+}
+window.jsTestIsAsync = true;
+getBasicDevice().then(function(device) {
+ start(device).then(function() {
+ finishJSTest();
+ }, function() {
+ testFailed("");
+ finishJSTest();
+ });
+}, function() {
+ testPassed("");
+ finishJSTest();
+});
+</script>
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/webgpu/whlsl-simple-arrays-expected.txt (0 => 246875)
--- trunk/LayoutTests/webgpu/whlsl-simple-arrays-expected.txt (rev 0)
+++ trunk/LayoutTests/webgpu/whlsl-simple-arrays-expected.txt 2019-06-27 08:19:54 UTC (rev 246875)
@@ -0,0 +1,5 @@
+PASS
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/webgpu/whlsl-simple-arrays.html (0 => 246875)
--- trunk/LayoutTests/webgpu/whlsl-simple-arrays.html (rev 0)
+++ trunk/LayoutTests/webgpu/whlsl-simple-arrays.html 2019-06-27 08:19:54 UTC (rev 246875)
@@ -0,0 +1,123 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+<script>
+const shaderSource = `
+void fill(thread int[] array, int value) {
+ for (uint i = 0; i < array.length; i++) {
+ array[i] = value;
+ }
+}
+
+[numthreads(1, 1, 1)]
+compute void computeShader(device int[] buffer : register(u0), float3 threadID : SV_DispatchThreadID) {
+ int[42] array;
+ if (array.length != 42)
+ return;
+ for (uint i = 0; i < array.length; ++i) {
+ if (array[i] != 0)
+ return;
+ }
+
+ array[0] = 517;
+ if (array[0] != 517)
+ return;
+
+ thread int[] arrayPtr = @array;
+ if (arrayPtr.length != 42)
+ return;
+
+ int[42] array2;
+ array2 = array;
+ if (array2.length != 42)
+ return;
+ if (array2[0] != 517)
+ return;
+
+ fill(arrayPtr, 1337);
+ for (uint i = 0; i < arrayPtr.length; ++i) {
+ if (arrayPtr[i] != 1337)
+ return;
+ if (array[i] != 1337)
+ return;
+ }
+
+ if (array2[0] != 517)
+ return;
+ if (array2.length != 42)
+ return;
+ for (uint i = 1; i < array2.length; ++i) {
+ if (array2[i] != 0)
+ return;
+ }
+
+ buffer[0] = 1;
+}
+`;
+async function start(device) {
+ 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 = Int32Array.BYTES_PER_ELEMENT * 1;
+
+ const bufferDescriptor = {size, usage: GPUBufferUsage.MAP_WRITE | GPUBufferUsage.TRANSFER_SRC};
+ const buffer = device.createBuffer(bufferDescriptor);
+ const bufferArrayBuffer = await buffer.mapWriteAsync();
+ const bufferFloat32Array = new Int32Array(bufferArrayBuffer);
+ bufferFloat32Array[0] = 0;
+ 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(1, 1, 1);
+ computePassEncoder.endPass();
+ const commandBuffer = commandEncoder.finish();
+ device.getQueue().submit([commandBuffer]);
+
+ const resultsArrayBuffer = await resultsBuffer.mapReadAsync();
+ let resultsInt32Array = new Int32Array(resultsArrayBuffer);
+ if (resultsInt32Array[0] === 1)
+ testPassed("");
+ else
+ testFailed("");
+ resultsBuffer.unmap();
+}
+window.jsTestIsAsync = true;
+getBasicDevice().then(function(device) {
+ start(device).then(function() {
+ finishJSTest();
+ }, function() {
+ testFailed("");
+ finishJSTest();
+ });
+}, function() {
+ testPassed("");
+ finishJSTest();
+});
+</script>
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/webgpu/whlsl-two-dimensional-array-expected.txt (0 => 246875)
--- trunk/LayoutTests/webgpu/whlsl-two-dimensional-array-expected.txt (rev 0)
+++ trunk/LayoutTests/webgpu/whlsl-two-dimensional-array-expected.txt 2019-06-27 08:19:54 UTC (rev 246875)
@@ -0,0 +1,5 @@
+PASS
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/webgpu/whlsl-two-dimensional-array.html (0 => 246875)
--- trunk/LayoutTests/webgpu/whlsl-two-dimensional-array.html (rev 0)
+++ trunk/LayoutTests/webgpu/whlsl-two-dimensional-array.html 2019-06-27 08:19:54 UTC (rev 246875)
@@ -0,0 +1,125 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script src=""
+</head>
+<body>
+<script>
+const shaderSource = `
+void fill(thread float[10][] array, float[10] value) {
+ for (uint i = 0; i < array.length; i++) {
+ array[i] = value;
+ }
+}
+
+void fill(thread float[] array, float value) {
+ for (uint i = 0; i < array.length; i++) {
+ array[i] = value;
+ }
+}
+
+bool contains(thread float[10][] array, float value) {
+ for (uint i = 0; i < array.length; i++) {
+ for (uint j = 0; j < array[j].length; j++) {
+ if (array[i][j] != value)
+ return false;
+ }
+ }
+ return true;
+}
+
+bool contains(thread float[] array, float value) {
+ for (uint i = 0; i < array.length; i++) {
+ if (array[i] != value)
+ return false;
+ }
+ return true;
+}
+
+[numthreads(1, 1, 1)]
+compute void computeShader(device int[] buffer : register(u0), float3 threadID : SV_DispatchThreadID) {
+ float[10][5] array;
+ if (array.length != 5)
+ return;
+ if (!contains(@array, 0))
+ return;
+
+ for (uint i = 0; i < array.length; ++i) {
+ float[10] value;
+ fill(@value, float(i));
+ array[i] = value;
+ }
+
+ for (uint i = 0; i < array.length; ++i) {
+ float[10] value = array[i];
+ if (!contains(@value, float(i)))
+ return;
+ }
+
+ buffer[0] = 1;
+}
+`;
+async function start(device) {
+ 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 = Int32Array.BYTES_PER_ELEMENT * 1;
+
+ const bufferDescriptor = {size, usage: GPUBufferUsage.MAP_WRITE | GPUBufferUsage.TRANSFER_SRC};
+ const buffer = device.createBuffer(bufferDescriptor);
+ const bufferArrayBuffer = await buffer.mapWriteAsync();
+ const bufferFloat32Array = new Int32Array(bufferArrayBuffer);
+ bufferFloat32Array[0] = 0;
+ 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(1, 1, 1);
+ computePassEncoder.endPass();
+ const commandBuffer = commandEncoder.finish();
+ device.getQueue().submit([commandBuffer]);
+
+ const resultsArrayBuffer = await resultsBuffer.mapReadAsync();
+ let resultsInt32Array = new Int32Array(resultsArrayBuffer);
+ if (resultsInt32Array[0] === 1)
+ testPassed("");
+ else
+ testFailed("");
+ resultsBuffer.unmap();
+}
+window.jsTestIsAsync = true;
+getBasicDevice().then(function(device) {
+ start(device).then(function() {
+ finishJSTest();
+ }, function() {
+ testFailed("");
+ finishJSTest();
+ });
+}, function() {
+ testPassed("");
+ finishJSTest();
+});
+</script>
+<script src=""
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (246874 => 246875)
--- trunk/Source/WebCore/ChangeLog 2019-06-27 08:14:30 UTC (rev 246874)
+++ trunk/Source/WebCore/ChangeLog 2019-06-27 08:19:54 UTC (rev 246875)
@@ -1,3 +1,53 @@
+2019-06-27 Saam Barati <[email protected]>
+
+ [WHLSL] Implement arrays and MakeArrayReference
+ https://bugs.webkit.org/show_bug.cgi?id=198414
+
+ Reviewed by Myles C. Maxfield.
+
+ This patch implements WHLSL arrays. The main implementation detail is that
+ arrays get compiled to use Metal's array type. To make everything work, this
+ patch also fixes a few bugs:
+ - The checker now allows "operator.length" to be called on arrays. Prior to
+ this patch, it was just allowed on array references.
+
+ - The preserve variable lifetimes pass now looks at MakeArrayReference nodes.
+ Prior to this patch, it just looked at MakePointerExpression.
+
+ - We were producing the wrong type for ander arguments for indexed accesses
+ on array types. We were saying the argument that was produced was a reference
+ to an array instead of an array reference to the element type.
+
+ - The trie we compose for the reverse type hierarchy was inserting elements
+ into the wrong "children" vector. We were always inserting things into the
+ top level vector. This is wrong when we have a nesting of types > 1.
+
+ I also found a bug with having arrays of pointers when writing this patch.
+ Work on this will take place in a follow up: https://bugs.webkit.org/show_bug.cgi?id=199197
+
+ Tests: webgpu/whlsl-huge-array.html
+ webgpu/whlsl-make-array-reference.html
+ webgpu/whlsl-simple-arrays.html
+ webgpu/whlsl-two-dimensional-array.html
+
+ * Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp:
+ (WebCore::WHLSL::Metal::FunctionDefinitionWriter::visit):
+ * Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp:
+ (WebCore::WHLSL::Metal::writeNativeFunction):
+ * Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp:
+ (WebCore::WHLSL::Metal::TypeNamer::insert):
+ (WebCore::WHLSL::Metal::TypeNamer::emitUnnamedTypeDefinition):
+ * Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.h:
+ * Modules/webgpu/WHLSL/WHLSLChecker.cpp:
+ (WebCore::WHLSL::resolveByInstantiation):
+ (WebCore::WHLSL::Checker::visit):
+ * Modules/webgpu/WHLSL/WHLSLPreserveVariableLifetimes.cpp:
+ (WebCore::WHLSL::EscapedVariableCollector::escapeVariableUse):
+ * Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp:
+ (WebCore::WHLSL::wrapAnderCallArgument):
+ (WebCore::WHLSL::anderCallArgument):
+ * Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt:
+
2019-06-27 Fujii Hironori <[email protected]>
[CMake] Bump cmake_minimum_required version to 3.10
Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp (246874 => 246875)
--- trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp 2019-06-27 08:14:30 UTC (rev 246874)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp 2019-06-27 08:19:54 UTC (rev 246875)
@@ -628,16 +628,22 @@
checkErrorAndVisit(makeArrayReferenceExpression.leftValue());
// FIXME: This needs to be made to work. It probably should be using the last leftValue too.
// https://bugs.webkit.org/show_bug.cgi?id=198838
- auto lValue = takeLastValue();
auto variableName = generateNextVariableName();
+
auto mangledTypeName = m_typeNamer.mangledNameForType(makeArrayReferenceExpression.resolvedType());
- if (is<AST::PointerType>(makeArrayReferenceExpression.resolvedType()))
+ if (is<AST::PointerType>(makeArrayReferenceExpression.leftValue().resolvedType())) {
+ auto ptrValue = takeLastValue();
+ m_stringBuilder.append(makeString(mangledTypeName, ' ', variableName, ";\n"));
+ m_stringBuilder.append(makeString("if (", ptrValue, ") ", variableName, " = { ", ptrValue, ", 1};\n"));
+ m_stringBuilder.append(makeString("else ", variableName, " = { nullptr, 0 };\n"));
+ } else if (is<AST::ArrayType>(makeArrayReferenceExpression.leftValue().resolvedType())) {
+ auto lValue = takeLastLeftValue();
+ auto& arrayType = downcast<AST::ArrayType>(makeArrayReferenceExpression.leftValue().resolvedType());
+ m_stringBuilder.append(makeString(mangledTypeName, ' ', variableName, " = { ", lValue, "->data(), ", arrayType.numElements(), " };\n"));
+ } else {
+ auto lValue = takeLastLeftValue();
m_stringBuilder.append(makeString(mangledTypeName, ' ', variableName, " = { ", lValue, ", 1 };\n"));
- else if (is<AST::ArrayType>(makeArrayReferenceExpression.resolvedType())) {
- auto& arrayType = downcast<AST::ArrayType>(makeArrayReferenceExpression.resolvedType());
- m_stringBuilder.append(makeString(mangledTypeName, ' ', variableName, " = { &(", lValue, "[0]), ", arrayType.numElements(), " };\n"));
- } else
- m_stringBuilder.append(makeString(mangledTypeName, ' ', variableName, " = { &", lValue, ", 1 };\n"));
+ }
appendRightValue(makeArrayReferenceExpression, variableName);
}
Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp (246874 => 246875)
--- trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp 2019-06-27 08:14:30 UTC (rev 246874)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp 2019-06-27 08:19:54 UTC (rev 246875)
@@ -174,8 +174,8 @@
auto& unnamedParameterType = downcast<AST::UnnamedType>(parameterType);
if (is<AST::ArrayType>(unnamedParameterType)) {
auto& arrayParameterType = downcast<AST::ArrayType>(unnamedParameterType);
- stringBuilder.append(makeString("uint ", outputFunctionName, '(', metalParameterName, " v) {\n"));
- stringBuilder.append(makeString(" return ", arrayParameterType.numElements(), "u;\n"));
+ stringBuilder.append(makeString("uint ", outputFunctionName, '(', metalParameterName, ") {\n"));
+ stringBuilder.append(makeString(" return ", arrayParameterType.numElements(), ";\n"));
stringBuilder.append("}\n");
return stringBuilder.toString();
}
@@ -257,6 +257,7 @@
auto metalParameter2Name = typeNamer.mangledNameForType(*nativeFunctionDeclaration.parameters()[1]->type());
auto metalReturnName = typeNamer.mangledNameForType(nativeFunctionDeclaration.type());
stringBuilder.append(makeString(metalReturnName, ' ', outputFunctionName, '(', metalParameter1Name, " v, ", metalParameter2Name, " n) {\n"));
+ ASSERT(is<AST::ArrayReferenceType>(*nativeFunctionDeclaration.parameters()[0]->type()));
stringBuilder.append(" if (n < v.length) return &(v.pointer[n]);\n");
stringBuilder.append(" return nullptr;\n");
stringBuilder.append("}\n");
Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp (246874 => 246875)
--- trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp 2019-06-27 08:14:30 UTC (rev 246874)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.cpp 2019-06-27 08:19:54 UTC (rev 246875)
@@ -309,7 +309,7 @@
return makeUniqueRef<ArrayTypeNameNode>(parent, generateNextTypeName(), arrayType.numElements());
}
-size_t TypeNamer::insert(AST::UnnamedType& unnamedType, Vector<UniqueRef<BaseTypeNameNode>>& types)
+BaseTypeNameNode* TypeNamer::insert(AST::UnnamedType& unnamedType, Vector<UniqueRef<BaseTypeNameNode>>& types)
{
Vector<UniqueRef<BaseTypeNameNode>>* vectorToInsertInto { nullptr };
BaseTypeNameNode* parent { nullptr };
@@ -317,17 +317,14 @@
vectorToInsertInto = &types;
parent = nullptr;
} else if (is<AST::PointerType>(unnamedType)) {
- auto& item = types[insert(downcast<AST::PointerType>(unnamedType).elementType(), types)];
- vectorToInsertInto = &item->children();
- parent = &item;
+ parent = insert(downcast<AST::PointerType>(unnamedType).elementType(), types);
+ vectorToInsertInto = &parent->children();
} else if (is<AST::ArrayReferenceType>(unnamedType)) {
- auto& item = types[insert(downcast<AST::ArrayReferenceType>(unnamedType).elementType(), types)];
- vectorToInsertInto = &item->children();
- parent = &item;
+ parent = insert(downcast<AST::ArrayReferenceType>(unnamedType).elementType(), types);
+ vectorToInsertInto = &parent->children();
} else {
- auto& item = types[insert(downcast<AST::ArrayType>(unnamedType).type(), types)];
- vectorToInsertInto = &item->children();
- parent = &item;
+ parent = insert(downcast<AST::ArrayType>(unnamedType).type(), types);
+ vectorToInsertInto = &parent->children();
}
ASSERT(vectorToInsertInto);
@@ -339,11 +336,11 @@
ASSERT_UNUSED(addResult, addResult.isNewEntry);
}
vectorToInsertInto->append(WTFMove(result));
- return vectorToInsertInto->size() - 1;
+ return &vectorToInsertInto->last().get();
}
auto addResult = m_unnamedTypeMapping.add(&unnamedType, &*iterator);
ASSERT_UNUSED(addResult, addResult.isNewEntry);
- return iterator - vectorToInsertInto->begin();
+ return &*iterator;
}
class MetalTypeDeclarationWriter : public Visitor {
@@ -398,7 +395,7 @@
} else {
auto& arrayType = downcast<ArrayTypeNameNode>(baseTypeNameNode);
ASSERT(baseTypeNameNode.parent());
- stringBuilder.append(makeString("typedef Array<", arrayType.parent()->mangledName(), ", ", arrayType.numElements(), "> ", arrayType.mangledName(), ";\n"));
+ stringBuilder.append(makeString("typedef array<", arrayType.parent()->mangledName(), ", ", arrayType.numElements(), "> ", arrayType.mangledName(), ";\n"));
}
emittedUnnamedTypes.add(&baseTypeNameNode);
}
Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.h (246874 => 246875)
--- trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.h 2019-06-27 08:14:30 UTC (rev 246874)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLTypeNamer.h 2019-06-27 08:19:54 UTC (rev 246875)
@@ -100,7 +100,7 @@
String metalTypeDefinitions();
UniqueRef<BaseTypeNameNode> createNameNode(AST::UnnamedType&, BaseTypeNameNode* parent);
- size_t insert(AST::UnnamedType&, Vector<UniqueRef<BaseTypeNameNode>>&);
+ BaseTypeNameNode* insert(AST::UnnamedType&, Vector<UniqueRef<BaseTypeNameNode>>&);
Program& m_program;
Vector<UniqueRef<BaseTypeNameNode>> m_trie;
Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp (246874 => 246875)
--- trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp 2019-06-27 08:14:30 UTC (rev 246874)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp 2019-06-27 08:19:54 UTC (rev 246875)
@@ -183,7 +183,7 @@
return resolveWithOperatorAnderIndexer(origin, *firstArgumentArrayRef, intrinsics);
} else if (name == "operator.length" && types.size() == 1) {
auto* firstArgumentReference = types[0].get().visit(WTF::makeVisitor([](UniqueRef<AST::UnnamedType>& unnamedType) -> AST::UnnamedType* {
- if (is<AST::ArrayReferenceType>(static_cast<AST::UnnamedType&>(unnamedType)))
+ if (is<AST::ArrayReferenceType>(static_cast<AST::UnnamedType&>(unnamedType)) || is<AST::ArrayType>(static_cast<AST::UnnamedType&>(unnamedType)))
return &unnamedType;
return nullptr;
}, [](RefPtr<ResolvableTypeReference>&) -> AST::UnnamedType* {
@@ -1132,9 +1132,7 @@
ASSERT(variableReference.variable());
ASSERT(variableReference.variable()->type());
- AST::TypeAnnotation typeAnnotation = AST::RightValue();
- typeAnnotation = AST::LeftValue { AST::AddressSpace::Thread };
- assignType(variableReference, variableReference.variable()->type()->clone(), WTFMove(typeAnnotation));
+ assignType(variableReference, variableReference.variable()->type()->clone(), AST::LeftValue { AST::AddressSpace::Thread });
}
void Checker::visit(AST::Return& returnStatement)
Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPreserveVariableLifetimes.cpp (246874 => 246875)
--- trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPreserveVariableLifetimes.cpp 2019-06-27 08:14:30 UTC (rev 246874)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPreserveVariableLifetimes.cpp 2019-06-27 08:19:54 UTC (rev 246875)
@@ -55,17 +55,17 @@
class EscapedVariableCollector : public Visitor {
using Base = Visitor;
public:
- void visit(AST::MakePointerExpression& makePointerExpression) override
+
+ void escapeVariableUse(AST::_expression_& _expression_)
{
- if (!is<AST::VariableReference>(makePointerExpression.leftValue())) {
+ if (!is<AST::VariableReference>(_expression_)) {
// FIXME: Are we missing any interesting productions here?
// https://bugs.webkit.org/show_bug.cgi?id=198311
- Base::visit(makePointerExpression.leftValue());
+ Base::visit(_expression_);
return;
}
- auto& variableReference = downcast<AST::VariableReference>(makePointerExpression.leftValue());
- auto* variable = variableReference.variable();
+ auto* variable = downcast<AST::VariableReference>(_expression_).variable();
ASSERT(variable);
// FIXME: We could skip this if we mark all internal variables with a bit, since we
// never make any internal variable escape the current scope it is defined in:
@@ -73,6 +73,16 @@
m_escapedVariables.add(variable, makeString("_", variable->name(), "_", m_count++));
}
+ void visit(AST::MakePointerExpression& makePointerExpression) override
+ {
+ escapeVariableUse(makePointerExpression.leftValue());
+ }
+
+ void visit(AST::MakeArrayReferenceExpression& makeArrayReferenceExpression) override
+ {
+ escapeVariableUse(makeArrayReferenceExpression.leftValue());
+ }
+
HashMap<AST::VariableDeclaration*, String> takeEscapedVariables() { return WTFMove(m_escapedVariables); }
private:
Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp (246874 => 246875)
--- trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp 2019-06-27 08:14:30 UTC (rev 246874)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp 2019-06-27 08:19:54 UTC (rev 246875)
@@ -95,13 +95,12 @@
};
template <typename ExpressionConstructor, typename TypeConstructor>
-static Optional<AnderCallArgumentResult> wrapAnderCallArgument(UniqueRef<AST::_expression_>& _expression_, bool anderFunction, bool threadAnderFunction)
+static Optional<AnderCallArgumentResult> wrapAnderCallArgument(UniqueRef<AST::_expression_>& _expression_, UniqueRef<AST::UnnamedType> baseType, bool anderFunction, bool threadAnderFunction)
{
if (auto addressSpace = _expression_->typeAnnotation().leftAddressSpace()) {
if (!anderFunction)
return WTF::nullopt;
auto origin = _expression_->origin();
- auto baseType = _expression_->resolvedType().clone();
auto makeArrayReference = makeUniqueRef<ExpressionConstructor>(Lexer::Token(origin), WTFMove(_expression_));
makeArrayReference->setType(makeUniqueRef<TypeConstructor>(WTFMove(origin), *addressSpace, WTFMove(baseType)));
makeArrayReference->setTypeAnnotation(AST::RightValue());
@@ -109,7 +108,6 @@
}
if (threadAnderFunction) {
auto origin = _expression_->origin();
- auto baseType = _expression_->resolvedType().clone();
auto variableDeclaration = makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(origin), AST::Qualifiers(), baseType->clone(), String(), WTF::nullopt, WTF::nullopt);
auto variableReference1 = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(variableDeclaration));
@@ -151,9 +149,9 @@
if (is<AST::ArrayReferenceType>(unnamedType))
return {{ WTFMove(_expression_), WTF::nullopt, WhichAnder::Ander }};
if (is<AST::ArrayType>(unnamedType))
- return wrapAnderCallArgument<AST::MakeArrayReferenceExpression, AST::ArrayReferenceType>(_expression_, anderFunction, threadAnderFunction);
+ return wrapAnderCallArgument<AST::MakeArrayReferenceExpression, AST::ArrayReferenceType>(_expression_, downcast<AST::ArrayType>(unnamedType).type().clone(), anderFunction, threadAnderFunction);
}
- return wrapAnderCallArgument<AST::MakePointerExpression, AST::PointerType>(_expression_, anderFunction, threadAnderFunction);
+ return wrapAnderCallArgument<AST::MakePointerExpression, AST::PointerType>(_expression_, _expression_->resolvedType().clone(), anderFunction, threadAnderFunction);
}
static Optional<UniqueRef<AST::_expression_>> setterCall(AST::PropertyAccessExpression& propertyAccessExpression, AST::FunctionDeclaration* relevantAnder, UniqueRef<AST::_expression_>&& newValue, const std::function<UniqueRef<AST::_expression_>()>& leftValueFactory, AST::VariableDeclaration* indexVariable)
Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt (246874 => 246875)
--- trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt 2019-06-27 08:14:30 UTC (rev 246874)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLStandardLibrary.txt 2019-06-27 08:19:54 UTC (rev 246875)
@@ -792,6 +792,12 @@
int operator--(int value) {
return value - 1;
}
+uint operator++(uint value) {
+ return value + 1;
+}
+uint operator--(uint value) {
+ return value - 1;
+}
native ushort Sample(Texture1D<ushort>, sampler, float location);
native ushort Sample(Texture1DArray<ushort>, sampler, float2 location);