[WHLSL] Auto initialize local variables
authorsbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 10 Jun 2019 19:58:19 +0000 (19:58 +0000)
committersbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 10 Jun 2019 19:58:19 +0000 (19:58 +0000)
https://bugs.webkit.org/show_bug.cgi?id=198426

Reviewed by Myles Maxfield.

Source/WebCore:

This patch implements zero-filling for local variables in two parts:
1. We add a new pass, autoInitializeVariables, which makes any variable declaration
without an initializer call the default constructor for the variable's type.
Since we auto generate the default constructor, it's a native function whose
implementation we control.

2. Each native constructor is implemented as a memset(&value, sizeof(value), 0).
This memset is an inlined loop in each constructor. The reason this turns
everything into zero is that for every primitive type, the "zero" value is
represented as all zeroes in memory: float, int, pointers, etc.

Since our ability to test some of this is limited, I opened a follow-up bug to
test this more:
https://bugs.webkit.org/show_bug.cgi?id=198413

Tests: webgpu/whlsl-zero-initialize-values-2.html
       webgpu/whlsl-zero-initialize-values.html

* Modules/webgpu/WHLSL/AST/WHLSLVariableDeclaration.h:
(WebCore::WHLSL::AST::VariableDeclaration::setInitializer):
* Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp:
(WebCore::WHLSL::Metal::FunctionDefinitionWriter::visit):
* Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp:
(WebCore::WHLSL::Metal::writeNativeFunction):
* Modules/webgpu/WHLSL/WHLSLASTDumper.h:
* Modules/webgpu/WHLSL/WHLSLAutoInitializeVariables.cpp: Added.
(WebCore::WHLSL::AutoInitialize::AutoInitialize):
(WebCore::WHLSL::AutoInitialize::visit):
(WebCore::WHLSL::autoInitializeVariables):
* Modules/webgpu/WHLSL/WHLSLAutoInitializeVariables.h: Added.
* Modules/webgpu/WHLSL/WHLSLChecker.cpp:
(WebCore::WHLSL::checkOperatorOverload):
(WebCore::WHLSL::Checker::visit):
* Modules/webgpu/WHLSL/WHLSLInferTypes.cpp:
(WebCore::WHLSL::inferTypesForCallImpl):
(WebCore::WHLSL::inferTypesForCall):
* Modules/webgpu/WHLSL/WHLSLInferTypes.h:
* Modules/webgpu/WHLSL/WHLSLPrepare.cpp:
(WebCore::WHLSL::prepareShared):
* Modules/webgpu/WHLSL/WHLSLResolveOverloadImpl.cpp:
(WebCore::WHLSL::resolveFunctionOverloadImpl):
(WebCore::WHLSL::resolveFunctionOverload):
* Modules/webgpu/WHLSL/WHLSLResolveOverloadImpl.h:
* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:

LayoutTests:

* webgpu/whlsl-zero-initialize-values-2-expected.html: Added.
* webgpu/whlsl-zero-initialize-values-2.html: Added.
* webgpu/whlsl-zero-initialize-values-expected.html: Added.
* webgpu/whlsl-zero-initialize-values.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@246273 268f45cc-cd09-0410-ab3c-d52691b4dbfc

20 files changed:
LayoutTests/ChangeLog
LayoutTests/webgpu/whlsl-zero-initialize-values-2-expected.html [new file with mode: 0644]
LayoutTests/webgpu/whlsl-zero-initialize-values-2.html [new file with mode: 0644]
LayoutTests/webgpu/whlsl-zero-initialize-values-expected.html [new file with mode: 0644]
LayoutTests/webgpu/whlsl-zero-initialize-values.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLVariableDeclaration.h
Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp
Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLASTDumper.h
Source/WebCore/Modules/webgpu/WHLSL/WHLSLAutoInitializeVariables.cpp [new file with mode: 0644]
Source/WebCore/Modules/webgpu/WHLSL/WHLSLAutoInitializeVariables.h [new file with mode: 0644]
Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLInferTypes.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLInferTypes.h
Source/WebCore/Modules/webgpu/WHLSL/WHLSLPrepare.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLResolveOverloadImpl.cpp
Source/WebCore/Modules/webgpu/WHLSL/WHLSLResolveOverloadImpl.h
Source/WebCore/Sources.txt
Source/WebCore/WebCore.xcodeproj/project.pbxproj

