Diff
Modified: trunk/LayoutTests/ChangeLog (246393 => 246394)
--- trunk/LayoutTests/ChangeLog 2019-06-13 05:10:11 UTC (rev 246393)
+++ trunk/LayoutTests/ChangeLog 2019-06-13 05:38:28 UTC (rev 246394)
@@ -1,3 +1,20 @@
+2019-06-12 Myles C. Maxfield <mmaxfi...@apple.com>
+
+ [WHLSL] Implement array references
+ https://bugs.webkit.org/show_bug.cgi?id=198163
+
+ Reviewed by Saam Barati.
+
+ * webgpu/buffer-resource-triangles-expected.html: Deleted. This test doens't make any sense and triggers
+ Metal to read out-of-bounds of a vertex buffer.
+ * webgpu/buffer-resource-triangles.html: Deleted.
+ * webgpu/whlsl-buffer-fragment-expected.html: Added.
+ * webgpu/whlsl-buffer-fragment.html: Added.
+ * webgpu/whlsl-buffer-vertex-expected.html: Added.
+ * webgpu/whlsl-buffer-vertex.html: Added.
+ * webgpu/whlsl-dont-crash-parsing-enum.html:
+ * webgpu/whlsl.html:
+
2019-06-12 Justin Fan <justin_...@apple.com>
[WebGL] ANGLE Extension directive location incorrectly enforced for webgl 1.0
Deleted: trunk/LayoutTests/webgpu/buffer-resource-triangles-expected.html (246393 => 246394)
--- trunk/LayoutTests/webgpu/buffer-resource-triangles-expected.html 2019-06-13 05:10:11 UTC (rev 246393)
+++ trunk/LayoutTests/webgpu/buffer-resource-triangles-expected.html 2019-06-13 05:38:28 UTC (rev 246394)
@@ -1,12 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<title>HTML Reference File</title>
-<p>Pass if square canvas below is completely green.</p>
-<canvas width="400" height="400"></canvas>
-<script>
-const canvas = document.querySelector("canvas");
-const context = canvas.getContext('2d');
-
-context.fillStyle = 'rgb(0, 255, 0)';
-context.fillRect(0, 0, canvas.width, canvas.height);
-</script>
\ No newline at end of file
Deleted: trunk/LayoutTests/webgpu/buffer-resource-triangles.html (246393 => 246394)
--- trunk/LayoutTests/webgpu/buffer-resource-triangles.html 2019-06-13 05:10:11 UTC (rev 246393)
+++ trunk/LayoutTests/webgpu/buffer-resource-triangles.html 2019-06-13 05:38:28 UTC (rev 246394)
@@ -1,209 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<title>WebGPU Hello Triangles</title>
-<meta name="assert" content="WebGPU correctly renders a green canvas.">
-<link rel="match" href=""
-<p>Pass if square canvas below is completely green.</p>
-<canvas width="400" height="400"></canvas>
-<script src=""
-<script>
-if (window.testRunner)
- testRunner.waitUntilDone();
-
-const shaderCode = `
-#include <metal_stdlib>
-
-using namespace metal;
-
-struct VertexInput {
- float4 position [[attribute(0)]];
-};
-
-struct Vertex {
- float4 position [[position]];
-};
-
-struct VertexArguments {
- device Vertex* v0;
- device Vertex* v1;
- device Vertex* v2;
-};
-
-vertex Vertex vertex_main(
- VertexInput input [[stage_in]],
- const device VertexArguments& args0 [[buffer(0)]],
- const device VertexArguments& args1 [[buffer(1)]],
- uint vid [[vertex_id]])
-{
- switch (vid)
- {
- case 0:
- case 1:
- case 2: {
- Vertex out;
- out.position = input.position;
- return out;
- }
- case 3: return *args0.v0;
- case 4: return *args0.v1;
- case 5: return *args0.v2;
- case 6: return *args1.v0;
- case 7: return *args1.v1;
- default: return *args1.v2;
- }
-}
-
-struct FragmentArguments {
- device float4* color;
-};
-
-fragment float4 fragment_main(const device FragmentArguments& args [[buffer(0)]])
-{
- return args.color[0];
-}
-`
-
-const bindingNums = {
- UL: 0,
- UM: 1,
- UR: 2,
- LL: 3,
- LR: 4,
- G: 5
-};
-
-function createUniformBufferBindGroupLayout(bindNum, stage = GPUShaderStageBit.VERTEX) {
- return {
- binding: bindNum,
- visibility: stage,
- type: "uniform-buffer"
- };
-}
-
-const vertexSize = 4 * 4;
-function createAndUploadVerticesBuffer(device) {
- const vertexArray = new Float32Array([
- 0, 1, 0, 1,
- -1, -1, 0, 1,
- 1, -1, 0, 1
- ]);
- return createBufferWithData(device, { size: vertexArray.byteLength, usage: GPUBufferUsage.VERTEX }, vertexArray.buffer);
-}
-
-function createFloat4Buffer(device, a, b, promises) {
- const buffer = device.createBuffer({ size: vertexSize, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.MAP_WRITE });
-
- const promise = buffer.mapWriteAsync().then(mapping => {
- const mappedArray = new Float32Array(mapping);
- mappedArray.set([a, b, 0, 1]);
- buffer.unmap();
- });
-
- promises.push(promise);
- return buffer;
-}
-
-function createBufferBinding(buffer) {
- return { buffer: buffer, size: vertexSize };
-}
-
-async function test() {
- const device = await getBasicDevice();
- const canvas = document.querySelector("canvas");
- const swapChain = createBasicSwapChain(canvas, device);
- // FIXME: Replace with non-MSL shaders.
- const shaderModule = device.createShaderModule({ code: shaderCode });
-
- // Create vertex data GPUBuffers.
- const verticesBuffer = createAndUploadVerticesBuffer(device);
-
- let bufferPromises = [];
- const upperLeft = createFloat4Buffer(device, -1, 1, bufferPromises);
- const upperMiddle = createFloat4Buffer(device, 0, 1, bufferPromises);
- const upperRight = createFloat4Buffer(device, 1, 1, bufferPromises);
- const lowerLeft = createFloat4Buffer(device, -1, -1, bufferPromises);
- const lowerRight = createFloat4Buffer(device, 1, -1, bufferPromises);
-
- // Color data buffer.
- const green = createFloat4Buffer(device, 0, 1, bufferPromises);
-
- // Create vertex input state.
- const vertexInput = {
- indexFormat: "uint32",
- vertexBuffers: [{
- stride: vertexSize,
- attributeSet: [{
- format: "float4",
- shaderLocation: 0
- }]
- }]
- };
-
- // Create buffer GPUBindGroupLayoutBindings.
- const layoutUL = createUniformBufferBindGroupLayout(bindingNums.UL);
- const layoutUM = createUniformBufferBindGroupLayout(bindingNums.UM);
- const layoutUR = createUniformBufferBindGroupLayout(bindingNums.UR);
- const layoutLL = createUniformBufferBindGroupLayout(bindingNums.LL);
- const layoutLR = createUniformBufferBindGroupLayout(bindingNums.LR);
- const layoutG = createUniformBufferBindGroupLayout(bindingNums.G, GPUShaderStageBit.FRAGMENT);
-
- // GPUBindGroupLayouts
- const leftTriangleBGLayout = device.createBindGroupLayout({ bindings: [layoutUL, layoutUM, layoutLL, layoutG] });
- const rightTriangleBGLayout = device.createBindGroupLayout({ bindings: [layoutUR, layoutUM, layoutLR] });
-
- // GPUPipelineLayout and GPURenderPipeline
- const pipelineLayout = device.createPipelineLayout({ bindGroupLayouts: [leftTriangleBGLayout, rightTriangleBGLayout] });
- const pipeline = createBasicPipeline(shaderModule, device, null, pipelineLayout, vertexInput, null, "triangle-list");
-
- // GPUBufferBindings
- const bindingUL = createBufferBinding(upperLeft);
- const bindingUM = createBufferBinding(upperMiddle);
- const bindingUR = createBufferBinding(upperRight);
- const bindingLL = createBufferBinding(lowerLeft);
- const bindingLR = createBufferBinding(lowerRight);
- const bindingG = createBufferBinding(green);
-
- // GPUBindGroupBindings
- const bgBindingUL = { binding: bindingNums.UL, resource: bindingUL };
- const bgBindingUM = { binding: bindingNums.UM, resource: bindingUM };
- const bgBindingUR = { binding: bindingNums.UR, resource: bindingUR };
- const bgBindingLL = { binding: bindingNums.LL, resource: bindingLL };
- const bgBindingLR = { binding: bindingNums.LR, resource: bindingLR };
- const bgBindingG = { binding: bindingNums.G, resource: bindingG };
-
- // GPUBindGroups
- const leftTriangleBG = device.createBindGroup({
- layout: leftTriangleBGLayout,
- bindings: [bgBindingUL, bgBindingUM, bgBindingLL, bgBindingG]
- });
- const rightTriangleBG = device.createBindGroup({
- layout: rightTriangleBGLayout,
- bindings: [bgBindingUR, bgBindingUM, bgBindingLR]
- });
-
- Promise.all(bufferPromises).then(() => {
- const commandEncoder = device.createCommandEncoder();
- const passEncoder = beginBasicRenderPass(swapChain, commandEncoder);
- passEncoder.setPipeline(pipeline);
-
- // Vertex data for upper triangles.
- passEncoder.setBindGroup(0, leftTriangleBG);
- passEncoder.setBindGroup(1, rightTriangleBG);
- // Lower triangle.
- passEncoder.setVertexBuffers(0, [verticesBuffer], [0]);
- passEncoder.draw(9, 1, 0, 0);
-
- passEncoder.endPass();
- const queue = device.getQueue();
- queue.submit([commandEncoder.finish()]);
- });
-}
-
-test().then(function() {
- if (window.testRunner)
- testRunner.notifyDone();
-}, function() {
- if (window.testRunner)
- testRunner.notifyDone();
-});
-</script>
Added: trunk/LayoutTests/webgpu/whlsl-buffer-fragment-expected.html (0 => 246394)
--- trunk/LayoutTests/webgpu/whlsl-buffer-fragment-expected.html (rev 0)
+++ trunk/LayoutTests/webgpu/whlsl-buffer-fragment-expected.html 2019-06-13 05:38:28 UTC (rev 246394)
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+<canvas id="canvas" width="400" height="400"></canvas>
+<script>
+async function start() {
+ const canvas = document.getElementById("canvas");
+ const context = canvas.getContext("2d");
+ context.fillStyle = "blue";
+ context.fillRect(0, 0, 400, 400);
+ context.fillStyle = "white";
+ context.fillRect(100, 100, 200, 200);
+}
+window.addEventListener("load", start);
+</script>
+</body>
+</html>
Copied: trunk/LayoutTests/webgpu/whlsl-buffer-fragment.html (from rev 246393, trunk/LayoutTests/webgpu/whlsl.html) (0 => 246394)
--- trunk/LayoutTests/webgpu/whlsl-buffer-fragment.html (rev 0)
+++ trunk/LayoutTests/webgpu/whlsl-buffer-fragment.html 2019-06-13 05:38:28 UTC (rev 246394)
@@ -0,0 +1,124 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+<canvas id="canvas" width="400" height="400"></canvas>
+<script>
+const shaderSource = `
+vertex float4 vertexShader(float4 position : attribute(0), float i : attribute(1)) : SV_Position {
+ return position;
+}
+
+fragment float4 fragmentShader(float4 position : SV_Position, constant float[] theBuffer : register(b0)) : SV_Target 0 {
+ return float4(theBuffer[0], theBuffer[0], theBuffer[0], 1.0);
+}
+`;
+async function start() {
+ const adapter = await navigator.gpu.requestAdapter();
+ const device = await adapter.requestDevice();
+
+ const shaderModule = device.createShaderModule({code: shaderSource, isWHLSL: true});
+ const vertexStage = {module: shaderModule, entryPoint: "vertexShader"};
+ const fragmentStage = {module: shaderModule, entryPoint: "fragmentShader"};
+ const primitiveTopology = "triangle-strip";
+ const rasterizationState = {frontFace: "cw", cullMode: "none"};
+ const alphaBlend = {};
+ const colorBlend = {};
+ const colorStates = [{format: "rgba8unorm", alphaBlend, colorBlend, writeMask: 15}]; // GPUColorWriteBits.ALL
+ const depthStencilState = null;
+
+ const attribute0 = {shaderLocation: 0, format: "float4"};
+ const attribute1 = {shaderLocation: 1, format: "float"};
+ const input0 = {stride: 16, attributeSet: [attribute0]};
+ const input1 = {stride: 4, attributeSet: [attribute1]};
+ const inputs = [input0, input1];
+ const vertexInput = {vertexBuffers: inputs};
+
+ const bindGroupLayoutDescriptor = {bindings: [{binding: 0, visibility: 7, type: "uniform-buffer"}]};
+ const bindGroupLayout = device.createBindGroupLayout(bindGroupLayoutDescriptor);
+ const pipelineLayoutDescriptor = {bindGroupLayouts: [bindGroupLayout]};
+ const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor);
+
+ const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, vertexInput, sampleCount: 1, layout: pipelineLayout};
+ const renderPipeline = device.createRenderPipeline(renderPipelineDescriptor);
+
+ const vertexBuffer0Descriptor = {size: Float32Array.BYTES_PER_ELEMENT * 4 * 4, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE};
+ const vertexBuffer0 = device.createBuffer(vertexBuffer0Descriptor);
+ const vertexBuffer0ArrayBuffer = await vertexBuffer0.mapWriteAsync();
+ const vertexBuffer0Float32Array = new Float32Array(vertexBuffer0ArrayBuffer);
+ vertexBuffer0Float32Array[0] = -0.5;
+ vertexBuffer0Float32Array[1] = -0.5;
+ vertexBuffer0Float32Array[2] = 1.0;
+ vertexBuffer0Float32Array[3] = 1;
+ vertexBuffer0Float32Array[4] = -0.5;
+ vertexBuffer0Float32Array[5] = 0.5;
+ vertexBuffer0Float32Array[6] = 1.0;
+ vertexBuffer0Float32Array[7] = 1;
+ vertexBuffer0Float32Array[8] = 0.5;
+ vertexBuffer0Float32Array[9] = -0.5;
+ vertexBuffer0Float32Array[10] = 1.0;
+ vertexBuffer0Float32Array[11] = 1;
+ vertexBuffer0Float32Array[12] = 0.5;
+ vertexBuffer0Float32Array[13] = 0.5;
+ vertexBuffer0Float32Array[14] = 1.0;
+ vertexBuffer0Float32Array[15] = 1;
+ vertexBuffer0.unmap();
+
+ const vertexBuffer1Descriptor = {size: Float32Array.BYTES_PER_ELEMENT * 4, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.MAP_WRITE};
+ const vertexBuffer1 = device.createBuffer(vertexBuffer1Descriptor);
+ const vertexBuffer1ArrayBuffer = await vertexBuffer1.mapWriteAsync();
+ const vertexBuffer1Float32Array = new Float32Array(vertexBuffer1ArrayBuffer);
+ vertexBuffer1Float32Array[0] = 1;
+ vertexBuffer1Float32Array[1] = 1;
+ vertexBuffer1Float32Array[2] = 1;
+ vertexBuffer1Float32Array[3] = 1;
+ vertexBuffer1.unmap();
+
+ const resourceBufferDescriptor = {size: Float32Array.BYTES_PER_ELEMENT, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.MAP_WRITE};
+ const resourceBuffer = device.createBuffer(resourceBufferDescriptor);
+ const resourceBufferArrayBuffer = await resourceBuffer.mapWriteAsync();
+ const resourceBufferFloat32Array = new Float32Array(resourceBufferArrayBuffer);
+ resourceBufferFloat32Array[0] = 1;
+ resourceBuffer.unmap();
+
+ const bufferBinding = {buffer: resourceBuffer, size: 4};
+ const bindGroupBinding = {binding: 0, resource: bufferBinding};
+ const bindGroupDescriptor = {layout: bindGroupLayout, bindings: [bindGroupBinding]};
+ const bindGroup = device.createBindGroup(bindGroupDescriptor);
+
+ const canvas = document.getElementById("canvas");
+ const context = canvas.getContext("gpu");
+ const swapChainDescriptor = {device, format: "bgra8unorm"};
+ const swapChain = context.configureSwapChain(swapChainDescriptor);
+ const outputTexture = swapChain.getCurrentTexture();
+ const outputTextureView = outputTexture.createDefaultView();
+
+ const commandEncoder = device.createCommandEncoder(); // {}
+ const red = {r: 0, g: 0, b: 1, a: 1};
+ const colorAttachments = [{attachment: outputTextureView, resolveTarget: null, loadOp: "clear", storeOp: "store", clearColor: red}];
+ const depthStencilAttachment = null;
+ const renderPassDescriptor = {colorAttachments, depthStencilAttachment};
+ const renderPassEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
+ renderPassEncoder.setPipeline(renderPipeline);
+ renderPassEncoder.setBindGroup(0, bindGroup);
+ renderPassEncoder.setVertexBuffers(0, [vertexBuffer0, vertexBuffer1], [0, 0]);
+ renderPassEncoder.draw(4, 1, 0, 0);
+ renderPassEncoder.endPass();
+ const commandBuffer = commandEncoder.finish();
+ device.getQueue().submit([commandBuffer]);
+}
+if (window.testRunner)
+ testRunner.waitUntilDone();
+window.addEventListener("load", function() {
+ start().then(function() {
+ if (window.testRunner)
+ testRunner.notifyDone();
+ }, function() {
+ if (window.testRunner)
+ testRunner.notifyDone();
+ });
+});
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/webgpu/whlsl-buffer-vertex-expected.html (0 => 246394)
--- trunk/LayoutTests/webgpu/whlsl-buffer-vertex-expected.html (rev 0)
+++ trunk/LayoutTests/webgpu/whlsl-buffer-vertex-expected.html 2019-06-13 05:38:28 UTC (rev 246394)
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+<canvas id="canvas" width="400" height="400"></canvas>
+<script>
+async function start() {
+ const canvas = document.getElementById("canvas");
+ const context = canvas.getContext("2d");
+ context.fillStyle = "blue";
+ context.fillRect(0, 0, 400, 400);
+ context.fillStyle = "white";
+ context.fillRect(100, 100, 200, 200);
+}
+window.addEventListener("load", start);
+</script>
+</body>
+</html>
Copied: trunk/LayoutTests/webgpu/whlsl-buffer-vertex.html (from rev 246393, trunk/LayoutTests/webgpu/whlsl.html) (0 => 246394)
--- trunk/LayoutTests/webgpu/whlsl-buffer-vertex.html (rev 0)
+++ trunk/LayoutTests/webgpu/whlsl-buffer-vertex.html 2019-06-13 05:38:28 UTC (rev 246394)
@@ -0,0 +1,101 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+<canvas id="canvas" width="400" height="400"></canvas>
+<script>
+const shaderSource = `
+vertex float4 vertexShader(constant float4[] buffer : register(b0), uint id : SV_VertexID) : SV_Position {
+ return buffer[id];
+}
+
+fragment float4 fragmentShader(float4 position : SV_Position) : SV_Target 0 {
+ return float4(1.0, 1.0, 1.0, 1.0);
+}
+`;
+async function start() {
+ const adapter = await navigator.gpu.requestAdapter();
+ const device = await adapter.requestDevice();
+
+ const shaderModule = device.createShaderModule({code: shaderSource, isWHLSL: true});
+ const vertexStage = {module: shaderModule, entryPoint: "vertexShader"};
+ const fragmentStage = {module: shaderModule, entryPoint: "fragmentShader"};
+ const primitiveTopology = "triangle-strip";
+ const rasterizationState = {frontFace: "cw", cullMode: "none"};
+ const alphaBlend = {};
+ const colorBlend = {};
+ const colorStates = [{format: "rgba8unorm", alphaBlend, colorBlend, writeMask: 15}]; // GPUColorWriteBits.ALL
+ const depthStencilState = null;
+
+ const vertexInput = {vertexBuffers: []};
+
+ const bindGroupLayoutDescriptor = {bindings: [{binding: 0, visibility: 7, type: "uniform-buffer"}]};
+ const bindGroupLayout = device.createBindGroupLayout(bindGroupLayoutDescriptor);
+ const pipelineLayoutDescriptor = {bindGroupLayouts: [bindGroupLayout]};
+ const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor);
+
+ const renderPipelineDescriptor = {vertexStage, fragmentStage, primitiveTopology, rasterizationState, colorStates, depthStencilState, vertexInput, sampleCount: 1, layout: pipelineLayout};
+ const renderPipeline = device.createRenderPipeline(renderPipelineDescriptor);
+
+ const resourceBufferDescriptor = {size: 4 * 4 * Float32Array.BYTES_PER_ELEMENT, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.MAP_WRITE};
+ const resourceBuffer = device.createBuffer(resourceBufferDescriptor);
+ const resourceBufferArrayBuffer = await resourceBuffer.mapWriteAsync();
+ const resourceBufferFloat32Array = new Float32Array(resourceBufferArrayBuffer);
+ resourceBufferFloat32Array[0] = -0.5;
+ resourceBufferFloat32Array[1] = -0.5;
+ resourceBufferFloat32Array[2] = 1.0;
+ resourceBufferFloat32Array[3] = 1;
+ resourceBufferFloat32Array[4] = -0.5;
+ resourceBufferFloat32Array[5] = 0.5;
+ resourceBufferFloat32Array[6] = 1.0;
+ resourceBufferFloat32Array[7] = 1;
+ resourceBufferFloat32Array[8] = 0.5;
+ resourceBufferFloat32Array[9] = -0.5;
+ resourceBufferFloat32Array[10] = 1.0;
+ resourceBufferFloat32Array[11] = 1;
+ resourceBufferFloat32Array[12] = 0.5;
+ resourceBufferFloat32Array[13] = 0.5;
+ resourceBufferFloat32Array[14] = 1.0;
+ resourceBufferFloat32Array[15] = 1;
+ resourceBuffer.unmap();
+
+ const bufferBinding = {buffer: resourceBuffer, size: 4};
+ const bindGroupBinding = {binding: 0, resource: bufferBinding};
+ const bindGroupDescriptor = {layout: bindGroupLayout, bindings: [bindGroupBinding]};
+ const bindGroup = device.createBindGroup(bindGroupDescriptor);
+
+ const canvas = document.getElementById("canvas");
+ const context = canvas.getContext("gpu");
+ const swapChainDescriptor = {device, format: "bgra8unorm"};
+ const swapChain = context.configureSwapChain(swapChainDescriptor);
+ const outputTexture = swapChain.getCurrentTexture();
+ const outputTextureView = outputTexture.createDefaultView();
+
+ const commandEncoder = device.createCommandEncoder(); // {}
+ const red = {r: 0, g: 0, b: 1, a: 1};
+ const colorAttachments = [{attachment: outputTextureView, resolveTarget: null, loadOp: "clear", storeOp: "store", clearColor: red}];
+ const depthStencilAttachment = null;
+ const renderPassDescriptor = {colorAttachments, depthStencilAttachment};
+ const renderPassEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
+ renderPassEncoder.setPipeline(renderPipeline);
+ renderPassEncoder.setBindGroup(0, bindGroup);
+ renderPassEncoder.draw(4, 1, 0, 0);
+ renderPassEncoder.endPass();
+ const commandBuffer = commandEncoder.finish();
+ device.getQueue().submit([commandBuffer]);
+}
+if (window.testRunner)
+ testRunner.waitUntilDone();
+window.addEventListener("load", function() {
+ start().then(function() {
+ if (window.testRunner)
+ testRunner.notifyDone();
+ }, function() {
+ if (window.testRunner)
+ testRunner.notifyDone();
+ });
+});
+</script>
+</body>
+</html>
Modified: trunk/LayoutTests/webgpu/whlsl-dont-crash-parsing-enum.html (246393 => 246394)
--- trunk/LayoutTests/webgpu/whlsl-dont-crash-parsing-enum.html 2019-06-13 05:10:11 UTC (rev 246393)
+++ trunk/LayoutTests/webgpu/whlsl-dont-crash-parsing-enum.html 2019-06-13 05:38:28 UTC (rev 246394)
@@ -74,10 +74,10 @@
const vertexBuffer1 = device.createBuffer(vertexBuffer1Descriptor);
const vertexBuffer1ArrayBuffer = await vertexBuffer1.mapWriteAsync();
const vertexBuffer1Float32Array = new Float32Array(vertexBuffer1ArrayBuffer);
- vertexBuffer1Descriptor[0] = 1;
- vertexBuffer1Descriptor[1] = 1;
- vertexBuffer1Descriptor[2] = 1;
- vertexBuffer1Descriptor[3] = 1;
+ vertexBuffer1Float32Array[0] = 1;
+ vertexBuffer1Float32Array[1] = 1;
+ vertexBuffer1Float32Array[2] = 1;
+ vertexBuffer1Float32Array[3] = 1;
vertexBuffer1.unmap();
const resourceBufferDescriptor = {size: Float32Array.BYTES_PER_ELEMENT, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.MAP_WRITE};
Modified: trunk/LayoutTests/webgpu/whlsl.html (246393 => 246394)
--- trunk/LayoutTests/webgpu/whlsl.html 2019-06-13 05:10:11 UTC (rev 246393)
+++ trunk/LayoutTests/webgpu/whlsl.html 2019-06-13 05:38:28 UTC (rev 246394)
@@ -69,10 +69,10 @@
const vertexBuffer1 = device.createBuffer(vertexBuffer1Descriptor);
const vertexBuffer1ArrayBuffer = await vertexBuffer1.mapWriteAsync();
const vertexBuffer1Float32Array = new Float32Array(vertexBuffer1ArrayBuffer);
- vertexBuffer1Descriptor[0] = 1;
- vertexBuffer1Descriptor[1] = 1;
- vertexBuffer1Descriptor[2] = 1;
- vertexBuffer1Descriptor[3] = 1;
+ vertexBuffer1Float32Array[0] = 1;
+ vertexBuffer1Float32Array[1] = 1;
+ vertexBuffer1Float32Array[2] = 1;
+ vertexBuffer1Float32Array[3] = 1;
vertexBuffer1.unmap();
const resourceBufferDescriptor = {size: Float32Array.BYTES_PER_ELEMENT, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.MAP_WRITE};
Modified: trunk/Source/WebCore/ChangeLog (246393 => 246394)
--- trunk/Source/WebCore/ChangeLog 2019-06-13 05:10:11 UTC (rev 246393)
+++ trunk/Source/WebCore/ChangeLog 2019-06-13 05:38:28 UTC (rev 246394)
@@ -1,3 +1,107 @@
+2019-06-12 Myles C. Maxfield <mmaxfi...@apple.com>
+
+ [WHLSL] Implement array references
+ https://bugs.webkit.org/show_bug.cgi?id=198163
+
+ Reviewed by Saam Barati.
+
+ The compiler automatically generates anders for every array reference. Luckily, the infrastructure
+ to generate those anders and emit Metal code to represent them already exists in the compiler.
+ There are two pieces remaining (which this patch implements):
+
+ 1. The _javascript_ compiler has a behavior where anders that are called with an array reference
+ as an argument don't wrap the argument in a MakePointerExpression. This is because the array
+ reference is already a reference type, so it's silly to operate on a pointer to a reference.
+ This patch implements this by teaching the type checker about which types should be passed
+ to the ander call, and by actually constructing those types in the property resolver.
+ The property resolver does this by placing the logic to construct an ander argument in a
+ single function which also has logic to save the argument in a temporary if the thread ander
+ will be called. The semantics about which functions are called in which situations are not
+ changed; instead, we just simply don't wrap array references with MakePointerExpressions.
+
+ 2. Creating a bind group from the WebGPU API has to retain information about buffer lengths for
+ each buffer so the shader can properly perform bounds checks. This can be broken down into a
+ few pieces:
+ - Creating a bind group layout has to assign extra id indexes for each buffer which will be
+ filled in to represent the buffer's length
+ - Creating the bind group itself needs to fill in the buffer length into the Metal argument
+ buffer
+ - The shader compiler needs to emit code at the beginning of entry point to find the buffer
+ lengths and pack them together into the array reference (array references correspond to
+ a Metal struct with two fields: a pointer and a length).
+
+ This patch doesn't actually implement bounds checks themselves; it just hooks up the buffer
+ lengths so https://bugs.webkit.org/show_bug.cgi?id=198600 can implement it.
+
+ The shader compiler's API is modified to allow for this extra buffer length information to be
+ passed in from the WebGPU implementation.
+
+ Unfortunately, I don't think I could split this patch up into two pieces because both are
+ required to test the compiler with buffers.
+
+ Tests: webgpu/whlsl-buffer-fragment.html
+ webgpu/whlsl-buffer-vertex.html
+
+ * Modules/webgpu/WHLSL/AST/WHLSLPropertyAccessExpression.h:
+ (WebCore::WHLSL::AST::PropertyAccessExpression::baseReference):
+ * Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.cpp:
+ (WebCore::WHLSL::AST::ResourceSemantic::isAcceptableType const): Arrays can't be resources
+ because the compiler has no way of guaranteeing if the resource is long enough to hold the
+ array at compile time.
+ * Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.cpp:
+ (WebCore::WHLSL::Metal::EntryPointScaffolding::EntryPointScaffolding): Generate an extra
+ variable name to represent the buffer length. Only do it for resources which have lengths.
+ (WebCore::WHLSL::Metal::EntryPointScaffolding::resourceHelperTypes):
+ (WebCore::WHLSL::Metal::EntryPointScaffolding::unpackResourcesAndNamedBuiltIns): Perform
+ the appropriate math to turn byte lengths into element counts and store the element count
+ in the array reference.
+ * Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.h:
+ * Modules/webgpu/WHLSL/WHLSLChecker.cpp:
+ (WebCore::WHLSL::resolveWithOperatorAnderIndexer): Refactor.
+ (WebCore::WHLSL::resolveWithOperatorLength): Ditto.
+ (WebCore::WHLSL::resolveWithReferenceComparator): Ditto.
+ (WebCore::WHLSL::resolveByInstantiation): Ditto.
+ (WebCore::WHLSL::argumentTypeForAndOverload): Given an ander, what should the type of the
+ argument be?
+ (WebCore::WHLSL::Checker::finishVisiting): Call argumentTypeForAndOverload(). Also, if
+ we couldn't find an ander, try automatically generating it, the same way that function
+ calls do. (This is how array references get their anders.)
+ (WebCore::WHLSL::Checker::visit):
+ * Modules/webgpu/WHLSL/WHLSLPipelineDescriptor.h: New WHLSL API to provide the length
+ information.
+ * Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp:
+ (WebCore::WHLSL::PropertyResolver::visit): SimplifyRightValue() can't fail any more.
+ (WebCore::WHLSL::wrapAnderCallArgument): If the ander argument should be wrapped in a
+ MakePointer or a MakeArrayReference, do that. Also, if the ander is a thread ander, save
+ the argument in a local variable and use that.
+ (WebCore::WHLSL::anderCallArgument): The equivalent of argumentTypeForAndOverload().
+ (WebCore::WHLSL::setterCall): Call anderCallArgument().
+ (WebCore::WHLSL::getterCall): Ditto.
+ (WebCore::WHLSL::modify): We used to have special-case code for handling pointer-to-argument
+ values as distinct from just the argument values themselves. However, emitting
+ chains of &* operators is valid and won't even make it through the Metal code generator
+ after https://bugs.webkit.org/show_bug.cgi?id=198600 is fixed. So, in order to simplify
+ wrapAnderCallArgument(), don't special case these values and just create &* chains instead.
+ (WebCore::WHLSL::PropertyResolver::simplifyRightValue):
+ (WebCore::WHLSL::LeftValueSimplifier::finishVisiting): Call anderCallArgument().
+ * Modules/webgpu/WHLSL/WHLSLSemanticMatcher.cpp: Update to support the new compiler API.
+ (WebCore::WHLSL::matchMode):
+ (WebCore::WHLSL::matchResources):
+ * Modules/webgpu/WebGPUBindGroupDescriptor.cpp: Ditto.
+ (WebCore::WebGPUBindGroupDescriptor::tryCreateGPUBindGroupDescriptor const):
+ * platform/graphics/gpu/GPUBindGroupLayout.h: Add some internal implementation data inside
+ the bindings object. Use a Variant to differentiate between the various bindings types, and
+ put the extra length field on just those members of the variant that represent buffers.
+ * platform/graphics/gpu/cocoa/GPUBindGroupLayoutMetal.mm: Update to support the new compiler API.
+ (WebCore::argumentDescriptor):
+ (WebCore::GPUBindGroupLayout::tryCreate):
+ * platform/graphics/gpu/cocoa/GPUBindGroupMetal.mm: Ditto.
+ (WebCore::setBufferOnEncoder):
+ (WebCore::GPUBindGroup::tryCreate):
+ * platform/graphics/gpu/cocoa/GPURenderPipelineMetal.mm: Ditto.
+ (WebCore::convertBindingType):
+ (WebCore::convertLayout):
+
2019-06-12 Carlos Garcia Campos <cgar...@igalia.com>
[cairo][SVG] If clipPath has multiple elements, clip-path doesn't work with transform
Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLPropertyAccessExpression.h (246393 => 246394)
--- trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLPropertyAccessExpression.h 2019-06-13 05:10:11 UTC (rev 246393)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLPropertyAccessExpression.h 2019-06-13 05:38:28 UTC (rev 246394)
@@ -99,6 +99,7 @@
}
_expression_& base() { return m_base; }
+ UniqueRef<_expression_>& baseReference() { return m_base; }
UniqueRef<_expression_> takeBase() { return WTFMove(m_base); }
private:
Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.cpp (246393 => 246394)
--- trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.cpp 2019-06-13 05:10:11 UTC (rev 246393)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLResourceSemantic.cpp 2019-06-13 05:38:28 UTC (rev 246394)
@@ -49,8 +49,6 @@
auto& referenceType = downcast<ReferenceType>(unnamedType);
return referenceType.addressSpace() == AddressSpace::Constant || referenceType.addressSpace() == AddressSpace::Device;
}
- if (is<ArrayType>(unnamedType))
- return true;
if (is<TypeReference>(unnamedType)) {
auto& typeReference = downcast<TypeReference>(unnamedType);
if (is<NativeTypeDeclaration>(typeReference.resolvedType()))
@@ -71,7 +69,7 @@
case Mode::Buffer:
if (is<ReferenceType>(unnamedType))
return downcast<ReferenceType>(unnamedType).addressSpace() == AddressSpace::Constant;
- return is<ArrayType>(unnamedType);
+ return false;
case Mode::Sampler:
return matches(unnamedType, intrinsics.samplerType());
}
Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.cpp (246393 => 246394)
--- trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.cpp 2019-06-13 05:10:11 UTC (rev 246393)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.cpp 2019-06-13 05:38:28 UTC (rev 246394)
@@ -32,6 +32,7 @@
#include "WHLSLFunctionDefinition.h"
#include "WHLSLGatherEntryPointItems.h"
#include "WHLSLPipelineDescriptor.h"
+#include "WHLSLReferenceType.h"
#include "WHLSLResourceSemantic.h"
#include "WHLSLStageInOutSemantic.h"
#include "WHLSLStructureDefinition.h"
@@ -108,7 +109,16 @@
for (size_t j = 0; j < m_layout[i].bindings.size(); ++j) {
NamedBinding namedBinding;
namedBinding.elementName = m_typeNamer.generateNextStructureElementName();
- namedBinding.index = m_layout[i].bindings[j].name; // GPUBindGroupLayout::tryCreate() makes sure these don't collide.
+ namedBinding.index = m_layout[i].bindings[j].internalName;
+ WTF::visit(WTF::makeVisitor([&](UniformBufferBinding& uniformBufferBinding) {
+ LengthInformation lengthInformation { m_typeNamer.generateNextStructureElementName(), m_generateNextVariableName(), uniformBufferBinding.lengthName };
+ namedBinding.lengthInformation = lengthInformation;
+ }, [&](SamplerBinding&) {
+ }, [&](TextureBinding&) {
+ }, [&](StorageBufferBinding& storageBufferBinding) {
+ LengthInformation lengthInformation { m_typeNamer.generateNextStructureElementName(), m_generateNextVariableName(), storageBufferBinding.lengthName };
+ namedBinding.lengthInformation = lengthInformation;
+ }), m_layout[i].bindings[j].binding);
namedBindGroup.namedBindings.uncheckedAppend(WTFMove(namedBinding));
}
m_namedBindGroups.uncheckedAppend(WTFMove(namedBindGroup));
@@ -137,10 +147,16 @@
auto iterator = m_resourceMap.find(&m_layout[i].bindings[j]);
if (iterator == m_resourceMap.end())
continue;
- auto mangledTypeName = m_typeNamer.mangledNameForType(*m_entryPointItems.inputs[iterator->value].unnamedType);
+ auto& unnamedType = *m_entryPointItems.inputs[iterator->value].unnamedType;
+ ASSERT(is<AST::ReferenceType>(unnamedType));
+ auto& referenceType = downcast<AST::ReferenceType>(unnamedType);
+ auto mangledTypeName = m_typeNamer.mangledNameForType(referenceType.elementType());
+ auto addressSpace = toString(referenceType.addressSpace());
auto elementName = m_namedBindGroups[i].namedBindings[j].elementName;
auto index = m_namedBindGroups[i].namedBindings[j].index;
- stringBuilder.append(makeString(" ", mangledTypeName, ' ', elementName, " [[id(", index, ")]];\n"));
+ stringBuilder.append(makeString(" ", addressSpace, " ", mangledTypeName, "* ", elementName, " [[id(", index, ")]];\n"));
+ if (auto lengthInformation = m_namedBindGroups[i].namedBindings[j].lengthInformation)
+ stringBuilder.append(makeString(" uint2 ", lengthInformation->elementName, " [[id(", lengthInformation->index, ")]];\n"));
}
stringBuilder.append("};\n\n");
}
@@ -257,9 +273,28 @@
auto iterator = m_resourceMap.find(&m_layout[i].bindings[j]);
if (iterator == m_resourceMap.end())
continue;
- auto& path = m_entryPointItems.inputs[iterator->value].path;
- auto elementName = m_namedBindGroups[i].namedBindings[j].elementName;
- stringBuilder.append(makeString(mangledInputPath(path), " = ", variableName, '.', elementName, ";\n"));
+ if (m_namedBindGroups[i].namedBindings[j].lengthInformation) {
+ auto& path = m_entryPointItems.inputs[iterator->value].path;
+ auto elementName = m_namedBindGroups[i].namedBindings[j].elementName;
+ auto lengthElementName = m_namedBindGroups[i].namedBindings[j].lengthInformation->elementName;
+ auto lengthTemporaryName = m_namedBindGroups[i].namedBindings[j].lengthInformation->temporaryName;
+
+ auto& unnamedType = *m_entryPointItems.inputs[iterator->value].unnamedType;
+ ASSERT(is<AST::ReferenceType>(unnamedType));
+ auto& referenceType = downcast<AST::ReferenceType>(unnamedType);
+ auto mangledTypeName = m_typeNamer.mangledNameForType(referenceType.elementType());
+
+ stringBuilder.append(makeString("size_t ", lengthTemporaryName, " = ", variableName, '.', lengthElementName, ".x;\n"));
+ stringBuilder.append(makeString(lengthTemporaryName, " = ", lengthTemporaryName, " << 32;\n"));
+ stringBuilder.append(makeString(lengthTemporaryName, " = ", lengthTemporaryName, " | ", variableName, '.', lengthElementName, ".y;\n"));
+ stringBuilder.append(makeString(lengthTemporaryName, " = ", lengthTemporaryName, " / sizeof(", mangledTypeName, ");\n"));
+ stringBuilder.append(makeString("if (", lengthTemporaryName, " > 0xFFFFFFFF) ", lengthTemporaryName, " = 0xFFFFFFFF;\n"));
+ stringBuilder.append(makeString(mangledInputPath(path), " = { ", variableName, '.', elementName, ", static_cast<uint32_t>(", lengthTemporaryName, ") };\n"));
+ } else {
+ auto& path = m_entryPointItems.inputs[iterator->value].path;
+ auto elementName = m_namedBindGroups[i].namedBindings[j].elementName;
+ stringBuilder.append(makeString(mangledInputPath(path), " = ", variableName, '.', elementName, ";\n"));
+ }
}
}
Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.h (246393 => 246394)
--- trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.h 2019-06-13 05:10:11 UTC (rev 246393)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLEntryPointScaffolding.h 2019-06-13 05:38:28 UTC (rev 246394)
@@ -77,9 +77,15 @@
Layout& m_layout;
std::function<String()> m_generateNextVariableName;
+ struct LengthInformation {
+ String elementName;
+ String temporaryName;
+ unsigned index;
+ };
struct NamedBinding {
String elementName;
unsigned index;
+ Optional<LengthInformation> lengthInformation;
};
struct NamedBindGroup {
String structName;
Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp (246393 => 246394)
--- trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp 2019-06-13 05:10:11 UTC (rev 246393)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp 2019-06-13 05:38:28 UTC (rev 246394)
@@ -117,29 +117,29 @@
}
};
-static AST::NativeFunctionDeclaration resolveWithOperatorAnderIndexer(AST::CallExpression& callExpression, AST::ArrayReferenceType& firstArgument, const Intrinsics& intrinsics)
+static AST::NativeFunctionDeclaration resolveWithOperatorAnderIndexer(Lexer::Token origin, AST::ArrayReferenceType& firstArgument, const Intrinsics& intrinsics)
{
const bool isOperator = true;
- auto returnType = makeUniqueRef<AST::PointerType>(Lexer::Token(callExpression.origin()), firstArgument.addressSpace(), firstArgument.elementType().clone());
+ auto returnType = makeUniqueRef<AST::PointerType>(Lexer::Token(origin), firstArgument.addressSpace(), firstArgument.elementType().clone());
AST::VariableDeclarations parameters;
- parameters.append(makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(callExpression.origin()), AST::Qualifiers(), firstArgument.clone(), String(), WTF::nullopt, WTF::nullopt));
- parameters.append(makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(callExpression.origin()), AST::Qualifiers(), UniqueRef<AST::UnnamedType>(AST::TypeReference::wrap(Lexer::Token(callExpression.origin()), intrinsics.uintType())), String(), WTF::nullopt, WTF::nullopt));
- return AST::NativeFunctionDeclaration(AST::FunctionDeclaration(Lexer::Token(callExpression.origin()), AST::AttributeBlock(), WTF::nullopt, WTFMove(returnType), String("operator&[]", String::ConstructFromLiteral), WTFMove(parameters), WTF::nullopt, isOperator));
+ parameters.append(makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(origin), AST::Qualifiers(), firstArgument.clone(), String(), WTF::nullopt, WTF::nullopt));
+ parameters.append(makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(origin), AST::Qualifiers(), UniqueRef<AST::UnnamedType>(AST::TypeReference::wrap(Lexer::Token(origin), intrinsics.uintType())), String(), WTF::nullopt, WTF::nullopt));
+ return AST::NativeFunctionDeclaration(AST::FunctionDeclaration(Lexer::Token(origin), AST::AttributeBlock(), WTF::nullopt, WTFMove(returnType), String("operator&[]", String::ConstructFromLiteral), WTFMove(parameters), WTF::nullopt, isOperator));
}
-static AST::NativeFunctionDeclaration resolveWithOperatorLength(AST::CallExpression& callExpression, AST::UnnamedType& firstArgument, const Intrinsics& intrinsics)
+static AST::NativeFunctionDeclaration resolveWithOperatorLength(Lexer::Token origin, AST::UnnamedType& firstArgument, const Intrinsics& intrinsics)
{
const bool isOperator = true;
- auto returnType = AST::TypeReference::wrap(Lexer::Token(callExpression.origin()), intrinsics.uintType());
+ auto returnType = AST::TypeReference::wrap(Lexer::Token(origin), intrinsics.uintType());
AST::VariableDeclarations parameters;
- parameters.append(makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(callExpression.origin()), AST::Qualifiers(), firstArgument.clone(), String(), WTF::nullopt, WTF::nullopt));
- return AST::NativeFunctionDeclaration(AST::FunctionDeclaration(Lexer::Token(callExpression.origin()), AST::AttributeBlock(), WTF::nullopt, WTFMove(returnType), String("operator.length", String::ConstructFromLiteral), WTFMove(parameters), WTF::nullopt, isOperator));
+ parameters.append(makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(origin), AST::Qualifiers(), firstArgument.clone(), String(), WTF::nullopt, WTF::nullopt));
+ return AST::NativeFunctionDeclaration(AST::FunctionDeclaration(Lexer::Token(origin), AST::AttributeBlock(), WTF::nullopt, WTFMove(returnType), String("operator.length", String::ConstructFromLiteral), WTFMove(parameters), WTF::nullopt, isOperator));
}
-static AST::NativeFunctionDeclaration resolveWithReferenceComparator(AST::CallExpression& callExpression, ResolvingType& firstArgument, ResolvingType& secondArgument, const Intrinsics& intrinsics)
+static AST::NativeFunctionDeclaration resolveWithReferenceComparator(Lexer::Token origin, ResolvingType& firstArgument, ResolvingType& secondArgument, const Intrinsics& intrinsics)
{
const bool isOperator = true;
- auto returnType = AST::TypeReference::wrap(Lexer::Token(callExpression.origin()), intrinsics.boolType());
+ auto returnType = AST::TypeReference::wrap(Lexer::Token(origin), intrinsics.boolType());
auto argumentType = firstArgument.visit(WTF::makeVisitor([](UniqueRef<AST::UnnamedType>& unnamedType) -> UniqueRef<AST::UnnamedType> {
return unnamedType->clone();
}, [&](RefPtr<ResolvableTypeReference>&) -> UniqueRef<AST::UnnamedType> {
@@ -149,13 +149,13 @@
// We encountered "null == null".
// FIXME: https://bugs.webkit.org/show_bug.cgi?id=198162 This can probably be generalized, using the "preferred type" infrastructure used by generic literals
ASSERT_NOT_REACHED();
- return AST::TypeReference::wrap(Lexer::Token(callExpression.origin()), intrinsics.intType());
+ return AST::TypeReference::wrap(Lexer::Token(origin), intrinsics.intType());
}));
}));
AST::VariableDeclarations parameters;
- parameters.append(makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(callExpression.origin()), AST::Qualifiers(), argumentType->clone(), String(), WTF::nullopt, WTF::nullopt));
- parameters.append(makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(callExpression.origin()), AST::Qualifiers(), UniqueRef<AST::UnnamedType>(WTFMove(argumentType)), String(), WTF::nullopt, WTF::nullopt));
- return AST::NativeFunctionDeclaration(AST::FunctionDeclaration(Lexer::Token(callExpression.origin()), AST::AttributeBlock(), WTF::nullopt, WTFMove(returnType), String("operator==", String::ConstructFromLiteral), WTFMove(parameters), WTF::nullopt, isOperator));
+ parameters.append(makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(origin), AST::Qualifiers(), argumentType->clone(), String(), WTF::nullopt, WTF::nullopt));
+ parameters.append(makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(origin), AST::Qualifiers(), UniqueRef<AST::UnnamedType>(WTFMove(argumentType)), String(), WTF::nullopt, WTF::nullopt));
+ return AST::NativeFunctionDeclaration(AST::FunctionDeclaration(Lexer::Token(origin), AST::AttributeBlock(), WTF::nullopt, WTFMove(returnType), String("operator==", String::ConstructFromLiteral), WTFMove(parameters), WTF::nullopt, isOperator));
}
enum class Acceptability {
@@ -164,9 +164,9 @@
No
};
-static Optional<AST::NativeFunctionDeclaration> resolveByInstantiation(AST::CallExpression& callExpression, const Vector<std::reference_wrapper<ResolvingType>>& types, const Intrinsics& intrinsics)
+static Optional<AST::NativeFunctionDeclaration> resolveByInstantiation(const String& name, Lexer::Token origin, const Vector<std::reference_wrapper<ResolvingType>>& types, const Intrinsics& intrinsics)
{
- if (callExpression.name() == "operator&[]" && types.size() == 2) {
+ if (name == "operator&[]" && types.size() == 2) {
auto* firstArgumentArrayRef = types[0].get().visit(WTF::makeVisitor([](UniqueRef<AST::UnnamedType>& unnamedType) -> AST::ArrayReferenceType* {
if (is<AST::ArrayReferenceType>(static_cast<AST::UnnamedType&>(unnamedType)))
return &downcast<AST::ArrayReferenceType>(static_cast<AST::UnnamedType&>(unnamedType));
@@ -180,8 +180,8 @@
return resolvableTypeReference->resolvableType().canResolve(intrinsics.uintType());
}));
if (firstArgumentArrayRef && secondArgumentIsUint)
- return resolveWithOperatorAnderIndexer(callExpression, *firstArgumentArrayRef, intrinsics);
- } else if (callExpression.name() == "operator.length" && types.size() == 1) {
+ 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)))
return &unnamedType;
@@ -190,8 +190,8 @@
return nullptr;
}));
if (firstArgumentReference)
- return resolveWithOperatorLength(callExpression, *firstArgumentReference, intrinsics);
- } else if (callExpression.name() == "operator==" && types.size() == 2) {
+ return resolveWithOperatorLength(origin, *firstArgumentReference, intrinsics);
+ } else if (name == "operator==" && types.size() == 2) {
auto acceptability = [](ResolvingType& resolvingType) -> Acceptability {
return resolvingType.visit(WTF::makeVisitor([](UniqueRef<AST::UnnamedType>& unnamedType) -> Acceptability {
return is<AST::ReferenceType>(static_cast<AST::UnnamedType&>(unnamedType)) ? Acceptability::Yes : Acceptability::No;
@@ -210,7 +210,7 @@
|| (leftAcceptability == Acceptability::Yes && rightAcceptability == Acceptability::Maybe))
success = true;
if (success)
- return resolveWithReferenceComparator(callExpression, types[0].get(), types[1].get(), intrinsics);
+ return resolveWithReferenceComparator(origin, types[0].get(), types[1].get(), intrinsics);
}
return WTF::nullopt;
}
@@ -969,6 +969,29 @@
assignType(makeArrayReferenceExpression, makeUniqueRef<AST::ArrayReferenceType>(Lexer::Token(makeArrayReferenceExpression.origin()), *leftAddressSpace, leftValueType->clone()));
}
+static Optional<UniqueRef<AST::UnnamedType>> argumentTypeForAndOverload(AST::UnnamedType& baseType, AST::AddressSpace addressSpace)
+{
+ auto& unifyNode = baseType.unifyNode();
+ if (is<AST::NamedType>(unifyNode)) {
+ auto& namedType = downcast<AST::NamedType>(unifyNode);
+ return { makeUniqueRef<AST::PointerType>(Lexer::Token(namedType.origin()), addressSpace, AST::TypeReference::wrap(Lexer::Token(namedType.origin()), namedType)) };
+ }
+
+ ASSERT(is<AST::UnnamedType>(unifyNode));
+ auto& unnamedType = downcast<AST::UnnamedType>(unifyNode);
+
+ if (is<AST::ArrayReferenceType>(unnamedType))
+ return unnamedType.clone();
+
+ if (is<AST::ArrayType>(unnamedType))
+ return { makeUniqueRef<AST::ArrayReferenceType>(Lexer::Token(unnamedType.origin()), addressSpace, downcast<AST::ArrayType>(unnamedType).type().clone()) };
+
+ if (is<AST::PointerType>(unnamedType))
+ return WTF::nullopt;
+
+ return { makeUniqueRef<AST::PointerType>(Lexer::Token(unnamedType.origin()), addressSpace, unnamedType.clone()) };
+}
+
void Checker::finishVisiting(AST::PropertyAccessExpression& propertyAccessExpression, ResolvingType* additionalArgumentType)
{
auto baseInfo = recurseAndGetInfo(propertyAccessExpression.base());
@@ -992,17 +1015,24 @@
AST::UnnamedType* anderReturnType = nullptr;
auto leftAddressSpace = baseInfo->typeAnnotation.leftAddressSpace();
if (leftAddressSpace) {
- ResolvingType argumentType = { makeUniqueRef<AST::PointerType>(Lexer::Token(propertyAccessExpression.origin()), *leftAddressSpace, baseUnnamedType->get().clone()) };
- Vector<std::reference_wrapper<ResolvingType>> anderArgumentTypes { argumentType };
- if (additionalArgumentType)
- anderArgumentTypes.append(*additionalArgumentType);
- if ((anderFunction = resolveFunctionOverload(propertyAccessExpression.possibleAnderOverloads(), anderArgumentTypes)))
- anderReturnType = &downcast<AST::PointerType>(anderFunction->type()).elementType(); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198164 Enforce the return of anders will always be a pointer
+ if (auto argumentTypeForAndOverload = WHLSL::argumentTypeForAndOverload(*baseUnnamedType, *leftAddressSpace)) {
+ ResolvingType argumentType = { WTFMove(*argumentTypeForAndOverload) };
+ Vector<std::reference_wrapper<ResolvingType>> anderArgumentTypes { argumentType };
+ if (additionalArgumentType)
+ anderArgumentTypes.append(*additionalArgumentType);
+ if ((anderFunction = resolveFunctionOverload(propertyAccessExpression.possibleAnderOverloads(), anderArgumentTypes)))
+ anderReturnType = &downcast<AST::PointerType>(anderFunction->type()).elementType(); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198164 Enforce the return of anders will always be a pointer
+ else if (auto newFunction = resolveByInstantiation(propertyAccessExpression.anderFunctionName(), propertyAccessExpression.origin(), anderArgumentTypes, m_intrinsics)) {
+ m_program.append(WTFMove(*newFunction));
+ anderFunction = &m_program.nativeFunctionDeclarations().last();
+ anderReturnType = &downcast<AST::PointerType>(anderFunction->type()).elementType(); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198164 Enforce the return of anders will always be a pointer
+ }
+ }
}
AST::FunctionDeclaration* threadAnderFunction = nullptr;
AST::UnnamedType* threadAnderReturnType = nullptr;
- {
+ if (auto argumentTypeForAndOverload = WHLSL::argumentTypeForAndOverload(*baseUnnamedType, AST::AddressSpace::Thread)) {
ResolvingType argumentType = { makeUniqueRef<AST::PointerType>(Lexer::Token(propertyAccessExpression.origin()), AST::AddressSpace::Thread, baseUnnamedType->get().clone()) };
Vector<std::reference_wrapper<ResolvingType>> threadAnderArgumentTypes { argumentType };
if (additionalArgumentType)
@@ -1009,6 +1039,11 @@
threadAnderArgumentTypes.append(*additionalArgumentType);
if ((threadAnderFunction = resolveFunctionOverload(propertyAccessExpression.possibleAnderOverloads(), threadAnderArgumentTypes)))
threadAnderReturnType = &downcast<AST::PointerType>(threadAnderFunction->type()).elementType(); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198164 Enforce the return of anders will always be a pointer
+ else if (auto newFunction = resolveByInstantiation(propertyAccessExpression.anderFunctionName(), propertyAccessExpression.origin(), threadAnderArgumentTypes, m_intrinsics)) {
+ m_program.append(WTFMove(*newFunction));
+ threadAnderFunction = &m_program.nativeFunctionDeclarations().last();
+ threadAnderReturnType = &downcast<AST::PointerType>(anderFunction->type()).elementType(); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198164 Enforce the return of anders will always be a pointer
+ }
}
if (leftAddressSpace && !anderFunction && !getterFunction) {
@@ -1434,7 +1469,7 @@
ASSERT(callExpression.hasOverloads());
auto* function = resolveFunctionOverload(*callExpression.overloads(), types, callExpression.castReturnType());
if (!function) {
- if (auto newFunction = resolveByInstantiation(callExpression, types, m_intrinsics)) {
+ if (auto newFunction = resolveByInstantiation(callExpression.name(), callExpression.origin(), types, m_intrinsics)) {
m_program.append(WTFMove(*newFunction));
function = &m_program.nativeFunctionDeclarations().last();
}
Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPipelineDescriptor.h (246393 => 246394)
--- trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPipelineDescriptor.h 2019-06-13 05:10:11 UTC (rev 246393)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPipelineDescriptor.h 2019-06-13 05:38:28 UTC (rev 246394)
@@ -114,18 +114,28 @@
Compute = 1 << 2
};
-enum class BindingType : uint8_t {
- UniformBuffer,
- Sampler,
- Texture,
- StorageBuffer,
- // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198168 Add the dynamic types
+struct UniformBufferBinding {
+ unsigned lengthName;
};
+struct SamplerBinding {
+};
+
+struct TextureBinding {
+};
+
+struct StorageBufferBinding {
+ unsigned lengthName;
+};
+
+// FIXME: https://bugs.webkit.org/show_bug.cgi?id=198168 Add the dynamic types
+
struct Binding {
+ using BindingDetails = Variant<UniformBufferBinding, SamplerBinding, TextureBinding, StorageBufferBinding>;
OptionSet<ShaderStage> visibility;
- BindingType bindingType;
- unsigned name;
+ BindingDetails binding;
+ unsigned internalName;
+ unsigned externalName;
};
struct BindGroup {
Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp (246393 => 246394)
--- trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp 2019-06-13 05:10:11 UTC (rev 246393)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLPropertyResolver.cpp 2019-06-13 05:38:28 UTC (rev 246394)
@@ -35,6 +35,7 @@
#include "WHLSLDotExpression.h"
#include "WHLSLFunctionDeclaration.h"
#include "WHLSLFunctionDefinition.h"
+#include "WHLSLMakeArrayReferenceExpression.h"
#include "WHLSLMakePointerExpression.h"
#include "WHLSLPointerType.h"
#include "WHLSLReadModifyWriteExpression.h"
@@ -55,7 +56,7 @@
void visit(AST::AssignmentExpression&) override;
void visit(AST::ReadModifyWriteExpression&) override;
- bool simplifyRightValue(AST::PropertyAccessExpression&);
+ void simplifyRightValue(AST::PropertyAccessExpression&);
bool simplifyAbstractLeftValue(AST::AssignmentExpression&, AST::DotExpression&, UniqueRef<AST::_expression_>&& right);
void simplifyLeftValue(AST::_expression_&);
@@ -65,8 +66,7 @@
void PropertyResolver::visit(AST::DotExpression& dotExpression)
{
// Unless we're inside an AssignmentExpression or a ReadModifyWriteExpression, we're a right value.
- if (!simplifyRightValue(dotExpression))
- setError();
+ simplifyRightValue(dotExpression);
}
void PropertyResolver::visit(AST::IndexExpression& indexExpression)
@@ -73,8 +73,7 @@
{
checkErrorAndVisit(indexExpression.indexExpression());
// Unless we're inside an AssignmentExpression or a ReadModifyWriteExpression, we're a right value.
- if (!simplifyRightValue(indexExpression))
- setError();
+ simplifyRightValue(indexExpression);
}
void PropertyResolver::visit(AST::FunctionDefinition& functionDefinition)
@@ -84,8 +83,79 @@
functionDefinition.block().statements().insert(0, makeUniqueRef<AST::VariableDeclarationsStatement>(Lexer::Token(m_variableDeclarations[0]->origin()), WTFMove(m_variableDeclarations)));
}
-static Optional<UniqueRef<AST::_expression_>> setterCall(AST::PropertyAccessExpression& propertyAccessExpression, AST::FunctionDeclaration* relevantAnder, UniqueRef<AST::_expression_>&& newValue, const std::function<UniqueRef<AST::_expression_>()>& leftValueFactory, const std::function<UniqueRef<AST::_expression_>()>& pointerToLeftValueFactory, AST::VariableDeclaration* indexVariable)
+enum class WhichAnder {
+ ThreadAnder,
+ Ander
+};
+
+struct AnderCallArgumentResult {
+ UniqueRef<AST::_expression_> _expression_;
+ Optional<UniqueRef<AST::VariableDeclaration>> variableDeclaration;
+ WhichAnder whichAnder;
+};
+
+template <typename ExpressionConstructor, typename TypeConstructor>
+static Optional<AnderCallArgumentResult> wrapAnderCallArgument(UniqueRef<AST::_expression_>& _expression_, 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());
+ return {{ WTFMove(makeArrayReference), WTF::nullopt, WhichAnder::Ander }};
+ }
+ 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));
+ variableReference1->setType(baseType->clone());
+ variableReference1->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread });
+
+ auto assignmentExpression = makeUniqueRef<AST::AssignmentExpression>(Lexer::Token(origin), WTFMove(variableReference1), WTFMove(_expression_));
+ assignmentExpression->setType(baseType->clone());
+ assignmentExpression->setTypeAnnotation(AST::RightValue());
+
+ auto variableReference2 = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(variableDeclaration));
+ variableReference2->setType(baseType->clone());
+ variableReference2->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread });
+
+ auto _expression_ = makeUniqueRef<ExpressionConstructor>(Lexer::Token(origin), WTFMove(variableReference2));
+ auto resultType = makeUniqueRef<TypeConstructor>(Lexer::Token(origin), AST::AddressSpace::Thread, WTFMove(baseType));
+ _expression_->setType(resultType->clone());
+ _expression_->setTypeAnnotation(AST::RightValue());
+
+ Vector<UniqueRef<AST::_expression_>> expressions;
+ expressions.append(WTFMove(assignmentExpression));
+ expressions.append(WTFMove(_expression_));
+ auto commaExpression = makeUniqueRef<AST::CommaExpression>(WTFMove(origin), WTFMove(expressions));
+ commaExpression->setType(WTFMove(resultType));
+ commaExpression->setTypeAnnotation(AST::RightValue());
+ return {{ WTFMove(commaExpression), { WTFMove(variableDeclaration) }, WhichAnder::ThreadAnder}};
+ }
+ return WTF::nullopt;
+}
+
+static Optional<AnderCallArgumentResult> anderCallArgument(UniqueRef<AST::_expression_>& _expression_, bool anderFunction, bool threadAnderFunction)
+{
+ auto& unifyNode = _expression_->resolvedType().unifyNode();
+ if (is<AST::UnnamedType>(unifyNode)) {
+ auto& unnamedType = downcast<AST::UnnamedType>(unifyNode);
+ ASSERT(!is<AST::PointerType>(unnamedType));
+ 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::MakePointerExpression, AST::PointerType>(_expression_, 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)
+{
auto maybeAddIndexArgument = [&](Vector<UniqueRef<AST::_expression_>>& arguments) {
if (!indexVariable)
return;
@@ -98,8 +168,13 @@
if (relevantAnder) {
// *operator&.foo(&v) = newValue
+ auto leftValue = leftValueFactory();
+ auto argument = anderCallArgument(leftValue, true, true);
+ ASSERT(argument);
+ ASSERT(!argument->variableDeclaration);
+ ASSERT(argument->whichAnder == WhichAnder::Ander);
Vector<UniqueRef<AST::_expression_>> arguments;
- arguments.append(pointerToLeftValueFactory());
+ arguments.append(WTFMove(argument->_expression_));
maybeAddIndexArgument(arguments);
auto callExpression = makeUniqueRef<AST::CallExpression>(Lexer::Token(propertyAccessExpression.origin()), String(relevantAnder->name()), WTFMove(arguments));
@@ -138,7 +213,7 @@
return UniqueRef<AST::_expression_>(WTFMove(assignmentExpression));
}
-static Optional<UniqueRef<AST::_expression_>> getterCall(AST::PropertyAccessExpression& propertyAccessExpression, AST::FunctionDeclaration* relevantAnder, const std::function<UniqueRef<AST::_expression_>()>& leftValueFactory, const std::function<UniqueRef<AST::_expression_>()>& pointerToLeftValueFactory, AST::VariableDeclaration* indexVariable)
+static Optional<UniqueRef<AST::_expression_>> getterCall(AST::PropertyAccessExpression& propertyAccessExpression, AST::FunctionDeclaration* relevantAnder, const std::function<UniqueRef<AST::_expression_>()>& leftValueFactory, AST::VariableDeclaration* indexVariable)
{
auto maybeAddIndexArgument = [&](Vector<UniqueRef<AST::_expression_>>& arguments) {
if (!indexVariable)
@@ -152,8 +227,13 @@
if (relevantAnder) {
// *operator&.foo(&v)
+ auto leftValue = leftValueFactory();
+ auto argument = anderCallArgument(leftValue, true, true);
+ ASSERT(argument);
+ ASSERT(!argument->variableDeclaration);
+ ASSERT(argument->whichAnder == WhichAnder::Ander);
Vector<UniqueRef<AST::_expression_>> arguments;
- arguments.append(pointerToLeftValueFactory());
+ arguments.append(WTFMove(argument->_expression_));
maybeAddIndexArgument(arguments);
auto callExpression = makeUniqueRef<AST::CallExpression>(Lexer::Token(propertyAccessExpression.origin()), String(relevantAnder->name()), WTFMove(arguments));
@@ -170,7 +250,7 @@
// operator.foo(v)
ASSERT(propertyAccessExpression.getterFunction());
-
+
Vector<UniqueRef<AST::_expression_>> arguments;
arguments.append(leftValueFactory());
maybeAddIndexArgument(arguments);
@@ -304,7 +384,7 @@
variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right?
return variableReference;
}
-
+
auto variableReference = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(pointerVariable));
ASSERT(pointerVariable->type());
variableReference->setType(pointerVariable->type()->clone());
@@ -316,26 +396,6 @@
dereferenceExpression->setTypeAnnotation(AST::LeftValue { downcast<AST::PointerType>(*pointerVariable->type()).addressSpace() });
return dereferenceExpression;
};
- auto pointerToPreviousLeftValue = [&]() -> UniqueRef<AST::_expression_> {
- if (previous) {
- auto variableReference = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(*previous));
- ASSERT(previous->type());
- variableReference->setType(previous->type()->clone());
- variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right?
-
- auto makePointerExpression = makeUniqueRef<AST::MakePointerExpression>(Lexer::Token(propertyAccessExpression.origin()), WTFMove(variableReference));
- ASSERT(previous->type());
- makePointerExpression->setType(makeUniqueRef<AST::PointerType>(Lexer::Token(propertyAccessExpression.origin()), AST::AddressSpace::Thread, previous->type()->clone()));
- makePointerExpression->setTypeAnnotation(AST::RightValue());
- return makePointerExpression;
- }
-
- auto variableReference = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(pointerVariable));
- ASSERT(pointerVariable->type());
- variableReference->setType(pointerVariable->type()->clone());
- variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right?
- return variableReference;
- };
auto appendIndexAssignment = [&](AST::PropertyAccessExpression& propertyAccessExpression, Optional<UniqueRef<AST::VariableDeclaration>>& indexVariable) {
if (!indexVariable)
return;
@@ -361,7 +421,7 @@
appendIndexAssignment(propertyAccessExpression, indexVariable);
AST::FunctionDeclaration* relevantAnder = i == chain.size() - 1 ? propertyAccessExpression.anderFunction() : propertyAccessExpression.threadAnderFunction();
- auto callExpression = getterCall(propertyAccessExpression, relevantAnder, previousLeftValue, pointerToPreviousLeftValue, indexVariable ? &*indexVariable : nullptr);
+ auto callExpression = getterCall(propertyAccessExpression, relevantAnder, previousLeftValue, indexVariable ? &*indexVariable : nullptr);
if (!callExpression)
return WTF::nullopt;
@@ -376,12 +436,12 @@
assignmentExpression->setTypeAnnotation(AST::RightValue());
expressions.append(WTFMove(assignmentExpression));
-
+
previous = &variableDeclaration;
}
appendIndexAssignment(chain[0], indexVariables[0]);
AST::FunctionDeclaration* relevantAnder = chain.size() == 1 ? propertyAccessExpression.anderFunction() : propertyAccessExpression.threadAnderFunction();
- auto lastGetterCallExpression = getterCall(chain[0], relevantAnder, previousLeftValue, pointerToPreviousLeftValue, indexVariables[0] ? &*(indexVariables[0]) : nullptr);
+ auto lastGetterCallExpression = getterCall(chain[0], relevantAnder, previousLeftValue, indexVariables[0] ? &*(indexVariables[0]) : nullptr);
// Step 3:
auto modificationResult = modification(WTFMove(lastGetterCallExpression));
@@ -404,17 +464,6 @@
variableReference->setType(variableDeclaration.type()->clone());
variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right?
return variableReference;
- }, [&]() -> UniqueRef<AST::_expression_> {
- auto variableReference = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(variableDeclaration));
- ASSERT(variableDeclaration.type());
- variableReference->setType(variableDeclaration.type()->clone());
- variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right?
-
- auto makePointerExpression = makeUniqueRef<AST::MakePointerExpression>(Lexer::Token(propertyAccessExpression.origin()), WTFMove(variableReference));
- ASSERT(variableDeclaration.type());
- makePointerExpression->setType(makeUniqueRef<AST::PointerType>(Lexer::Token(propertyAccessExpression.origin()), AST::AddressSpace::Thread, variableDeclaration.type()->clone()));
- makePointerExpression->setTypeAnnotation(AST::RightValue());
- return makePointerExpression;
}, indexVariable ? &*indexVariable : nullptr);
if (!assignmentExpression)
@@ -442,12 +491,6 @@
dereferenceExpression->setType(downcast<AST::PointerType>(*pointerVariable->type()).elementType().clone());
dereferenceExpression->setTypeAnnotation(AST::LeftValue { downcast<AST::PointerType>(*pointerVariable->type()).addressSpace() });
return dereferenceExpression;
- }, [&]() -> UniqueRef<AST::_expression_> {
- auto variableReference = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(pointerVariable));
- ASSERT(pointerVariable->type());
- variableReference->setType(pointerVariable->type()->clone());
- variableReference->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread }); // FIXME: https://bugs.webkit.org/show_bug.cgi?id=198169 Is this right?
- return variableReference;
}, indexVariables[indexVariables.size() - 1] ? &*(indexVariables[indexVariables.size() - 1]) : nullptr);
if (!assignmentExpression)
@@ -671,94 +714,50 @@
m_variableDeclarations.append(WTFMove(newVariableDeclaration));
}
-bool PropertyResolver::simplifyRightValue(AST::PropertyAccessExpression& propertyAccessExpression)
+static Optional<AnderCallArgumentResult> anderCallArgument(AST::PropertyAccessExpression& propertyAccessExpression)
{
+ return anderCallArgument(propertyAccessExpression.baseReference(), propertyAccessExpression.anderFunction(), propertyAccessExpression.threadAnderFunction());
+}
+
+void PropertyResolver::simplifyRightValue(AST::PropertyAccessExpression& propertyAccessExpression)
+{
Lexer::Token origin = propertyAccessExpression.origin();
checkErrorAndVisit(propertyAccessExpression.base());
- auto& base = propertyAccessExpression.base();
- if (auto leftAddressSpace = base.typeAnnotation().leftAddressSpace()) {
- if (auto* anderFunction = propertyAccessExpression.anderFunction()) {
- auto makePointerExpression = makeUniqueRef<AST::MakePointerExpression>(Lexer::Token(origin), propertyAccessExpression.takeBase());
- makePointerExpression->setType(makeUniqueRef<AST::PointerType>(Lexer::Token(origin), *leftAddressSpace, base.resolvedType().clone()));
- makePointerExpression->setTypeAnnotation(AST::RightValue());
-
- Vector<UniqueRef<AST::_expression_>> arguments;
- arguments.append(WTFMove(makePointerExpression));
- if (is<AST::IndexExpression>(propertyAccessExpression))
- arguments.append(downcast<AST::IndexExpression>(propertyAccessExpression).takeIndex());
- auto callExpression = makeUniqueRef<AST::CallExpression>(Lexer::Token(origin), String(anderFunction->name()), WTFMove(arguments));
- callExpression->setType(anderFunction->type().clone());
- callExpression->setTypeAnnotation(AST::RightValue());
- callExpression->setFunction(*anderFunction);
-
- auto* dereferenceExpression = AST::replaceWith<AST::DereferenceExpression>(propertyAccessExpression, WTFMove(origin), WTFMove(callExpression));
- dereferenceExpression->setType(downcast<AST::PointerType>(anderFunction->type()).elementType().clone());
- dereferenceExpression->setTypeAnnotation(AST::LeftValue { downcast<AST::PointerType>(anderFunction->type()).addressSpace() });
- return true;
- }
- }
-
- if (propertyAccessExpression.getterFunction()) {
- auto& getterFunction = *propertyAccessExpression.getterFunction();
+ if (auto argument = anderCallArgument(propertyAccessExpression)) {
+ auto* anderFunction = argument->whichAnder == WhichAnder::ThreadAnder ? propertyAccessExpression.threadAnderFunction() : propertyAccessExpression.anderFunction();
+ ASSERT(anderFunction);
+ auto origin = propertyAccessExpression.origin();
Vector<UniqueRef<AST::_expression_>> arguments;
- arguments.append(propertyAccessExpression.takeBase());
+ arguments.append(WTFMove(argument->_expression_));
if (is<AST::IndexExpression>(propertyAccessExpression))
arguments.append(downcast<AST::IndexExpression>(propertyAccessExpression).takeIndex());
- auto* callExpression = AST::replaceWith<AST::CallExpression>(propertyAccessExpression, WTFMove(origin), String(getterFunction.name()), WTFMove(arguments));
- callExpression->setFunction(getterFunction);
- callExpression->setType(getterFunction.type().clone());
+ auto callExpression = makeUniqueRef<AST::CallExpression>(Lexer::Token(origin), String(anderFunction->name()), WTFMove(arguments));
+ callExpression->setType(anderFunction->type().clone());
callExpression->setTypeAnnotation(AST::RightValue());
- return true;
- }
+ callExpression->setFunction(*anderFunction);
- // We have an ander, but no left value to call it on. Let's save the value into a temporary variable to create a left value.
- // This is effectively inlining the functions the spec says are generated.
- ASSERT(propertyAccessExpression.threadAnderFunction());
- auto* threadAnderFunction = propertyAccessExpression.threadAnderFunction();
+ auto* dereferenceExpression = AST::replaceWith<AST::DereferenceExpression>(propertyAccessExpression, WTFMove(origin), WTFMove(callExpression));
+ dereferenceExpression->setType(downcast<AST::PointerType>(anderFunction->type()).elementType().clone());
+ dereferenceExpression->setTypeAnnotation(AST::LeftValue { downcast<AST::PointerType>(anderFunction->type()).addressSpace() });
- auto variableDeclaration = makeUniqueRef<AST::VariableDeclaration>(Lexer::Token(origin), AST::Qualifiers(), base.resolvedType().clone(), String(), WTF::nullopt, WTF::nullopt);
+ if (auto& variableDeclaration = argument->variableDeclaration)
+ m_variableDeclarations.append(WTFMove(*variableDeclaration));
- auto variableReference1 = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(variableDeclaration));
- variableReference1->setType(base.resolvedType().clone());
- variableReference1->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread });
+ return;
+ }
- auto assignmentExpression = makeUniqueRef<AST::AssignmentExpression>(Lexer::Token(origin), WTFMove(variableReference1), propertyAccessExpression.takeBase());
- assignmentExpression->setType(base.resolvedType().clone());
- assignmentExpression->setTypeAnnotation(AST::RightValue());
-
- auto variableReference2 = makeUniqueRef<AST::VariableReference>(AST::VariableReference::wrap(variableDeclaration));
- variableReference2->setType(base.resolvedType().clone());
- variableReference2->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread });
-
- auto makePointerExpression = makeUniqueRef<AST::MakePointerExpression>(Lexer::Token(origin), WTFMove(variableReference2));
- makePointerExpression->setType(makeUniqueRef<AST::PointerType>(Lexer::Token(origin), AST::AddressSpace::Thread, base.resolvedType().clone()));
- makePointerExpression->setTypeAnnotation(AST::RightValue());
-
+ ASSERT(propertyAccessExpression.getterFunction());
+ auto& getterFunction = *propertyAccessExpression.getterFunction();
Vector<UniqueRef<AST::_expression_>> arguments;
- arguments.append(WTFMove(makePointerExpression));
+ arguments.append(propertyAccessExpression.takeBase());
if (is<AST::IndexExpression>(propertyAccessExpression))
arguments.append(downcast<AST::IndexExpression>(propertyAccessExpression).takeIndex());
- auto callExpression = makeUniqueRef<AST::CallExpression>(Lexer::Token(origin), String(threadAnderFunction->name()), WTFMove(arguments));
- callExpression->setType(threadAnderFunction->type().clone());
+ auto* callExpression = AST::replaceWith<AST::CallExpression>(propertyAccessExpression, WTFMove(origin), String(getterFunction.name()), WTFMove(arguments));
+ callExpression->setFunction(getterFunction);
+ callExpression->setType(getterFunction.type().clone());
callExpression->setTypeAnnotation(AST::RightValue());
- callExpression->setFunction(*threadAnderFunction);
-
- auto dereferenceExpression = makeUniqueRef<AST::DereferenceExpression>(WTFMove(origin), WTFMove(callExpression));
- dereferenceExpression->setType(downcast<AST::PointerType>(threadAnderFunction->type()).elementType().clone());
- dereferenceExpression->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread });
-
- Vector<UniqueRef<AST::_expression_>> expressions;
- expressions.append(WTFMove(assignmentExpression));
- expressions.append(WTFMove(dereferenceExpression));
- auto* commaExpression = AST::replaceWith<AST::CommaExpression>(propertyAccessExpression, WTFMove(origin), WTFMove(expressions));
- commaExpression->setType(downcast<AST::PointerType>(threadAnderFunction->type()).elementType().clone());
- commaExpression->setTypeAnnotation(AST::LeftValue { AST::AddressSpace::Thread });
-
- m_variableDeclarations.append(WTFMove(variableDeclaration));
- return true;
-
}
class LeftValueSimplifier : public Visitor {
@@ -777,14 +776,14 @@
Lexer::Token origin = propertyAccessExpression.origin();
auto* anderFunction = propertyAccessExpression.anderFunction();
- auto& base = propertyAccessExpression.base();
- auto leftAddressSpace = *propertyAccessExpression.base().typeAnnotation().leftAddressSpace();
- auto makePointerExpression = makeUniqueRef<AST::MakePointerExpression>(Lexer::Token(origin), propertyAccessExpression.takeBase());
- makePointerExpression->setType(makeUniqueRef<AST::PointerType>(Lexer::Token(origin), leftAddressSpace, base.resolvedType().clone()));
- makePointerExpression->setTypeAnnotation(AST::RightValue());
+ auto argument = anderCallArgument(propertyAccessExpression);
+ ASSERT(argument);
+ ASSERT(!argument->variableDeclaration);
+ ASSERT(argument->whichAnder == WhichAnder::Ander);
+
Vector<UniqueRef<AST::_expression_>> arguments;
- arguments.append(WTFMove(makePointerExpression));
+ arguments.append(WTFMove(argument->_expression_));
if (is<AST::IndexExpression>(propertyAccessExpression))
arguments.append(downcast<AST::IndexExpression>(propertyAccessExpression).takeIndex());
auto callExpression = makeUniqueRef<AST::CallExpression>(Lexer::Token(origin), String(anderFunction->name()), WTFMove(arguments));
Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSemanticMatcher.cpp (246393 => 246394)
--- trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSemanticMatcher.cpp 2019-06-13 05:10:11 UTC (rev 246393)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLSemanticMatcher.cpp 2019-06-13 05:38:28 UTC (rev 246394)
@@ -55,19 +55,17 @@
return &*iterator;
};
-static bool matchMode(BindingType bindingType, AST::ResourceSemantic::Mode mode)
+static bool matchMode(Binding::BindingDetails bindingType, AST::ResourceSemantic::Mode mode)
{
- switch (bindingType) {
- case BindingType::UniformBuffer:
+ return WTF::visit(WTF::makeVisitor([&](UniformBufferBinding) -> bool {
return mode == AST::ResourceSemantic::Mode::Buffer;
- case BindingType::Sampler:
+ }, [&](SamplerBinding) -> bool {
return mode == AST::ResourceSemantic::Mode::Sampler;
- case BindingType::Texture:
+ }, [&](TextureBinding) -> bool {
return mode == AST::ResourceSemantic::Mode::Texture;
- default:
- ASSERT(bindingType == BindingType::StorageBuffer);
+ }, [&](StorageBufferBinding) -> bool {
return mode == AST::ResourceSemantic::Mode::UnorderedAccessView;
- }
+ }), bindingType);
}
static Optional<HashMap<Binding*, size_t>> matchResources(Vector<EntryPointItem>& entryPointItems, Layout& layout, ShaderStage shaderStage)
@@ -87,9 +85,9 @@
if (!WTF::holds_alternative<AST::ResourceSemantic>(semantic))
continue;
auto& resourceSemantic = WTF::get<AST::ResourceSemantic>(semantic);
- if (!matchMode(binding.bindingType, resourceSemantic.mode()))
+ if (!matchMode(binding.binding, resourceSemantic.mode()))
continue;
- if (binding.name != resourceSemantic.index())
+ if (binding.externalName != resourceSemantic.index())
continue;
if (space != resourceSemantic.space())
continue;
Modified: trunk/Source/WebCore/Modules/webgpu/WebGPUBindGroupDescriptor.cpp (246393 => 246394)
--- trunk/Source/WebCore/Modules/webgpu/WebGPUBindGroupDescriptor.cpp 2019-06-13 05:10:11 UTC (rev 246393)
+++ trunk/Source/WebCore/Modules/webgpu/WebGPUBindGroupDescriptor.cpp 2019-06-13 05:38:28 UTC (rev 246394)
@@ -111,7 +111,7 @@
if (!buffer)
return WTF::nullopt;
- if (!validateBufferBindingType(buffer, layoutBinding, functionName))
+ if (!validateBufferBindingType(buffer, layoutBinding.externalBinding, functionName))
return WTF::nullopt;
return static_cast<GPUBindingResource>(GPUBufferBinding { makeRef(*buffer), bufferBinding.offset, bufferBinding.size });
@@ -119,7 +119,7 @@
auto bindingResource = WTF::visit(bindingResourceVisitor, binding.resource);
if (!bindingResource) {
- LOG(WebGPU, "%s: Invalid resource for binding %u!", functionName, layoutBinding.binding);
+ LOG(WebGPU, "%s: Invalid resource for binding %u!", functionName, layoutBinding.externalBinding.binding);
return WTF::nullopt;
}
Modified: trunk/Source/WebCore/platform/graphics/gpu/GPUBindGroupLayout.h (246393 => 246394)
--- trunk/Source/WebCore/platform/graphics/gpu/GPUBindGroupLayout.h 2019-06-13 05:10:11 UTC (rev 246393)
+++ trunk/Source/WebCore/platform/graphics/gpu/GPUBindGroupLayout.h 2019-06-13 05:38:28 UTC (rev 246394)
@@ -33,6 +33,7 @@
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
#include <wtf/RetainPtr.h>
+#include <wtf/Variant.h>
#if USE(METAL)
OBJC_PROTOCOL(MTLArgumentEncoder);
@@ -47,7 +48,37 @@
public:
static RefPtr<GPUBindGroupLayout> tryCreate(const GPUDevice&, const GPUBindGroupLayoutDescriptor&);
- using BindingsMapType = HashMap<uint64_t, GPUBindGroupLayoutBinding, WTF::IntHash<uint64_t>, WTF::UnsignedWithZeroKeyHashTraits<uint64_t>>;
+ struct UniformBuffer {
+ unsigned internalLengthName;
+ };
+
+ struct DynamicUniformBuffer {
+ unsigned internalLengthName;
+ };
+
+ struct Sampler {
+ };
+
+ struct SampledTexture {
+ };
+
+ struct StorageBuffer {
+ unsigned internalLengthName;
+ };
+
+ struct DynamicStorageBuffer {
+ unsigned internalLengthName;
+ };
+
+ using InternalBindingDetails = Variant<UniformBuffer, DynamicUniformBuffer, Sampler, SampledTexture, StorageBuffer, DynamicStorageBuffer>;
+
+ struct Binding {
+ GPUBindGroupLayoutBinding externalBinding;
+ unsigned internalName;
+ InternalBindingDetails internalBindingDetails;
+ };
+
+ using BindingsMapType = HashMap<uint64_t, Binding, WTF::IntHash<uint64_t>, WTF::UnsignedWithZeroKeyHashTraits<uint64_t>>;
const BindingsMapType& bindingsMap() const { return m_bindingsMap; }
#if USE(METAL)
MTLArgumentEncoder *vertexEncoder() const { return m_vertexEncoder.get(); }
Modified: trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUBindGroupLayoutMetal.mm (246393 => 246394)
--- trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUBindGroupLayoutMetal.mm 2019-06-13 05:10:11 UTC (rev 246393)
+++ trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUBindGroupLayoutMetal.mm 2019-06-13 05:38:28 UTC (rev 246394)
@@ -77,6 +77,18 @@
return encoder;
};
+static RetainPtr<MTLArgumentDescriptor> argumentDescriptor(MTLDataType dataType, NSUInteger index)
+{
+ RetainPtr<MTLArgumentDescriptor> mtlArgument;
+ BEGIN_BLOCK_OBJC_EXCEPTIONS;
+ mtlArgument = adoptNS([MTLArgumentDescriptor new]);
+ END_BLOCK_OBJC_EXCEPTIONS;
+
+ [mtlArgument setDataType:dataType];
+ [mtlArgument setIndex:index];
+ return mtlArgument;
+}
+
RefPtr<GPUBindGroupLayout> GPUBindGroupLayout::tryCreate(const GPUDevice& device, const GPUBindGroupLayoutDescriptor& descriptor)
{
if (!device.platformDevice()) {
@@ -87,48 +99,73 @@
ArgumentArray vertexArgsArray, fragmentArgsArray, computeArgsArray;
BindingsMapType bindingsMap;
+ unsigned internalName = 0;
+ unsigned internalLengthBase = descriptor.bindings.size();
for (const auto& binding : descriptor.bindings) {
- if (!bindingsMap.add(binding.binding, binding)) {
+ Optional<unsigned> extraIndex;
+ auto internalDetails = ([&]() -> GPUBindGroupLayout::InternalBindingDetails {
+ switch (binding.type) {
+ case GPUBindingType::UniformBuffer:
+ extraIndex = internalLengthBase++;
+ return GPUBindGroupLayout::UniformBuffer { *extraIndex };
+ case GPUBindingType::DynamicUniformBuffer:
+ extraIndex = internalLengthBase++;
+ return GPUBindGroupLayout::DynamicUniformBuffer { *extraIndex };
+ case GPUBindingType::Sampler:
+ return GPUBindGroupLayout::Sampler { };
+ case GPUBindingType::SampledTexture:
+ return GPUBindGroupLayout::SampledTexture { };
+ case GPUBindingType::StorageBuffer:
+ extraIndex = internalLengthBase++;
+ return GPUBindGroupLayout::StorageBuffer { *extraIndex };
+ default:
+ ASSERT(binding.type == GPUBindingType::DynamicStorageBuffer);
+ extraIndex = internalLengthBase++;
+ return GPUBindGroupLayout::DynamicStorageBuffer { *extraIndex };
+ }
+ })();
+ Binding bindingDetails = { binding, internalName++, WTFMove(internalDetails) };
+ if (!bindingsMap.add(binding.binding, bindingDetails)) {
LOG(WebGPU, "GPUBindGroupLayout::tryCreate(): Duplicate binding %u found in GPUBindGroupLayoutDescriptor!", binding.binding);
return nullptr;
}
- RetainPtr<MTLArgumentDescriptor> mtlArgument;
+ RetainPtr<MTLArgumentDescriptor> mtlArgument = argumentDescriptor(MTLDataTypeForBindingType(binding.type), bindingDetails.internalName);
- BEGIN_BLOCK_OBJC_EXCEPTIONS;
- mtlArgument = adoptNS([MTLArgumentDescriptor new]);
- END_BLOCK_OBJC_EXCEPTIONS;
if (!mtlArgument) {
LOG(WebGPU, "GPUBindGroupLayout::tryCreate(): Unable to create MTLArgumentDescriptor for binding %u!", binding.binding);
return nullptr;
}
- [mtlArgument setDataType:MTLDataTypeForBindingType(binding.type)];
- [mtlArgument setIndex:binding.binding];
-
- if (binding.visibility & GPUShaderStageBit::Flags::Vertex)
- appendArgumentToArray(vertexArgsArray, mtlArgument);
- if (binding.visibility & GPUShaderStageBit::Flags::Fragment)
- appendArgumentToArray(fragmentArgsArray, mtlArgument);
- if (binding.visibility & GPUShaderStageBit::Flags::Compute)
- appendArgumentToArray(computeArgsArray, mtlArgument);
- }
-
- RetainPtr<MTLArgumentEncoder> vertex, fragment, compute;
-
- if (vertexArgsArray) {
- if (!(vertex = tryCreateMtlArgumentEncoder(device, vertexArgsArray)))
+ auto addIndices = [&](ArgumentArray& array) -> bool {
+ appendArgumentToArray(array, mtlArgument);
+ if (extraIndex) {
+ RetainPtr<MTLArgumentDescriptor> mtlArgument = argumentDescriptor(MTLDataTypeUInt2, *extraIndex);
+ if (!mtlArgument) {
+ LOG(WebGPU, "GPUBindGroupLayout::tryCreate(): Unable to create MTLArgumentDescriptor for binding %u!", binding.binding);
+ return false;
+ }
+ appendArgumentToArray(array, mtlArgument);
+ }
+ return true;
+ };
+ if ((binding.visibility & GPUShaderStageBit::Flags::Vertex) && !addIndices(vertexArgsArray))
return nullptr;
- }
- if (fragmentArgsArray) {
- if (!(fragment = tryCreateMtlArgumentEncoder(device, fragmentArgsArray)))
+ if ((binding.visibility & GPUShaderStageBit::Flags::Fragment) && !addIndices(fragmentArgsArray))
return nullptr;
- }
- if (computeArgsArray) {
- if (!(compute = tryCreateMtlArgumentEncoder(device, computeArgsArray)))
+ if ((binding.visibility & GPUShaderStageBit::Flags::Compute) && !addIndices(computeArgsArray))
return nullptr;
}
+ RetainPtr<MTLArgumentEncoder> vertex, fragment, compute;
+
+ if (vertexArgsArray && !(vertex = tryCreateMtlArgumentEncoder(device, vertexArgsArray)))
+ return nullptr;
+ if (fragmentArgsArray && !(fragment = tryCreateMtlArgumentEncoder(device, fragmentArgsArray)))
+ return nullptr;
+ if (computeArgsArray && !(compute = tryCreateMtlArgumentEncoder(device, computeArgsArray)))
+ return nullptr;
+
return adoptRef(new GPUBindGroupLayout(WTFMove(bindingsMap), WTFMove(vertex), WTFMove(fragment), WTFMove(compute)));
}
Modified: trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUBindGroupMetal.mm (246393 => 246394)
--- trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUBindGroupMetal.mm 2019-06-13 05:10:11 UTC (rev 246393)
+++ trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPUBindGroupMetal.mm 2019-06-13 05:38:28 UTC (rev 246394)
@@ -72,13 +72,15 @@
return GPUBufferBinding { bufferBinding.buffer.copyRef(), bufferBinding.offset, bufferBinding.size };
}
-static void setBufferOnEncoder(MTLArgumentEncoder *argumentEncoder, const GPUBufferBinding& bufferBinding, unsigned index)
+static void setBufferOnEncoder(MTLArgumentEncoder *argumentEncoder, const GPUBufferBinding& bufferBinding, unsigned name, unsigned lengthName)
{
ASSERT(argumentEncoder && bufferBinding.buffer->platformBuffer());
BEGIN_BLOCK_OBJC_EXCEPTIONS;
// Bounds check when converting GPUBufferBinding ensures that NSUInteger cast of uint64_t offset is safe.
- [argumentEncoder setBuffer:bufferBinding.buffer->platformBuffer() offset:static_cast<NSUInteger>(bufferBinding.offset) atIndex:index];
+ [argumentEncoder setBuffer:bufferBinding.buffer->platformBuffer() offset:static_cast<NSUInteger>(bufferBinding.offset) atIndex:name];
+ void* lengthPointer = [argumentEncoder constantDataAtIndex:lengthName];
+ memcpy(lengthPointer, &bufferBinding.size, sizeof(uint64_t));
END_BLOCK_OBJC_EXCEPTIONS;
}
@@ -171,12 +173,12 @@
return nullptr;
}
auto layoutBinding = layoutIterator->value;
- if (layoutBinding.visibility == GPUShaderStageBit::Flags::None)
+ if (layoutBinding.externalBinding.visibility == GPUShaderStageBit::Flags::None)
continue;
- bool isForVertex = layoutBinding.visibility & GPUShaderStageBit::Flags::Vertex;
- bool isForFragment = layoutBinding.visibility & GPUShaderStageBit::Flags::Fragment;
- bool isForCompute = layoutBinding.visibility & GPUShaderStageBit::Flags::Compute;
+ bool isForVertex = layoutBinding.externalBinding.visibility & GPUShaderStageBit::Flags::Vertex;
+ bool isForFragment = layoutBinding.externalBinding.visibility & GPUShaderStageBit::Flags::Fragment;
+ bool isForCompute = layoutBinding.externalBinding.visibility & GPUShaderStageBit::Flags::Compute;
if (isForVertex && !vertexEncoder) {
LOG(WebGPU, "%s: No vertex argument encoder found for binding %u!", functionName, index);
@@ -191,27 +193,28 @@
return nullptr;
}
- switch (layoutBinding.type) {
- // FIXME: Support more resource types.
- // FIXME: We could avoid this ugly switch-on-type using virtual functions if GPUBindingResource is refactored as a base class rather than a Variant.
- case GPUBindingType::UniformBuffer:
- case GPUBindingType::StorageBuffer: {
+ auto handleBuffer = [&](unsigned internalLengthName) -> bool {
auto bufferResource = tryGetResourceAsBufferBinding(resourceBinding.resource, functionName);
if (!bufferResource)
- return nullptr;
+ return false;
if (isForVertex)
- setBufferOnEncoder(vertexEncoder, *bufferResource, index);
+ setBufferOnEncoder(vertexEncoder, *bufferResource, layoutBinding.internalName, internalLengthName);
if (isForFragment)
- setBufferOnEncoder(fragmentEncoder, *bufferResource, index);
+ setBufferOnEncoder(fragmentEncoder, *bufferResource, layoutBinding.internalName, internalLengthName);
if (isForCompute)
- setBufferOnEncoder(computeEncoder, *bufferResource, index);
+ setBufferOnEncoder(computeEncoder, *bufferResource, layoutBinding.internalName, internalLengthName);
boundBuffers.append(bufferResource->buffer.copyRef());
- break;
- }
- case GPUBindingType::Sampler: {
+ return true;
+ };
+
+ auto success = WTF::visit(WTF::makeVisitor([&](GPUBindGroupLayout::UniformBuffer& uniformBuffer) -> bool {
+ return handleBuffer(uniformBuffer.internalLengthName);
+ }, [&](GPUBindGroupLayout::DynamicUniformBuffer& dynamicUniformBuffer) -> bool {
+ return handleBuffer(dynamicUniformBuffer.internalLengthName);
+ }, [&](GPUBindGroupLayout::Sampler&) -> bool {
auto samplerState = tryGetResourceAsMtlSampler(resourceBinding.resource, functionName);
if (!samplerState)
- return nullptr;
+ return false;
if (isForVertex)
setSamplerOnEncoder(vertexEncoder, samplerState, index);
if (isForFragment)
@@ -218,12 +221,11 @@
setSamplerOnEncoder(fragmentEncoder, samplerState, index);
if (isForCompute)
setSamplerOnEncoder(computeEncoder, samplerState, index);
- break;
- }
- case GPUBindingType::SampledTexture: {
+ return true;
+ }, [&](GPUBindGroupLayout::SampledTexture&) -> bool {
auto textureResource = tryGetResourceAsTexture(resourceBinding.resource, functionName);
if (!textureResource)
- return nullptr;
+ return false;
if (isForVertex)
setTextureOnEncoder(vertexEncoder, textureResource->platformTexture(), index);
if (isForFragment)
@@ -231,12 +233,14 @@
if (isForCompute)
setTextureOnEncoder(computeEncoder, textureResource->platformTexture(), index);
boundTextures.append(textureResource.releaseNonNull());
- break;
- }
- default:
- LOG(WebGPU, "%s: Resource type not yet implemented.", functionName);
+ return true;
+ }, [&](GPUBindGroupLayout::StorageBuffer& storageBuffer) -> bool {
+ return handleBuffer(storageBuffer.internalLengthName);
+ }, [&](GPUBindGroupLayout::DynamicStorageBuffer& dynamicStorageBuffer) -> bool {
+ return handleBuffer(dynamicStorageBuffer.internalLengthName);
+ }), layoutBinding.internalBindingDetails);
+ if (!success)
return nullptr;
- }
}
return adoptRef(new GPUBindGroup(WTFMove(vertexArgsBuffer), WTFMove(fragmentArgsBuffer), WTFMove(computeArgsBuffer), WTFMove(boundBuffers), WTFMove(boundTextures)));
Modified: trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPURenderPipelineMetal.mm (246393 => 246394)
--- trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPURenderPipelineMetal.mm 2019-06-13 05:10:11 UTC (rev 246393)
+++ trunk/Source/WebCore/platform/graphics/gpu/cocoa/GPURenderPipelineMetal.mm 2019-06-13 05:38:28 UTC (rev 246394)
@@ -110,20 +110,21 @@
return result;
}
-static Optional<WHLSL::BindingType> convertBindingType(GPUBindingType type)
+static Optional<WHLSL::Binding::BindingDetails> convertBindingType(GPUBindGroupLayout::InternalBindingDetails internalBindingDetails)
{
- switch (type) {
- case GPUBindingType::UniformBuffer:
- return WHLSL::BindingType::UniformBuffer;
- case GPUBindingType::Sampler:
- return WHLSL::BindingType::Sampler;
- case GPUBindingType::SampledTexture:
- return WHLSL::BindingType::Texture;
- case GPUBindingType::StorageBuffer:
- return WHLSL::BindingType::StorageBuffer;
- default:
+ return WTF::visit(WTF::makeVisitor([&](GPUBindGroupLayout::UniformBuffer uniformBuffer) -> Optional<WHLSL::Binding::BindingDetails> {
+ return { WHLSL::UniformBufferBinding { uniformBuffer.internalLengthName } };
+ }, [&](GPUBindGroupLayout::DynamicUniformBuffer) -> Optional<WHLSL::Binding::BindingDetails> {
return WTF::nullopt;
- }
+ }, [&](GPUBindGroupLayout::Sampler) -> Optional<WHLSL::Binding::BindingDetails> {
+ return { WHLSL::SamplerBinding { } };
+ }, [&](GPUBindGroupLayout::SampledTexture) -> Optional<WHLSL::Binding::BindingDetails> {
+ return { WHLSL::TextureBinding { } };
+ }, [&](GPUBindGroupLayout::StorageBuffer storageBuffer) -> Optional<WHLSL::Binding::BindingDetails> {
+ return { WHLSL::StorageBufferBinding { storageBuffer.internalLengthName } };
+ }, [&](GPUBindGroupLayout::DynamicStorageBuffer) -> Optional<WHLSL::Binding::BindingDetails> {
+ return WTF::nullopt;
+ }), internalBindingDetails);
}
static Optional<WHLSL::TextureFormat> convertTextureFormat(GPUTextureFormat format)
@@ -377,16 +378,17 @@
WHLSL::BindGroup bindGroup;
bindGroup.name = static_cast<unsigned>(i);
for (const auto& keyValuePair : bindGroupLayout->bindingsMap()) {
- const auto& gpuBindGroupLayoutBinding = keyValuePair.value;
+ const auto& bindingDetails = keyValuePair.value;
WHLSL::Binding binding;
- binding.visibility = convertShaderStageFlags(gpuBindGroupLayoutBinding.visibility);
- if (auto bindingType = convertBindingType(gpuBindGroupLayoutBinding.type))
- binding.bindingType = *bindingType;
+ binding.visibility = convertShaderStageFlags(bindingDetails.externalBinding.visibility);
+ if (auto bindingType = convertBindingType(bindingDetails.internalBindingDetails))
+ binding.binding = *bindingType;
else
return WTF::nullopt;
- if (gpuBindGroupLayoutBinding.binding > std::numeric_limits<unsigned>::max())
+ if (bindingDetails.externalBinding.binding > std::numeric_limits<unsigned>::max())
return WTF::nullopt;
- binding.name = static_cast<unsigned>(gpuBindGroupLayoutBinding.binding);
+ binding.externalName = bindingDetails.externalBinding.binding;
+ binding.internalName = bindingDetails.internalName;
bindGroup.bindings.append(WTFMove(binding));
}
result.append(WTFMove(bindGroup));