index fc32a87..93e4a04 100644 (file)
@@ -1,3 +1,15 @@
+2019-06-10  Saam Barati  <sbarati@apple.com>
+
+        [WHLSL] Auto initialize local variables
+        https://bugs.webkit.org/show_bug.cgi?id=198426
+
+        Reviewed by Myles Maxfield.
+
+        * webgpu/whlsl-zero-initialize-values-2-expected.html: Added.
+        * webgpu/whlsl-zero-initialize-values-2.html: Added.
+        * webgpu/whlsl-zero-initialize-values-expected.html: Added.
+        * webgpu/whlsl-zero-initialize-values.html: Added.
+
 2019-06-10  Timothy Hatcher  <timothy@apple.com>
 
         Integrate dark mode support for iOS.
diff --git a/LayoutTests/webgpu/whlsl-zero-initialize-values-2-expected.html b/LayoutTests/webgpu/whlsl-zero-initialize-values-2-expected.html
new file mode 100644 (file)
index 0000000..ca6e692
--- /dev/null
@@ -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 = "black";
+    context.fillRect(100, 100, 200, 200);
+}
+window.addEventListener("load", start);
+</script>
+</body>
+</html>
diff --git a/LayoutTests/webgpu/whlsl-zero-initialize-values-2.html b/LayoutTests/webgpu/whlsl-zero-initialize-values-2.html
new file mode 100644 (file)
index 0000000..8065b9b
--- /dev/null
@@ -0,0 +1,152 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+<canvas id="canvas" width="400" height="400"></canvas>
+<script>
+const shaderSource = `
+struct VertexOut {
+    float4 position : SV_Position;
+    float shade : attribute(0);
+}
+
+struct Bar {
+    float y;
+    float y1;
+    float y2;
+    float y3;
+    float y4;
+    float y5;
+    float y6;
+    float y7;
+    float y8;
+    float y9;
+    float y10;
+    float y11;
+    float y12;
+    float y13;
+    float y14;
+    float y15;
+    float y16;
+    float y17;
+    float y18;
+    float y19;
+    float y20;
+}
+
+vertex VertexOut vertexShader(float4 position : attribute(0), float shade : attribute(1)) {
+    VertexOut result;
+
+    Bar bar;
+
+    result.position = position;
+    result.shade = bar.y20;
+
+    return result;
+}
+
+fragment float4 fragmentShader(float shade : attribute(0)) : SV_Target 0 {
+    return float4(shade, shade, shade, 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", offset: 0};
+    const attribute1 = {shaderLocation: 1, format: "float", offset: 16};
+    const attributes = [attribute0, attribute1];
+    const input0 = {stride: 20, attributeSet: attributes};
+    const inputs = [input0];
+    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 * 5 * 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.0;
+    vertexBuffer0Float32Array[4] = 1.0;
+
+    vertexBuffer0Float32Array[5] = -0.5;
+    vertexBuffer0Float32Array[6] = 0.5;
+    vertexBuffer0Float32Array[7] = 1.0;
+    vertexBuffer0Float32Array[8] = 1.0;
+    vertexBuffer0Float32Array[9] = 1.0;
+
+    vertexBuffer0Float32Array[10] = 0.5;
+    vertexBuffer0Float32Array[11] = -0.5;
+    vertexBuffer0Float32Array[12] = 1.0;
+    vertexBuffer0Float32Array[13] = 1.0;
+    vertexBuffer0Float32Array[14] = 1.0;
+
+    vertexBuffer0Float32Array[15] = 0.5;
+    vertexBuffer0Float32Array[16] = 0.5;
+    vertexBuffer0Float32Array[17] = 1.0;
+    vertexBuffer0Float32Array[18] = 1.0;
+    vertexBuffer0Float32Array[19] = 1.0;
+    vertexBuffer0.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], [0]);
+    renderPassEncoder.draw(4, 1, 0, 0);
+    renderPassEncoder.endPass();
+    const commandBuffer = commandEncoder.finish();
+    device.getQueue().submit([commandBuffer]);
+
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+if (window.testRunner)
+    testRunner.waitUntilDone();
+window.addEventListener("load", start);
+</script>
+</body>
+</html>
diff --git a/LayoutTests/webgpu/whlsl-zero-initialize-values-expected.html b/LayoutTests/webgpu/whlsl-zero-initialize-values-expected.html
new file mode 100644 (file)
index 0000000..ca6e692
--- /dev/null
@@ -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 = "black";
+    context.fillRect(100, 100, 200, 200);
+}
+window.addEventListener("load", start);
+</script>
+</body>
+</html>
diff --git a/LayoutTests/webgpu/whlsl-zero-initialize-values.html b/LayoutTests/webgpu/whlsl-zero-initialize-values.html
new file mode 100644 (file)
index 0000000..bcc50d8
--- /dev/null
@@ -0,0 +1,135 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+<canvas id="canvas" width="400" height="400"></canvas>
+<script>
+const shaderSource = `
+struct VertexOut {
+    float4 position : SV_Position;
+    float shade : attribute(0);
+}
+
+thread float* ptr() {
+    float local;
+    return &local;
+}
+
+vertex VertexOut vertexShader(float4 position : attribute(0), float shade : attribute(1)) {
+    VertexOut result;
+
+    thread float* p = ptr();
+    *p = 1.0;
+    float value = *ptr(); // calling ptr() zero initializes.
+
+    result.position = position;
+    result.shade = value;
+
+    return result;
+}
+
+fragment float4 fragmentShader(float shade : attribute(0)) : SV_Target 0 {
+    return float4(shade, shade, shade, 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", offset: 0};
+    const attribute1 = {shaderLocation: 1, format: "float", offset: 16};
+    const attributes = [attribute0, attribute1];
+    const input0 = {stride: 20, attributeSet: attributes};
+    const inputs = [input0];
+    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 * 5 * 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.0;
+    vertexBuffer0Float32Array[4] = 1.0;
+
+    vertexBuffer0Float32Array[5] = -0.5;
+    vertexBuffer0Float32Array[6] = 0.5;
+    vertexBuffer0Float32Array[7] = 1.0;
+    vertexBuffer0Float32Array[8] = 1.0;
+    vertexBuffer0Float32Array[9] = 1.0;
+
+    vertexBuffer0Float32Array[10] = 0.5;
+    vertexBuffer0Float32Array[11] = -0.5;
+    vertexBuffer0Float32Array[12] = 1.0;
+    vertexBuffer0Float32Array[13] = 1.0;
+    vertexBuffer0Float32Array[14] = 1.0;
+
+    vertexBuffer0Float32Array[15] = 0.5;
+    vertexBuffer0Float32Array[16] = 0.5;
+    vertexBuffer0Float32Array[17] = 1.0;
+    vertexBuffer0Float32Array[18] = 1.0;
+    vertexBuffer0Float32Array[19] = 1.0;
+    vertexBuffer0.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], [0]);
+    renderPassEncoder.draw(4, 1, 0, 0);
+    renderPassEncoder.endPass();
+    const commandBuffer = commandEncoder.finish();
+    device.getQueue().submit([commandBuffer]);
+
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+if (window.testRunner)
+    testRunner.waitUntilDone();
+window.addEventListener("load", start);
+</script>
+</body>
+</html>
index 76e7949..ce5fb1e 100644 (file)
@@ -1,3 +1,56 @@
+2019-06-10  Saam Barati  <sbarati@apple.com>
+
+        [WHLSL] Auto initialize local variables
+        https://bugs.webkit.org/show_bug.cgi?id=198426
+
+        Reviewed by Myles Maxfield.
+
+        This patch implements zero-filling for local variables in two parts:
+        1. We add a new pass, autoInitializeVariables, which makes any variable declaration
+        without an initializer call the default constructor for the variable's type.
+        Since we auto generate the default constructor, it's a native function whose
+        implementation we control.
+        
+        2. Each native constructor is implemented as a memset(&value, sizeof(value), 0).
+        This memset is an inlined loop in each constructor. The reason this turns
+        everything into zero is that for every primitive type, the "zero" value is
+        represented as all zeroes in memory: float, int, pointers, etc.
+        
+        Since our ability to test some of this is limited, I opened a follow-up bug to
+        test this more:
+        https://bugs.webkit.org/show_bug.cgi?id=198413
+
+        Tests: webgpu/whlsl-zero-initialize-values-2.html
+               webgpu/whlsl-zero-initialize-values.html
+
+        * Modules/webgpu/WHLSL/AST/WHLSLVariableDeclaration.h:
+        (WebCore::WHLSL::AST::VariableDeclaration::setInitializer):
+        * Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp:
+        (WebCore::WHLSL::Metal::FunctionDefinitionWriter::visit):
+        * Modules/webgpu/WHLSL/Metal/WHLSLNativeFunctionWriter.cpp:
+        (WebCore::WHLSL::Metal::writeNativeFunction):
+        * Modules/webgpu/WHLSL/WHLSLASTDumper.h:
+        * Modules/webgpu/WHLSL/WHLSLAutoInitializeVariables.cpp: Added.
+        (WebCore::WHLSL::AutoInitialize::AutoInitialize):
+        (WebCore::WHLSL::AutoInitialize::visit):
+        (WebCore::WHLSL::autoInitializeVariables):
+        * Modules/webgpu/WHLSL/WHLSLAutoInitializeVariables.h: Added.
+        * Modules/webgpu/WHLSL/WHLSLChecker.cpp:
+        (WebCore::WHLSL::checkOperatorOverload):
+        (WebCore::WHLSL::Checker::visit):
+        * Modules/webgpu/WHLSL/WHLSLInferTypes.cpp:
+        (WebCore::WHLSL::inferTypesForCallImpl):
+        (WebCore::WHLSL::inferTypesForCall):
+        * Modules/webgpu/WHLSL/WHLSLInferTypes.h:
+        * Modules/webgpu/WHLSL/WHLSLPrepare.cpp:
+        (WebCore::WHLSL::prepareShared):
+        * Modules/webgpu/WHLSL/WHLSLResolveOverloadImpl.cpp:
+        (WebCore::WHLSL::resolveFunctionOverloadImpl):
+        (WebCore::WHLSL::resolveFunctionOverload):
+        * Modules/webgpu/WHLSL/WHLSLResolveOverloadImpl.h:
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+
 2019-06-10  Timothy Hatcher  <timothy@apple.com>
 
         Integrate dark mode support for iOS.
index d3c64a3..9f8d99b 100644 (file)
@@ -70,6 +70,11 @@ public:
     Expression* initializer() { return m_initializer ? &*m_initializer : nullptr; }
     bool isAnonymous() const { return m_name.isNull(); }
     Optional<UniqueRef<Expression>> takeInitializer() { return WTFMove(m_initializer); }
+    void setInitializer(UniqueRef<Expression> expression)
+    {
+        ASSERT(!initializer());
+        m_initializer = WTFMove(expression);
+    }
 
 private:
     Qualifiers m_qualifiers;
index 44d2b1e..c02cbc5 100644 (file)
@@ -477,10 +477,8 @@ void FunctionDefinitionWriter::visit(AST::VariableDeclaration& variableDeclarati
     if (variableDeclaration.initializer()) {
         checkErrorAndVisit(*variableDeclaration.initializer());
         m_stringBuilder.append(makeString(m_typeNamer.mangledNameForType(*variableDeclaration.type()), ' ', variableName, " = ", m_stack.takeLast(), ";\n"));
-    } else {
-        // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195771 Zero-fill the variable.
+    } else
         m_stringBuilder.append(makeString(m_typeNamer.mangledNameForType(*variableDeclaration.type()), ' ', variableName, ";\n"));
-    }
 }
 
 void FunctionDefinitionWriter::visit(AST::AssignmentExpression& assignmentExpression)
index 38e7a71..e6c9e40 100644 (file)
@@ -104,7 +104,8 @@ String writeNativeFunction(AST::NativeFunctionDeclaration& nativeFunctionDeclara
         if (!nativeFunctionDeclaration.parameters().size()) {
             stringBuilder.append(makeString(metalReturnName, ' ', outputFunctionName, "() {\n"));
             stringBuilder.append(makeString("    ", metalReturnName, " x;\n"));
-            // FIXME: https://bugs.webkit.org/show_bug.cgi?id=195771 Zero-fill
+            stringBuilder.append("    thread char* ptr = static_cast<thread char*>(static_cast<thread void*>(&x));\n");
+            stringBuilder.append(makeString("    for (size_t i = 0; i < sizeof(", metalReturnName, "); ++i) ptr[i] = 0;\n"));
             stringBuilder.append("    return x;\n");
             stringBuilder.append("}\n");
             return stringBuilder.toString();
index 93eccd2..94a624d 100644 (file)
@@ -142,6 +142,7 @@ MAKE_PRINT_ADAPTOR(StatementDumper, AST::Statement&, dumpASTNode);
 MAKE_PRINT_ADAPTOR(ProgramDumper, Program&, dumpASTNode);
 MAKE_PRINT_ADAPTOR(StructureDefinitionDumper, AST::StructureDefinition&, dumpASTNode);
 MAKE_PRINT_ADAPTOR(FunctionDefinitionDumper, AST::FunctionDefinition&, dumpASTNode);
+MAKE_PRINT_ADAPTOR(TypeDumper, AST::UnnamedType&, dumpASTNode);
 
 
 static ALWAYS_INLINE void dumpAST(Program& program)
diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLAutoInitializeVariables.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLAutoInitializeVariables.cpp
new file mode 100644 (file)
index 0000000..b22957a
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WHLSLAutoInitializeVariables.h"
+
+#if ENABLE(WEBGPU)
+
+#include "WHLSLAST.h"
+#include "WHLSLASTDumper.h"
+#include "WHLSLNameContext.h"
+#include "WHLSLResolveOverloadImpl.h"
+#include "WHLSLResolvingType.h"
+#include "WHLSLVisitor.h"
+#include <wtf/StringPrintStream.h>
+
+namespace WebCore {
+
+namespace WHLSL {
+
+class AutoInitialize : public Visitor {
+    using Base = Visitor;
+public:
+    AutoInitialize(NameContext& nameContext)
+        : m_nameContext(nameContext)
+        , m_castFunctions(*m_nameContext.getFunctions("operator cast"_str))
+    { }
+
+private:
+    void visit(AST::FunctionDeclaration&)
+    {
+        // Skip argument declarations.
+    }
+
+    void visit(AST::VariableDeclaration& variableDeclaration)
+    {
+        if (variableDeclaration.initializer())
+            return;
+
+        AST::UnnamedType* type = variableDeclaration.type();
+        RELEASE_ASSERT(type);
+
+#ifndef NDEBUG
+        StringPrintStream printStream;
+        printStream.print(TypeDumper(*type));
+        String functionName = printStream.toString();
+#else
+        String functionName = "<zero-init>"_s;
+#endif
+        auto callExpression = makeUniqueRef<AST::CallExpression>(variableDeclaration.origin(), WTFMove(functionName), Vector<UniqueRef<AST::Expression>>());
+        callExpression->setType(type->clone());
+        callExpression->setTypeAnnotation(AST::RightValue());
+        callExpression->setOverloads(m_castFunctions);
+        Vector<std::reference_wrapper<ResolvingType>> argumentTypes;
+        auto* function = resolveFunctionOverload(*callExpression->overloads(), argumentTypes, type);
+        RELEASE_ASSERT(function);
+        callExpression->setFunction(*function);
+
+        variableDeclaration.setInitializer(WTFMove(callExpression));
+    }
+
+    NameContext& m_nameContext;
+    Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1>& m_castFunctions;
+};
+
+void autoInitializeVariables(Program& program)
+{
+    AutoInitialize autoInitialize(program.nameContext());
+    autoInitialize.Visitor::visit(program);
+}
+
+} // namespace WHLSL
+
+} // namespace WebCore
+
+#endif // ENABLE(WEBGPU)
diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLAutoInitializeVariables.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLAutoInitializeVariables.h
new file mode 100644 (file)
index 0000000..f2eac33
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEBGPU)
+
+namespace WebCore {
+
+namespace WHLSL {
+
+class Program;
+
+void autoInitializeVariables(Program&);
+
+}
+
+}
+
+#endif
index 11d631e..6935f1b 100644 (file)
@@ -357,7 +357,7 @@ static bool checkOperatorOverload(const AST::FunctionDefinition& functionDefinit
             argumentTypes.append((*functionDefinition.parameters()[0]->type())->clone());
         for (auto& argumentType : argumentTypes)
             argumentTypeReferences.append(argumentType);
-        auto* overload = resolveFunctionOverloadImpl(*getterFuncs, argumentTypeReferences, nullptr);
+        auto* overload = resolveFunctionOverload(*getterFuncs, argumentTypeReferences);
         if (!overload)
             return false;
         auto& resultType = overload->type();
@@ -979,7 +979,7 @@ void Checker::visit(AST::DotExpression& dotExpression)
     AST::UnnamedType* getterReturnType = nullptr;
     {
         Vector<std::reference_wrapper<ResolvingType>> getterArgumentTypes { baseInfo->resolvingType };
-        getterFunction = resolveFunctionOverloadImpl(dotExpression.possibleGetterOverloads(), getterArgumentTypes, nullptr);
+        getterFunction = resolveFunctionOverload(dotExpression.possibleGetterOverloads(), getterArgumentTypes);
         if (getterFunction)
             getterReturnType = &getterFunction->type();
     }
@@ -989,7 +989,7 @@ void Checker::visit(AST::DotExpression& dotExpression)
     if (auto leftAddressSpace = baseInfo->typeAnnotation.leftAddressSpace()) {
         auto argumentType = makeUniqueRef<AST::PointerType>(Lexer::Token(dotExpression.origin()), *leftAddressSpace, baseUnnamedType->get().clone());
         Vector<std::reference_wrapper<ResolvingType>> anderArgumentTypes { baseInfo->resolvingType };
-        anderFunction = resolveFunctionOverloadImpl(dotExpression.possibleAnderOverloads(), anderArgumentTypes, nullptr);
+        anderFunction = resolveFunctionOverload(dotExpression.possibleAnderOverloads(), anderArgumentTypes);
         if (anderFunction)
             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
     }
@@ -999,7 +999,7 @@ void Checker::visit(AST::DotExpression& dotExpression)
     {
         auto argumentType = makeUniqueRef<AST::PointerType>(Lexer::Token(dotExpression.origin()), AST::AddressSpace::Thread, baseUnnamedType->get().clone());
         Vector<std::reference_wrapper<ResolvingType>> threadAnderArgumentTypes { baseInfo->resolvingType };
-        threadAnderFunction = resolveFunctionOverloadImpl(dotExpression.possibleAnderOverloads(), threadAnderArgumentTypes, nullptr);
+        threadAnderFunction = resolveFunctionOverload(dotExpression.possibleAnderOverloads(), threadAnderArgumentTypes);
         if (threadAnderFunction)
             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
     }
@@ -1024,7 +1024,7 @@ void Checker::visit(AST::DotExpression& dotExpression)
     {
         ResolvingType fieldResolvingType(fieldType->clone());
         Vector<std::reference_wrapper<ResolvingType>> setterArgumentTypes { baseInfo->resolvingType, fieldResolvingType };
-        setterFunction = resolveFunctionOverloadImpl(dotExpression.possibleSetterOverloads(), setterArgumentTypes, nullptr);
+        setterFunction = resolveFunctionOverload(dotExpression.possibleSetterOverloads(), setterArgumentTypes);
         if (setterFunction)
             setterReturnType = &setterFunction->type();
     }
@@ -1397,7 +1397,7 @@ void Checker::visit(AST::CallExpression& callExpression)
     // We don't want to recurse to the same node twice.
 
     ASSERT(callExpression.hasOverloads());
-    auto* function = resolveFunctionOverloadImpl(*callExpression.overloads(), types, callExpression.castReturnType());
+    auto* function = resolveFunctionOverload(*callExpression.overloads(), types, callExpression.castReturnType());
     if (!function) {
         if (auto newFunction = resolveByInstantiation(callExpression, types, m_intrinsics)) {
             m_program.append(WTFMove(*newFunction));
index 6699362..f565cfd 100644 (file)
@@ -221,7 +221,8 @@ bool inferTypesForTypeArguments(AST::NamedType& possibleType, AST::TypeArguments
     return true;
 }
 
-bool inferTypesForCall(AST::FunctionDeclaration& possibleFunction, Vector<std::reference_wrapper<ResolvingType>>& argumentTypes, const AST::NamedType* castReturnType)
+template <typename TypeKind>
+ALWAYS_INLINE bool inferTypesForCallImpl(AST::FunctionDeclaration& possibleFunction, Vector<std::reference_wrapper<ResolvingType>>& argumentTypes, const TypeKind* castReturnType)
 {
     if (possibleFunction.parameters().size() != argumentTypes.size())
         return false;
@@ -239,6 +240,16 @@ bool inferTypesForCall(AST::FunctionDeclaration& possibleFunction, Vector<std::r
     return true;
 }
 
+bool inferTypesForCall(AST::FunctionDeclaration& possibleFunction, Vector<std::reference_wrapper<ResolvingType>>& argumentTypes, const AST::NamedType* castReturnType)
+{
+    return inferTypesForCallImpl(possibleFunction, argumentTypes, castReturnType);
+}
+
+bool inferTypesForCall(AST::FunctionDeclaration& possibleFunction, Vector<std::reference_wrapper<ResolvingType>>& argumentTypes, const AST::UnnamedType* castReturnType)
+{
+    return inferTypesForCallImpl(possibleFunction, argumentTypes, castReturnType);
+}
+
 } // namespace WHLSL
 
 } // namespace WebCore
index 173d301..43c5188 100644 (file)
@@ -54,6 +54,7 @@ Optional<UniqueRef<AST::UnnamedType>> matchAndCommit(AST::ResolvableType&, AST::
 Optional<UniqueRef<AST::UnnamedType>> commit(AST::ResolvableType&);
 bool inferTypesForTypeArguments(AST::NamedType& possibleType, AST::TypeArguments&);
 bool inferTypesForCall(AST::FunctionDeclaration& possibleFunction, Vector<std::reference_wrapper<ResolvingType>>& argumentTypes, const AST::NamedType* castReturnType);
+bool inferTypesForCall(AST::FunctionDeclaration& possibleFunction, Vector<std::reference_wrapper<ResolvingType>>& argumentTypes, const AST::UnnamedType* castReturnType);
 
 }
 
index 56fb365..42848c7 100644 (file)
@@ -29,6 +29,7 @@
 #if ENABLE(WEBGPU)
 
 #include "WHLSLASTDumper.h"
+#include "WHLSLAutoInitializeVariables.h"
 #include "WHLSLCheckDuplicateFunctions.h"
 #include "WHLSLChecker.h"
 #include "WHLSLFunctionStageChecker.h"
@@ -58,7 +59,7 @@ namespace WHLSL {
 static constexpr bool dumpASTBeforeEachPass = false;
 static constexpr bool dumpASTAfterParsing = false;
 static constexpr bool dumpASTAtEnd = false;
-static constexpr bool alwaysDumpPassFailures = true;
+static constexpr bool alwaysDumpPassFailures = false;
 static constexpr bool dumpPassFailure = dumpASTBeforeEachPass || dumpASTAfterParsing || dumpASTAtEnd || alwaysDumpPassFailures;
 
 static bool dumpASTIfNeeded(bool shouldDump, Program& program, const char* message)
@@ -130,6 +131,7 @@ static Optional<Program> prepareShared(String& whlslSource)
     RUN_PASS(check, program);
 
     checkLiteralTypes(program);
+    autoInitializeVariables(program);
     resolveProperties(program);
     findHighZombies(program);
     RUN_PASS(checkStatementBehavior, program);
index dc934db..db2636e 100644 (file)
@@ -51,7 +51,8 @@ static unsigned conversionCost(AST::FunctionDeclaration& candidate, const Vector
     return conversionCost;
 }
 
-AST::FunctionDeclaration* resolveFunctionOverloadImpl(Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1>& possibleFunctions, Vector<std::reference_wrapper<ResolvingType>>& argumentTypes, AST::NamedType* castReturnType)
+template <typename TypeKind>
+AST::FunctionDeclaration* resolveFunctionOverloadImpl(Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1>& possibleFunctions, Vector<std::reference_wrapper<ResolvingType>>& argumentTypes, TypeKind* castReturnType)
 {
     Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1> candidates;
     for (auto& possibleFunction : possibleFunctions) {
@@ -76,6 +77,21 @@ AST::FunctionDeclaration* resolveFunctionOverloadImpl(Vector<std::reference_wrap
     return nullptr;
 }
 
+AST::FunctionDeclaration* resolveFunctionOverload(Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1>& possibleFunctions, Vector<std::reference_wrapper<ResolvingType>>& argumentTypes)
+{
+    return resolveFunctionOverloadImpl(possibleFunctions, argumentTypes, static_cast<AST::NamedType*>(nullptr));
+}
+
+AST::FunctionDeclaration* resolveFunctionOverload(Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1>& possibleFunctions, Vector<std::reference_wrapper<ResolvingType>>& argumentTypes, AST::NamedType* castReturnType)
+{
+    return resolveFunctionOverloadImpl(possibleFunctions, argumentTypes, castReturnType);
+}
+
+AST::FunctionDeclaration* resolveFunctionOverload(Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1>& possibleFunctions, Vector<std::reference_wrapper<ResolvingType>>& argumentTypes, AST::UnnamedType* castReturnType)
+{
+    return resolveFunctionOverloadImpl(possibleFunctions, argumentTypes, castReturnType);
+}
+
 AST::NamedType* resolveTypeOverloadImpl(Vector<std::reference_wrapper<AST::NamedType>, 1>& possibleTypes, AST::TypeArguments& typeArguments)
 {
     AST::NamedType* result = nullptr;
index 0653303..3d34ab6 100644 (file)
@@ -43,7 +43,9 @@ class NamedType;
 
 }
 
-AST::FunctionDeclaration* resolveFunctionOverloadImpl(Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1>& possibleFunctions, Vector<std::reference_wrapper<ResolvingType>>& argumentTypes, AST::NamedType* castReturnType);
+AST::FunctionDeclaration* resolveFunctionOverload(Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1>& possibleFunctions, Vector<std::reference_wrapper<ResolvingType>>& argumentTypes);
+AST::FunctionDeclaration* resolveFunctionOverload(Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1>& possibleFunctions, Vector<std::reference_wrapper<ResolvingType>>& argumentTypes, AST::NamedType* castReturnType);
+AST::FunctionDeclaration* resolveFunctionOverload(Vector<std::reference_wrapper<AST::FunctionDeclaration>, 1>& possibleFunctions, Vector<std::reference_wrapper<ResolvingType>>& argumentTypes, AST::UnnamedType* castReturnType);
 AST::NamedType* resolveTypeOverloadImpl(Vector<std::reference_wrapper<AST::NamedType>, 1>&, AST::TypeArguments&);
 
 }
index a8bbbf9..0d381d3 100644 (file)
@@ -307,6 +307,7 @@ Modules/websockets/WorkerThreadableWebSocketChannel.cpp
 Modules/webgpu/GPUCanvasContext.cpp
 Modules/webgpu/NavigatorGPU.cpp
 Modules/webgpu/WHLSL/WHLSLASTDumper.cpp
+Modules/webgpu/WHLSL/WHLSLAutoInitializeVariables.cpp
 Modules/webgpu/WHLSL/WHLSLInferTypes.cpp
 Modules/webgpu/WHLSL/WHLSLLexer.cpp
 Modules/webgpu/WHLSL/WHLSLParser.cpp
index 0e46120..f66f397 100644 (file)
                52B0D4BD1C57FD1E0077CE53 /* PlatformView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformView.h; sourceTree = "<group>"; };
                52B0D4BF1C57FD660077CE53 /* VideoFullscreenChangeObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoFullscreenChangeObserver.h; sourceTree = "<group>"; };
                52B0D4C11C57FF910077CE53 /* VideoFullscreenInterfaceMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoFullscreenInterfaceMac.h; sourceTree = "<group>"; };
+               52B3434922A0752200E49389 /* WHLSLAutoInitializeVariables.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLAutoInitializeVariables.h; sourceTree = "<group>"; };
+               52B3434B22A0752300E49389 /* WHLSLAutoInitializeVariables.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WHLSLAutoInitializeVariables.cpp; sourceTree = "<group>"; };
                52D5A18D1C54590300DE34A3 /* VideoFullscreenLayerManagerObjC.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = VideoFullscreenLayerManagerObjC.mm; sourceTree = "<group>"; };
                52D5A18E1C54590300DE34A3 /* VideoFullscreenLayerManagerObjC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoFullscreenLayerManagerObjC.h; sourceTree = "<group>"; };
                52D5A1A41C57488900DE34A3 /* VideoFullscreenModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoFullscreenModel.h; sourceTree = "<group>"; };
                                1CECB3AD21F2B96400F44542 /* Metal */,
                                C20F88AA22966B0E00D610FA /* WHLSLASTDumper.cpp */,
                                C20F88AC22966B0F00D610FA /* WHLSLASTDumper.h */,
+                               52B3434B22A0752300E49389 /* WHLSLAutoInitializeVariables.cpp */,
+                               52B3434922A0752200E49389 /* WHLSLAutoInitializeVariables.h */,
                                C234A9B221E92C1F003C984D /* WHLSLCheckDuplicateFunctions.cpp */,
                                C234A9AE21E92C1A003C984D /* WHLSLCheckDuplicateFunctions.h */,
                                1C840B9B21EC400900D0500D /* WHLSLChecker.cpp */,