WebKit Bugzilla
Attachment 349818 Details for
Bug 187738
: [WHLSL] Test suite for Metal code generation
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
WIP
bug-187738-20180914152645.patch (text/plain), 430.51 KB, created by
Thomas Denney
on 2018-09-14 15:26:49 PDT
(
hide
)
Description:
WIP
Filename:
MIME Type:
Creator:
Thomas Denney
Created:
2018-09-14 15:26:49 PDT
Size:
430.51 KB
patch
obsolete
>Subversion Revision: 236001 >diff --git a/Tools/ChangeLog b/Tools/ChangeLog >index 60dc9bcca816fc13fe430ba3ccf2879b5f8ce42c..af9e949237e669a2f1bc6c81fe3ba7fd0ec0ffac 100644 >--- a/Tools/ChangeLog >+++ b/Tools/ChangeLog >@@ -1,3 +1,279 @@ >+2018-09-14 Thomas Denney <tdenney@apple.com> >+ >+ [WHLSL] Test suite for Metal code generation >+ https://bugs.webkit.org/show_bug.cgi?id=187738 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * WebGPUShadingLanguageRI/ArrayType.js: >+ (ArrayType.prototype.get arrayRefType): >+ * WebGPUShadingLanguageRI/Casts.js: >+ (castToBool): >+ (castAndCheckValue): >+ (isBitwiseEquivalent): >+ * WebGPUShadingLanguageRI/Intrinsics.js: >+ (Intrinsics.isBitwiseEquivalent): Deleted. >+ * WebGPUShadingLanguageRI/MakeArrayRefExpression.js: >+ (MakeArrayRefExpression): >+ (MakeArrayRefExpression.prototype.get type): >+ * WebGPUShadingLanguageRI/Metal/MSLBackend.js: Added. >+ (MSLBackend): >+ (MSLBackend.prototype.get program): >+ (MSLBackend.prototype.get declarations): >+ (MSLBackend.prototype.get functionSources): >+ (MSLBackend.prototype.compile): >+ (MSLBackend.prototype._msl): >+ (MSLBackend.prototype._findFunctionsToCompile.FindFunctionsThatGetCalled.prototype.visitCallExpression): >+ (MSLBackend.prototype._findFunctionsToCompile.FindFunctionsThatGetCalled): >+ (MSLBackend.prototype._findFunctionsToCompile): >+ (MSLBackend.prototype._createTypeDecls): >+ (MSLBackend.prototype._createFunctionDecls): >+ (MSLBackend.prototype._sortTypeDeclarationsInTopologicalOrder.TypeOrderer.prototype.visitStructType): >+ (MSLBackend.prototype._sortTypeDeclarationsInTopologicalOrder.TypeOrderer.prototype.visitReferenceType): >+ (MSLBackend.prototype._sortTypeDeclarationsInTopologicalOrder.TypeOrderer): >+ (MSLBackend.prototype._sortTypeDeclarationsInTopologicalOrder): >+ (MSLBackend.prototype._removeCommentsAndEmptyLines): >+ * WebGPUShadingLanguageRI/Metal/MSLCodegenAll.js: Copied from Tools/WebGPUShadingLanguageRI/MakeArrayRefExpression.js. >+ * WebGPUShadingLanguageRI/Metal/MSLCompileResult.js: Copied from Tools/WebGPUShadingLanguageRI/MakeArrayRefExpression.js. >+ (MSLCompileResult): >+ (MSLCompileResult.prototype.get metalShaderLanguageSource): >+ (MSLCompileResult.prototype.get error): >+ (MSLCompileResult.prototype.get originalFunctionNameToMangledNames): >+ (MSLCompileResult.prototype.get functionSources): >+ (MSLCompileResult.prototype.get didSucceed): >+ * WebGPUShadingLanguageRI/Metal/MSLConstexprEmitter.js: Copied from Tools/WebGPUShadingLanguageRI/MakeArrayRefExpression.js. >+ (MSLConstexprEmitter.prototype.visitIdentityExpression): >+ (MSLConstexprEmitter.prototype.visitBoolLiteral): >+ (MSLConstexprEmitter.prototype.visitEnumLiteral): >+ (MSLConstexprEmitter.prototype.visitGenericLiteral): >+ (MSLConstexprEmitter.prototype.visitNullLiteral): >+ (MSLConstexprEmitter): >+ * WebGPUShadingLanguageRI/Metal/MSLFunctionDeclaration.js: Added. >+ (MSLFunctionDeclaration): >+ (MSLFunctionDeclaration.prototype.get funcMangler): >+ (MSLFunctionDeclaration.prototype.get func): >+ (MSLFunctionDeclaration.prototype.get typeNamer): >+ (MSLFunctionDeclaration.prototype.get typeAttributes): >+ (MSLFunctionDeclaration.prototype.get isVertexShader): >+ (MSLFunctionDeclaration.prototype.get paramMap): >+ (MSLFunctionDeclaration.prototype.commentLine): >+ (MSLFunctionDeclaration.prototype.toString): >+ (MSLFunctionDeclaration.prototype.get isShader): >+ (MSLFunctionDeclaration.prototype.parameterIsAttribute): >+ (MSLFunctionDeclaration.prototype.parameterIsVertexId): >+ * WebGPUShadingLanguageRI/Metal/MSLFunctionDefinition.js: Copied from Tools/WebGPUShadingLanguageRI/MakeArrayRefExpression.js. >+ (MSLFunctionDefinition.prototype.toString): >+ (MSLFunctionDefinition): >+ * WebGPUShadingLanguageRI/Metal/MSLFunctionForwardDeclaration.js: Copied from Tools/WebGPUShadingLanguageRI/MakeArrayRefExpression.js. >+ (MSLFunctionForwardDeclaration.prototype.toString): >+ (MSLFunctionForwardDeclaration): >+ * WebGPUShadingLanguageRI/Metal/MSLNameMangler.js: Copied from Tools/WebGPUShadingLanguageRI/MakeArrayRefExpression.js. >+ (MSLNameMangler): >+ (MSLNameMangler.prototype.mangle): >+ * WebGPUShadingLanguageRI/Metal/MSLNativeFunctionCall.js: Added. >+ (mslNativeFunctionCall): >+ * WebGPUShadingLanguageRI/Metal/MSLStatementEmitter.js: Added. >+ (MSLStatementEmitter): >+ (MSLStatementEmitter.prototype._emitTrap): >+ (MSLStatementEmitter.prototype._zeroInitialize.ZeroInitializer.prototype.visitNativeType): >+ (MSLStatementEmitter.prototype._zeroInitialize.ZeroInitializer.prototype.visitPtrType): >+ (MSLStatementEmitter.prototype._zeroInitialize.ZeroInitializer.prototype.visitArrayType): >+ (MSLStatementEmitter.prototype._zeroInitialize.ZeroInitializer.prototype.visitArrayRefType): >+ (MSLStatementEmitter.prototype._zeroInitialize.ZeroInitializer.prototype.visitEnumType): >+ (MSLStatementEmitter.prototype._zeroInitialize.ZeroInitializer.prototype.visitStructType): >+ (MSLStatementEmitter.prototype._zeroInitialize.ZeroInitializer.prototype.visitVectorType): >+ (MSLStatementEmitter.prototype._zeroInitialize.ZeroInitializer.prototype.visitMatrixType): >+ (MSLStatementEmitter.prototype._zeroInitialize.ZeroInitializer.prototype.visitTypeRef): >+ (MSLStatementEmitter.prototype._zeroInitialize.ZeroInitializer): >+ (MSLStatementEmitter.prototype._zeroInitialize): >+ (MSLStatementEmitter.): >+ * WebGPUShadingLanguageRI/Metal/MSLTypeAttributes.js: Copied from Tools/WebGPUShadingLanguageRI/Type.js. >+ (MSLTypeAttributes): >+ (MSLTypeAttributes.prototype.get type): >+ (MSLTypeAttributes.prototype.get isVertexAttribute): >+ (MSLTypeAttributes.prototype.set isVertexAttribute): >+ (MSLTypeAttributes.prototype.get isVertexOutputOrFragmentInput): >+ (MSLTypeAttributes.prototype.set isVertexOutputOrFragmentInput): >+ (MSLTypeAttributes.prototype.get isFragmentOutput): >+ (MSLTypeAttributes.prototype.set isFragmentOutput): >+ (MSLTypeAttributes.prototype.get fieldMangler): >+ (MSLTypeAttributes.prototype.mangledFieldName): >+ * WebGPUShadingLanguageRI/Metal/MSLTypeAttributesMap.js: Copied from Tools/WebGPUShadingLanguageRI/Type.js. >+ (MSLTypeAttributesMap): >+ (MSLTypeAttributesMap.prototype.attributesForType): >+ (MSLTypeAttributesMap.prototype._visitVertexShader): >+ (MSLTypeAttributesMap.prototype._visitFragmentShader): >+ * WebGPUShadingLanguageRI/Metal/MSLTypeNamer.js: Added. >+ (MSLTypeNamer): >+ (MSLTypeNamer.prototype.get typeUnifier): >+ (MSLTypeNamer.prototype.uniqueTypeId): >+ (MSLTypeNamer.prototype.mslTypeName.TypeNameVisitor.prototype.visitNativeType): >+ (MSLTypeNamer.prototype.mslTypeName.TypeNameVisitor.prototype.visitStructType): >+ (MSLTypeNamer.prototype.mslTypeName.TypeNameVisitor.prototype.visitEnumType): >+ (MSLTypeNamer.prototype.mslTypeName.TypeNameVisitor.prototype.visitReferenceType): >+ (MSLTypeNamer.prototype.mslTypeName.TypeNameVisitor.prototype.visitArrayType): >+ (MSLTypeNamer.prototype.mslTypeName.TypeNameVisitor.prototype.visitArrayRefType): >+ (MSLTypeNamer.prototype.mslTypeName.TypeNameVisitor.prototype.visitVectorType): >+ (MSLTypeNamer.prototype.mslTypeName.TypeNameVisitor.prototype.visitTypeRef): >+ (MSLTypeNamer.prototype.mslTypeName.TypeNameVisitor.prototype.visitMatrixType): >+ (MSLTypeNamer.prototype.mslTypeName.TypeNameVisitor): >+ (MSLTypeNamer.prototype.mslTypeName): >+ * WebGPUShadingLanguageRI/Metal/MSLTypeUnifier.js: Added. >+ (MSLTypeUnifier): >+ (MSLTypeUnifier.prototype.get allTypes): >+ (MSLTypeUnifier.prototype.uniqueTypeId): >+ (MSLTypeUnifier.prototype.visitTypeRef): >+ (MSLTypeUnifier.prototype.visitStructType): >+ (MSLTypeUnifier.prototype.visitEnumType): >+ (MSLTypeUnifier.prototype.visitNativeType): >+ (MSLTypeUnifier.prototype.visitPtrType): >+ (MSLTypeUnifier.prototype.visitArrayType): >+ (MSLTypeUnifier.prototype.visitArrayRefType): >+ (MSLTypeUnifier.prototype.visitVectorType): >+ (MSLTypeUnifier.prototype.visitMakeArrayRefExpression): >+ (MSLTypeUnifier.prototype.typesThatNeedDeclaration): >+ * WebGPUShadingLanguageRI/Metal/MSLVarDeclaration.js: Copied from Tools/WebGPUShadingLanguageRI/Type.js. >+ (mslVarDeclaration): >+ * WebGPUShadingLanguageRI/Metal/TypeOf.js: Added. >+ (typeOf.TypeVisitor.prototype.visitAnonymousVariable): >+ (typeOf.TypeVisitor.prototype.visitArrayRefType): >+ (typeOf.TypeVisitor.prototype.visitArrayType): >+ (typeOf.TypeVisitor.prototype.visitAssignment): >+ (typeOf.TypeVisitor.prototype.visitCallExpression): >+ (typeOf.TypeVisitor.prototype.visitCommaExpression): >+ (typeOf.TypeVisitor.prototype.visitConvertPtrToArrayRefExpression): >+ (typeOf.TypeVisitor.prototype.visitDotExpression): >+ (typeOf.TypeVisitor.prototype.visitElementalType): >+ (typeOf.TypeVisitor.prototype.visitEnumType): >+ (typeOf.TypeVisitor.prototype.visitField): >+ (typeOf.TypeVisitor.prototype.visitFunc): >+ (typeOf.TypeVisitor.prototype.visitFuncDef): >+ (typeOf.TypeVisitor.prototype.visitFuncParameter): >+ (typeOf.TypeVisitor.prototype.visitFunctionLikeBlock): >+ (typeOf.TypeVisitor.prototype.visitGenericLiteralType): >+ (typeOf.TypeVisitor.prototype.visitIdentityExpression): >+ (typeOf.TypeVisitor.prototype.visitIndexExpression): >+ (typeOf.TypeVisitor.prototype.visitLogicalExpression): >+ (typeOf.TypeVisitor.prototype.visitLogicalNot): >+ (typeOf.TypeVisitor.prototype.visitMakeArrayRefExpression): >+ (typeOf.TypeVisitor.prototype.visitMakePtrExpression): >+ (typeOf.TypeVisitor.prototype.visitMatrixType): >+ (typeOf.TypeVisitor.prototype.visitNativeFunc): >+ (typeOf.TypeVisitor.prototype.visitNativeFuncInstance): >+ (typeOf.TypeVisitor.prototype.visitNativeType): >+ (typeOf.TypeVisitor.prototype.visitNativeTypeInstance): >+ (typeOf.TypeVisitor.prototype.visitNullLiteral): >+ (typeOf.TypeVisitor.prototype.visitNullType): >+ (typeOf.TypeVisitor.prototype.visitPtrType): >+ (typeOf.TypeVisitor.prototype.visitReadModifyWriteExpression): >+ (typeOf.TypeVisitor.prototype.visitReferenceType): >+ (typeOf.TypeVisitor.prototype.visitStructType): >+ (typeOf.TypeVisitor.prototype.visitTypeDef): >+ (typeOf.TypeVisitor.prototype.visitTypeRef): >+ (typeOf.TypeVisitor.prototype.visitVariableDecl): >+ (typeOf.TypeVisitor.prototype.visitVariableRef): >+ (typeOf.TypeVisitor.prototype.visitVectorType): >+ (typeOf.TypeVisitor.prototype.visitBlock): >+ (typeOf.TypeVisitor.prototype.visitBoolLiteral): >+ (typeOf.TypeVisitor.prototype.visitBreak): >+ (typeOf.TypeVisitor.prototype.visitConstexprTypeParameter): >+ (typeOf.TypeVisitor.prototype.visitContinue): >+ (typeOf.TypeVisitor.prototype.visitDereferenceExpression): >+ (typeOf.TypeVisitor.prototype.visitDoWhileLoop): >+ (typeOf.TypeVisitor.prototype.visitEnumLiteral): >+ (typeOf.TypeVisitor.prototype.visitEnumMember): >+ (typeOf.TypeVisitor.prototype.visitForLoop): >+ (typeOf.TypeVisitor.prototype.visitGenericLiteral): >+ (typeOf.TypeVisitor.prototype.visitIfStatement): >+ (typeOf.TypeVisitor.prototype.visitProgram): >+ (typeOf.TypeVisitor.prototype.visitProtocolDecl): >+ (typeOf.TypeVisitor.prototype.visitProtocolFuncDecl): >+ (typeOf.TypeVisitor.prototype.visitProtocolRef): >+ (typeOf.TypeVisitor.prototype.visitReturn): >+ (typeOf.TypeVisitor.prototype.visitSwitchCase): >+ (typeOf.TypeVisitor.prototype.visitSwitchStatement): >+ (typeOf.TypeVisitor.prototype.visitTrapStatement): >+ (typeOf.TypeVisitor.prototype.visitWhileLoop): >+ (typeOf.TypeVisitor): >+ (typeOf): >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/.gitignore: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/AppDelegate.h: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/AppDelegate.m: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Assets.xcassets/AppIcon.appiconset/Contents.json: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Assets.xcassets/Contents.json: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Base.lproj/Main.storyboard: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/CompileResult.h: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/CompileResult.m: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Compiler.h: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Compiler.m: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/CustomMetalView.h: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/CustomMetalView.m: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Demo shaders/Default.whlsl: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Demo shaders/Julia.whlsl: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Demo shaders/Mandelbrot.whlsl: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Info.plist: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Metal equivalents/Shaders.metal: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Renderer/OffscreenRenderer.h: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Renderer/OffscreenRenderer.m: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Renderer/OnscreenRenderer.h: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Renderer/OnscreenRenderer.m: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Renderer/Renderer.h: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Renderer/Renderer.m: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/TestCallArgument.h: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/TestCallArgument.m: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/TestDescription.h: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/TestDescription.m: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/TestFamily.h: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/TestFamily.m: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/TestFamilyRunner.h: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/TestFamilyRunner.m: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/ViewController.h: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/ViewController.m: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/WHLSL.entitlements: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/_SharedMetal.txt: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/main.m: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/WHLSL Tests.xcodeproj/project.pbxproj: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/WHLSL ToyTests/Info.plist: Added. >+ * WebGPUShadingLanguageRI/Metal/WHLSL Tests/WHLSL ToyTests/WHLSL_ToyTests.m: Added. >+ * WebGPUShadingLanguageRI/Metal/WhlslToMsl.js: Copied from Tools/WebGPUShadingLanguageRI/MakeArrayRefExpression.js. >+ (whlslToMsl): >+ * WebGPUShadingLanguageRI/PropertyResolver.js: >+ (PropertyResolver.visitMakePtrExpression): >+ * WebGPUShadingLanguageRI/SynthesizeStructAccessors.js: >+ (synthesizeStructAccessors.setupImplementationData): >+ * WebGPUShadingLanguageRI/Test.js: >+ (makeInt): >+ (makeUint): >+ (makeUchar): >+ (makeBool): >+ (makeFloat): >+ (makeCastedFloat): >+ (makeHalf): >+ (checkInt): >+ (tests.incrementAndDecrement): >+ (tests.returnIntLiteralUint): >+ (tests.returnIntLiteralFloat): >+ (tests.nestedSubscriptWithArraysInStructs): >+ (tests.nestedSubscript): >+ (tests.lotsOfLocalVariables): >+ (tests.uintBitAnd): >+ (tests.uintBitOr): >+ (tests.uintBitXor): >+ (tests.uintBitNot): >+ (tests.uintLShift): >+ (tests.uintRShift): >+ (tests.ucharBitAnd): >+ (tests.ucharBitOr): >+ (tests.ucharBitXor): >+ (tests.ucharBitNot): >+ (tests.ucharLShift): >+ (tests.ucharRShift): >+ (tests.textureSample): >+ (checkNumber): Deleted. >+ (checkEnum): Deleted. >+ * WebGPUShadingLanguageRI/Type.js: >+ (Type.prototype.get arrayRefType): >+ > 2018-09-13 Ryan Haddad <ryanhaddad@apple.com> > > Unreviewed, rolling out r235954. >diff --git a/Tools/WebGPUShadingLanguageRI/ArrayType.js b/Tools/WebGPUShadingLanguageRI/ArrayType.js >index 0d56a0b375712c4c14bf731196109dff586bab94..b9d918e80cd210a937f238bde4f4668f10689360 100644 >--- a/Tools/WebGPUShadingLanguageRI/ArrayType.js >+++ b/Tools/WebGPUShadingLanguageRI/ArrayType.js >@@ -48,6 +48,11 @@ class ArrayType extends Type { > return this.numElements.value; > } > >+ get arrayRefType() >+ { >+ return new ArrayRefType(this.origin, "thread", this.elementType); >+ } >+ > toString() > { > return this.elementType + "[" + this.numElements + "]"; >diff --git a/Tools/WebGPUShadingLanguageRI/Casts.js b/Tools/WebGPUShadingLanguageRI/Casts.js >index acbb2ea028535b4670423097f7a5b57caf6b8b1c..c8f08ce69a7f32e8a11a0504352a4052df164d3f 100644 >--- a/Tools/WebGPUShadingLanguageRI/Casts.js >+++ b/Tools/WebGPUShadingLanguageRI/Casts.js >@@ -39,6 +39,11 @@ function bitwiseCast(typedArrayConstructor1, typedArrayConstructor2, value) > return typedArray2[0]; > } > >+function castToBool(value) >+{ >+ return !!value; >+} >+ > function castToUchar(number) > { > return number & 0xFF; >@@ -113,3 +118,25 @@ function castToFloat(number) > { > return Math.fround(number); > } >+ >+function castAndCheckValue(castFunction, value) >+{ >+ const castedValue = castFunction(value); >+ if (!isBitwiseEquivalent(castedValue, value)) >+ throw new Error(`${value} was casted and yielded ${castedValue}, which is not bitwise equivalent.`); >+ return castedValue; >+} >+ >+function isBitwiseEquivalent(left, right) >+{ >+ let doubleArray = new Float64Array(1); >+ let intArray = new Int32Array(doubleArray.buffer); >+ doubleArray[0] = left; >+ let leftInts = Int32Array.from(intArray); >+ doubleArray[0] = right; >+ for (let i = 0; i < 2; ++i) { >+ if (leftInts[i] != intArray[i]) >+ return false; >+ } >+ return true; >+} >diff --git a/Tools/WebGPUShadingLanguageRI/Intrinsics.js b/Tools/WebGPUShadingLanguageRI/Intrinsics.js >index 1b0a12af4002a90be635e738f1d5e7d90dcb04d3..68b0dd573fc02ea38517955d8388a646aa90a596 100644 >--- a/Tools/WebGPUShadingLanguageRI/Intrinsics.js >+++ b/Tools/WebGPUShadingLanguageRI/Intrinsics.js >@@ -34,20 +34,6 @@ class Intrinsics { > // For example, if a native function is declared using "int" rather than "int", then we must > // use "int" here, since we don't yet know that they are the same type. > >- function isBitwiseEquivalent(left, right) >- { >- let doubleArray = new Float64Array(1); >- let intArray = new Int32Array(doubleArray.buffer); >- doubleArray[0] = left; >- let leftInts = Int32Array.from(intArray); >- doubleArray[0] = right; >- for (let i = 0; i < 2; ++i) { >- if (leftInts[i] != intArray[i]) >- return false; >- } >- return true; >- } >- > this._map.set( > "native typedef void", > type => { >diff --git a/Tools/WebGPUShadingLanguageRI/MakeArrayRefExpression.js b/Tools/WebGPUShadingLanguageRI/MakeArrayRefExpression.js >index 0cc6f6ecd23bf03f0ae223f192b1a07ad443709e..6eb6f27d26ccd27c86f362f3808c5ec5f1ef8a56 100644 >--- a/Tools/WebGPUShadingLanguageRI/MakeArrayRefExpression.js >+++ b/Tools/WebGPUShadingLanguageRI/MakeArrayRefExpression.js >@@ -29,12 +29,13 @@ class MakeArrayRefExpression extends Expression { > { > super(origin); > this._lValue = lValue; >- if (this.lValue.variable && this.lValue.variable.type && this.lValue.variable.type.isArray && this.lValue.variable.type.elementType) { >- this._type = new ArrayRefType(origin, "thread", this.lValue.variable.type.elementType); >- } > } > >- get type() { return this._type; } >+ get type() >+ { >+ return typeOf(this.lValue).arrayRefType; >+ } >+ > get lValue() { return this._lValue; } > > toString() >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/MSLBackend.js b/Tools/WebGPUShadingLanguageRI/Metal/MSLBackend.js >new file mode 100644 >index 0000000000000000000000000000000000000000..2d5d39a42352ae7df5e80e84c0aea97fe6cf2143 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/MSLBackend.js >@@ -0,0 +1,256 @@ >+/* >+ * Copyright (C) 2018 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. ``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 >+ * 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. >+ */ >+ >+const DefaultMetalSource = `#include <metal_stdlib> >+using namespace metal; >+ >+`; >+ >+// Handles the compilation of Program AST instances to MSLCompileResult instances, which >+// include the raw MSL. In general clients should call |whlslToMsl|, which parses, >+// typechecks, and inlines the WHLSL before passing it to this compiler. >+class MSLBackend { >+ >+ constructor(program) >+ { >+ this._program = program; >+ this._declarations = []; >+ this._funcNameMangler = new MSLNameMangler("F"); >+ this._typeUnifier = new MSLTypeUnifier(); >+ this._typeNamer = new MSLTypeNamer(this._typeUnifier); >+ this._forwardTypeDecls = []; >+ this._typeDefinitions = []; >+ this._forwardFunctionDecls = []; >+ this._functionDefintions = []; >+ } >+ >+ get program() >+ { >+ return this._program; >+ } >+ >+ get declarations() >+ { >+ return this._declarations; >+ } >+ >+ get functionSources() >+ { >+ return this._functionSources; >+ } >+ >+ compile() >+ { >+ try { >+ const src = this._msl(); >+ const mangledMap = {}; >+ for (let func of this._functionDefintions) { >+ const key = func.func.name; >+ const value = this._funcNameMangler.mangle(func.func); >+ mangledMap[key] = value; >+ } >+ >+ return new MSLCompileResult(src, null, mangledMap, this._functionSources); >+ } catch (e) { >+ return new MSLCompileResult(null, e, null, null); >+ } >+ } >+ >+ _msl() >+ { >+ // Step 1: Find all the functions to compile >+ >+ const functionsToCompile = this._findFunctionsToCompile(); >+ for (let func of functionsToCompile) >+ func.visit(this._typeUnifier); >+ >+ // Step 2: Find properties of the types and create type and function declarations. >+ >+ this._allTypeAttributes = new MSLTypeAttributesMap(functionsToCompile, this._typeUnifier); >+ this._createTypeDecls(); >+ this._createFunctionDecls(functionsToCompile); >+ >+ // Step 3: Generate the actual MSL source code. >+ >+ let outputStr = DefaultMetalSource; >+ >+ const addSection = (title, decls) => { >+ outputStr += `#pragma mark - ${title}\n\n${decls.join("\n\n")}\n\n`; >+ }; >+ >+ addSection("Forward type declarations", this._forwardTypeDecls); >+ addSection("Type definitions", this._typeDefinitions); >+ addSection("Forward function declarations", this._forwardFunctionDecls); >+ addSection("Function definitions", this._functionDefintions); >+ >+ if (!this._allowComments) >+ outputStr = this._removeCommentsAndEmptyLines(outputStr); >+ >+ return outputStr; >+ } >+ >+ _findFunctionsToCompile() >+ { >+ const entryPointFunctions = []; >+ for (let [name, instances] of this._program.functions) { >+ for (let instance of instances) { >+ if (instance.isEntryPoint) >+ entryPointFunctions.push(instance); >+ } >+ } >+ const functions = new Set(entryPointFunctions); >+ >+ class FindFunctionsThatGetCalled extends Visitor { >+ visitCallExpression(node) >+ { >+ super.visitCallExpression(node); >+ if (node.func instanceof FuncDef) { >+ functions.add(node.func); >+ node.func.visit(this); >+ } >+ } >+ } >+ const findFunctionsThatGetCalledVisitor = new FindFunctionsThatGetCalled(); >+ for (let entryPoint of entryPointFunctions) >+ entryPoint.visit(findFunctionsThatGetCalledVisitor); >+ return Array.from(functions); >+ } >+ >+ _createTypeDecls() >+ { >+ const typesThatNeedDeclaration = this._typeUnifier.typesThatNeedDeclaration(); >+ const typeDeclsInOrder = this._sortTypeDeclarationsInTopologicalOrder(typesThatNeedDeclaration); >+ >+ for (let type of typeDeclsInOrder) { >+ if (type instanceof StructType) { >+ this._forwardTypeDecls.push(this._metalSourceForStructForwardDeclaration(type, this._typeNamer)); >+ this._typeDefinitions.push(this._metalSourceForStructDefinition(type, this._typeNamer, this._allTypeAttributes.attributesForType(type))); >+ } else if (type instanceof ArrayRefType) { >+ this._forwardTypeDecls.push(this._metalSourceForArrayRefForwardDeclaration(type, this._typeNamer)); >+ this._typeDefinitions.push(this._metalSourceForArrayRefDefinition(type, this._typeNamer)); >+ } else >+ throw new Error(`${type} cannot be declared in Metal`); >+ } >+ } >+ >+ _createFunctionDecls(unifiedFunctionDefs) >+ { >+ for (let func of unifiedFunctionDefs) { >+ this._forwardFunctionDecls.push(new MSLFunctionForwardDeclaration(this._funcNameMangler, func, this._typeNamer, this._allTypeAttributes)); >+ this._functionDefintions.push(new MSLFunctionDefinition(this._funcNameMangler, func, this._typeNamer, this._allTypeAttributes)); >+ } >+ } >+ >+ _sortTypeDeclarationsInTopologicalOrder(typesToDeclare) >+ { >+ const declarations = new Array(); >+ for (let type of typesToDeclare) >+ declarations.push(type); >+ >+ let typeOrder = []; >+ let visitedSet = new Set(); >+ const typeUnifier = this._typeUnifier; >+ class TypeOrderer extends Visitor { >+ visitStructType(node) >+ { >+ const id = typeUnifier.uniqueTypeId(node); >+ if (!visitedSet.has(id)) { >+ typeOrder.push(node); >+ super.visitStructType(node); >+ } >+ visitedSet.add(id); >+ } >+ >+ // An empty implementation ensures that we don't recurse into the element type and needlessly create dependencies. >+ visitReferenceType(node) {} >+ } >+ const typeOrderer = new TypeOrderer(); >+ for (let type of typesToDeclare) >+ type.visit(typeOrderer); >+ typeOrder = typeOrder.reverse(); >+ >+ const typeOrderMap = new Map(); >+ for (let i = 0; i < typeOrder.length; i++) >+ typeOrderMap.set(typeOrder[i], i); >+ >+ return declarations.sort((a, b) => typeOrderMap.get(a) - typeOrderMap.get(b)); >+ } >+ >+ // Also removes #pragma marks. >+ _removeCommentsAndEmptyLines(src) >+ { >+ const singleLineCommentRegex = /(\/\/|\#pragma)(.*?)($|\n)/; >+ const lines = src.split('\n') >+ .map(line => line.replace(singleLineCommentRegex, '').trimEnd()) >+ .filter(line => line.length > 0); >+ return lines.join('\n'); >+ } >+ >+ _metalSourceForArrayRefDefinition(arrayRefType, typeNamer) >+ { >+ let src = `struct ${typeNamer.uniqueTypeId(arrayRefType)} {\n`; >+ const fakePtrType = new PtrType(arrayRefType.origin, arrayRefType.addressSpace, arrayRefType.elementType); >+ src += ` ${mslVarDeclaration(typeNamer, fakePtrType, "ptr")};\n`; >+ src += " uint32_t length;\n"; >+ src += "};"; >+ return src; >+ } >+ >+ _metalSourceForArrayRefForwardDeclaration(arrayRefType, typeNamer) >+ { >+ return `struct ${typeNamer.uniqueTypeId(arrayRefType)};`; >+ } >+ >+ _metalSourceForStructForwardDeclaration(structType, typeNamer) >+ { >+ return `struct ${typeNamer.uniqueTypeId(structType)};`; >+ } >+ >+ _metalSourceForStructDefinition(structType, typeNamer, structTypeAttributes) >+ { >+ let src = `struct ${typeNamer.uniqueTypeId(structType)} {\n`; >+ >+ let index = 0; >+ for (let [fieldName, field] of structType.fieldMap) { >+ const mangledFieldName = structTypeAttributes.mangledFieldName(fieldName); >+ src += ` ${mslVarDeclaration(typeNamer, field.type, mangledFieldName)}`; >+ >+ const annotations = []; >+ if (structTypeAttributes.isVertexAttribute) >+ annotations.push(`attribute(${index++})`); >+ if (structTypeAttributes.isVertexOutputOrFragmentInput && fieldName === "wsl_Position") >+ annotations.push("position"); >+ if (structTypeAttributes.isFragmentOutput && fieldName === "wsl_Color") >+ annotations.push("color(0)"); >+ if (annotations.length) >+ src += ` [[${annotations.join(", ")}]]`; >+ src += ";\n"; >+ } >+ >+ src += "};"; >+ >+ return src; >+ } >+} >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/MSLCodegenAll.js b/Tools/WebGPUShadingLanguageRI/Metal/MSLCodegenAll.js >new file mode 100644 >index 0000000000000000000000000000000000000000..94677b9f11ec5958aefc917fcfcf1a4ca86365ae >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/MSLCodegenAll.js >@@ -0,0 +1,41 @@ >+/* >+ * Copyright (C) 2018 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. ``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 >+ * 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. >+ */ >+ >+load("MSLBackend.js"); >+load("MSLCompileResult.js"); >+load("MSLConstexprEmitter.js"); >+load("MSLFunctionDeclaration.js"); >+load("MSLFunctionDefinition.js"); >+load("MSLFunctionForwardDeclaration.js"); >+load("MSLNameMangler.js"); >+load("MSLNativeFunctionCall.js"); >+load("MSLStatementEmitter.js"); >+load("MSLTypeAttributesMap.js"); >+load("MSLTypeAttributes.js"); >+load("MSLTypeNamer.js"); >+load("MSLTypeUnifier.js"); >+load("MSLVarDeclaration.js"); >+load("TypeOf.js"); >+load("WhlslToMsl.js"); >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/MSLCompileResult.js b/Tools/WebGPUShadingLanguageRI/Metal/MSLCompileResult.js >new file mode 100644 >index 0000000000000000000000000000000000000000..2fd0bb892b669e79b730c790f453ae5a29346d0c >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/MSLCompileResult.js >@@ -0,0 +1,60 @@ >+/* >+ * Copyright (C) 2018 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. ``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 >+ * 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. >+ */ >+ >+class MSLCompileResult { >+ >+ constructor(src, err, mangledNameMap, functionSources) >+ { >+ this._metalShaderLanguageSource = src; >+ this._error = err; >+ this._originalFunctionNameToMangledNames = mangledNameMap; >+ this._functionSources = functionSources; >+ } >+ >+ get metalShaderLanguageSource() >+ { >+ return this._metalShaderLanguageSource; >+ } >+ >+ get error() >+ { >+ return this._error; >+ } >+ >+ get originalFunctionNameToMangledNames() >+ { >+ return this._originalFunctionNameToMangledNames; >+ } >+ >+ get functionSources() >+ { >+ return this._functionSources; >+ } >+ >+ get didSucceed() >+ { >+ return !this.error; >+ } >+} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/MSLConstexprEmitter.js b/Tools/WebGPUShadingLanguageRI/Metal/MSLConstexprEmitter.js >new file mode 100644 >index 0000000000000000000000000000000000000000..5d343286cfd2f38a43e83c49059804478bbfe9d1 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/MSLConstexprEmitter.js >@@ -0,0 +1,54 @@ >+/* >+ * Copyright (C) 2018 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. ``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 >+ * 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. >+ */ >+ >+// Used in scenarios where having an auxiliary variable is not possible (e.g. switch cases). >+class MSLConstexprEmitter extends Visitor >+{ >+ visitIdentityExpression(node) >+ { >+ return node.target.visit(this); >+ } >+ >+ visitBoolLiteral(node) >+ { >+ return node.value.toString(); >+ } >+ >+ visitEnumLiteral(node) >+ { >+ return node.member.value.visit(this); >+ } >+ >+ visitGenericLiteral(node) >+ { >+ // FIXME: What happens in the case of halfs/floats/etc >+ return node.value.toString(); >+ } >+ >+ visitNullLiteral(node) >+ { >+ return "nullptr"; >+ } >+} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/MSLFunctionDeclaration.js b/Tools/WebGPUShadingLanguageRI/Metal/MSLFunctionDeclaration.js >new file mode 100644 >index 0000000000000000000000000000000000000000..de39a49fb8436ea5bab642b1a22e07688e9f706e >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/MSLFunctionDeclaration.js >@@ -0,0 +1,124 @@ >+/* >+ * Copyright (C) 2018 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. ``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 >+ * 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. >+ */ >+ >+// Emits code for for the first line of a function declaration or definition. >+class MSLFunctionDeclaration { >+ >+ constructor(funcMangler, funcDef, typeNamer, typeAttributes) >+ { >+ this._funcMangler = funcMangler; >+ this._func = funcDef; >+ this._typeNamer = typeNamer; >+ this._typeAttributes = typeAttributes; >+ } >+ >+ get funcMangler() >+ { >+ return this._funcMangler; >+ } >+ >+ get func() >+ { >+ return this._func; >+ } >+ >+ get typeNamer() >+ { >+ return this._typeNamer; >+ } >+ >+ get typeAttributes() >+ { >+ return this._typeAttributes; >+ } >+ >+ get isVertexShader() >+ { >+ return this._func.shaderType == "vertex"; >+ } >+ >+ get paramMap() >+ { >+ const map = new Map(); >+ let counter = 0; >+ for (let param of this._func.parameters) >+ map.set(param, `P${counter++}`); >+ return map; >+ } >+ >+ commentLine() >+ { >+ const params = []; >+ for (let param of this.paramMap.keys()) >+ params.push(param.name); >+ return `// ${this._func.name}(${params.join(", ")}) @ ${this._func.origin.originString}\n`; >+ } >+ >+ toString() >+ { >+ let declLine = this.commentLine(); >+ >+ if (this.isShader) >+ declLine += `${this._func.shaderType} `; >+ declLine += `${this._typeNamer.mslTypeName(this._func.returnType)} `; >+ declLine += this._funcMangler.mangle(this.func); >+ declLine += "(" >+ >+ let params = []; >+ const paramMap = this.paramMap; >+ for (let param of this._func.parameters) { >+ let pStr = mslVarDeclaration(this._typeNamer, param.type, paramMap.get(param), true); >+ // FIXME: The parser doesn't currently support vertex shaders having uint parameters, so this doesn't work. >+ if (this.parameterIsVertexId(param) && this.isVertexShader) >+ pStr += " [[vertex_id]]"; >+ else if (this.parameterIsAttribute(param)) >+ pStr += " [[stage_in]]"; >+ params.push(pStr); >+ } >+ >+ declLine += params.join(", ") + ")"; >+ >+ return declLine; >+ } >+ >+ get isShader() >+ { >+ // FIXME: Support WHLSL "compute" shaders (MSL calls these kernel shaders) >+ return this.func.shaderType === "vertex" || this.func.shaderType === "fragment"; >+ } >+ >+ parameterIsAttribute(node) >+ { >+ // We currently assuming that all parameters to entry points are attributes. >+ // TODO: Better logic for this, i.e. support samplers. >+ return this.isShader; >+ } >+ >+ parameterIsVertexId(node) >+ { >+ // FIXME: This isn't final, and isn't formally specified yet. >+ return this.isVertexShader && node.name == "wsl_vertexID" && node.type.name == "uint32"; >+ } >+} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/MSLFunctionDefinition.js b/Tools/WebGPUShadingLanguageRI/Metal/MSLFunctionDefinition.js >new file mode 100644 >index 0000000000000000000000000000000000000000..0d2878a94a619096c2846280f78d22b83a98251a >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/MSLFunctionDefinition.js >@@ -0,0 +1,37 @@ >+/* >+ * Copyright (C) 2018 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. ``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 >+ * 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. >+ */ >+ >+class MSLFunctionDefinition extends MSLFunctionDeclaration >+{ >+ toString() >+ { >+ let src = super.toString(); >+ src += "\n{\n"; >+ let emitter = new MSLStatementEmitter(this.funcMangler, this.typeNamer, this.func, this.paramMap, this.func.name, this.typeAttributes); >+ src += emitter.indentedSource(); >+ src += "}"; >+ return src; >+ } >+} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/MSLFunctionForwardDeclaration.js b/Tools/WebGPUShadingLanguageRI/Metal/MSLFunctionForwardDeclaration.js >new file mode 100644 >index 0000000000000000000000000000000000000000..57c6f81353c1f381f967345f8987f3cfb91da518 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/MSLFunctionForwardDeclaration.js >@@ -0,0 +1,32 @@ >+/* >+ * Copyright (C) 2018 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. ``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 >+ * 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. >+ */ >+ >+class MSLFunctionForwardDeclaration extends MSLFunctionDeclaration >+{ >+ toString() >+ { >+ return super.toString() + ";" >+ } >+} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/MSLNameMangler.js b/Tools/WebGPUShadingLanguageRI/Metal/MSLNameMangler.js >new file mode 100644 >index 0000000000000000000000000000000000000000..49a30df91f821748132329629e5b55a520206bb1 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/MSLNameMangler.js >@@ -0,0 +1,41 @@ >+/* >+ * Copyright (C) 2018 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. ``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 >+ * 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. >+ */ >+ >+class MSLNameMangler { >+ >+ constructor(prefix) >+ { >+ this._prefix = prefix; >+ this._counter = 0; >+ this._mangledNameMap = new Map(); >+ } >+ >+ mangle(key) >+ { >+ if (!this._mangledNameMap.has(key)) >+ this._mangledNameMap.set(key, `${this._prefix}${this._counter++}`); >+ return this._mangledNameMap.get(key); >+ } >+} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/MSLNativeFunctionCall.js b/Tools/WebGPUShadingLanguageRI/Metal/MSLNativeFunctionCall.js >new file mode 100644 >index 0000000000000000000000000000000000000000..2ab8717fcd1ad70757fbf0a879cec91225813ccd >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/MSLNativeFunctionCall.js >@@ -0,0 +1,82 @@ >+/* >+ * Copyright (C) 2018 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. ``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 >+ * 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. >+ */ >+ >+"use strict"; >+ >+function mslNativeFunctionCall(node, resultVariable, args) >+{ >+ const key = node.toString(); >+ >+ // FIXME: Implement the sampling functions. >+ // FIXME: Implement functions like f16tof32, asfloat, etc. >+ // FIXME: Implement tests for all native functions https://bugs.webkit.org/show_bug.cgi?id=189535. >+ const functionsWithTheSameCallingConvention = { >+ "native bool isfinite(float)" : "isfinite", >+ "native bool isinf(float)" : "isinf", >+ "native bool isnormal(float)" : "isnormal", >+ "native bool isnormal(half)" : "isnormal", >+ "native float acos(float)" : "acos", >+ "native float asfloat(int)" : "static_cast<float>", >+ "native float asfloat(uint)" : "static_cast<float>", >+ "native int asint(float)" : "static_cast<int>", >+ "native uint asuint(float)" : "static_cast<uint>", >+ "native float asin(float)" : "asin", >+ "native float atan(float)" : "atan", >+ "native float atan2(float,float)" : "atan2", >+ "native float ceil(float)" : "ceil", >+ "native float cos(float)" : "cos", >+ "native float cosh(float)" : "cosh", >+ "native float ddx(float)" : "dfdx", >+ "native float ddy(float)" : "dfdy", >+ "native float exp(float)" : "exp", >+ "native float floor(float)" : "floor", >+ "native float log(float)" : "log", >+ "native float pow(float,float)" : "pow", >+ "native float round(float)" : "round", >+ "native float sin(float)" : "sin", >+ "native float sinh(float)" : "sinh", >+ "native float sqrt(float)" : "sqrt", >+ "native float tan(float)" : "tan", >+ "native float tanh(float)" : "tanh", >+ "native float trunc(float)" : "trunc", >+ }; >+ >+ if (key in functionsWithTheSameCallingConvention) { >+ const callString = `${functionsWithTheSameCallingConvention[key]}(${args.join(", ")})`; >+ if (resultVariable) >+ return `${resultVariable} = ${callString};`; >+ else >+ return `${callString};`; >+ } >+ >+ const functionsWithDifferentCallingConventions = { >+ "native uint f32tof16(float)" : () => `${resultVariable} = uint(static_cast<ushort>(half(${args[0]})));`, >+ "native float f16tof32(uint)" : () => `${resultVariable} = float(static_cast<half>(ushort(${args[0]})));` >+ }; >+ if (key in functionsWithDifferentCallingConventions) >+ return functionsWithDifferentCallingConventions[key](); >+ >+ throw new Error(`${node} doesn't have mapping to a native Metal function.`); >+} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/MSLStatementEmitter.js b/Tools/WebGPUShadingLanguageRI/Metal/MSLStatementEmitter.js >new file mode 100644 >index 0000000000000000000000000000000000000000..f14ad367e9309ed2f609aa98719c864b5a12423c >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/MSLStatementEmitter.js >@@ -0,0 +1,749 @@ >+/* >+ * Copyright (C) 2018 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. ``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 >+ * 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. >+ */ >+ >+class MSLStatementEmitter extends Visitor { >+ >+ constructor(funcMangler, typeNamer, func, paramMap, debugName, typeAttributes) >+ { >+ super(); >+ this._funcMangler = funcMangler; >+ this._typeNamer = typeNamer; >+ this._func = func; >+ this._nameMap = paramMap; >+ this._debugName = debugName; >+ this._typeAttributes = typeAttributes; >+ this._counter = 0; >+ this._indentLevel = 0; >+ this._lines = []; >+ >+ this._loopConditionVariableStack = []; >+ this._loopConditionNodeStack = []; >+ this._loopIncrementNodeStack = []; >+ >+ this._actualResult = this._func.visit(this); >+ } >+ >+ _emitTrap() >+ { >+ // FIXME: Handle traps. >+ } >+ >+ _zeroInitialize(type, variableName, allowComment = true) >+ { >+ const emitter = this; >+ >+ class ZeroInitializer extends Visitor { >+ visitNativeType(node) >+ { >+ if (node.name == "bool") >+ emitter._add(`${variableName} = false;`); >+ else >+ emitter._add(`${variableName} = 0;`); >+ } >+ >+ visitPtrType(node) >+ { >+ emitter._add(`${variableName} = nullptr;`); >+ } >+ >+ visitArrayType(node) >+ { >+ for (let i = 0; i < node.numElements.value; i++) >+ emitter._zeroInitialize(node.elementType, `${variableName}[${i}]`, false); >+ } >+ >+ visitArrayRefType(node) >+ { >+ emitter._add(`${variableName}.ptr = nullptr;`); >+ emitter._add(`${variableName}.length = 0;`); >+ } >+ >+ visitEnumType(node) >+ { >+ emitter._zeroInitialize(node.baseType, variableName, false); >+ } >+ >+ visitStructType(node) >+ { >+ const typeAttributes = emitter._typeAttributes.attributesForType(node); >+ >+ for (let field of node.fields) { >+ const fieldName = typeAttributes.mangledFieldName(field.name); >+ emitter._zeroInitialize(field.type, `${variableName}.${fieldName}`, false); >+ } >+ } >+ >+ visitVectorType(node) >+ { >+ const elementNames = [ "x", "y", "z", "w" ]; >+ for (let i = 0; i < node.numElementsValue; i++) >+ emitter._add(`${variableName}.${elementNames[i]} = 0;`); >+ } >+ >+ visitMatrixType(node) >+ { >+ for (let i = 0; i < node.numRowsValue; i++) { >+ for (let j = 0; j < node.numRowsValue; j++) >+ emitter._zeroInitialize(node.elementType, `${variableName}[${i}][${j}]`, false); >+ } >+ } >+ >+ visitTypeRef(node) >+ { >+ node.type.visit(this); >+ } >+ } >+ if (allowComment) >+ this._add(`// Zero initialization of ${variableName}`); >+ Node.visit(type, new ZeroInitializer()); >+ } >+ >+ get actualResult() >+ { >+ return this._actualResult; >+ } >+ >+ get lines() >+ { >+ return this._lines; >+ } >+ >+ indentedSource() >+ { >+ return this._lines.map(line => " " + line + "\n").join(""); >+ } >+ >+ get _loopConditionVariable() >+ { >+ return this._loopConditionVariableStack[this._loopConditionVariableStack.length - 1]; >+ } >+ >+ get _loopCondition() >+ { >+ return this._loopConditionNodeStack[this._loopConditionNodeStack.length - 1]; >+ } >+ >+ get _loopIncrement() >+ { >+ return this._loopIncrementNodeStack[this._loopIncrementNodeStack.length - 1]; >+ } >+ >+ _add(linesString) >+ { >+ for (let line of linesString.split('\n')) { >+ for (let i = 0; i < this._indentLevel; i++) >+ line = " " + line; >+ this._lines.push(line); >+ } >+ } >+ >+ _addLines(lines) >+ { >+ for (let line of lines) >+ this._add(line); >+ } >+ >+ _fresh() >+ { >+ return `V${this._counter++}`; >+ } >+ >+ _indent(closure) >+ { >+ this._indentLevel++; >+ const result = closure(); >+ this._indentLevel--; >+ return result; >+ } >+ >+ // Atomic statements. >+ >+ visitBreak(node) >+ { >+ this._add("break;") >+ } >+ >+ visitContinue(node) >+ { >+ // This is necessary because for loops are compiled as while loops, so we need to do >+ // the loop increment and condition check before returning to the beginning of the loop. >+ this._emitLoopBodyEnd(); >+ this._add("continue;"); >+ } >+ >+ // Basic compound statements. >+ >+ visitBlock(block) >+ { >+ for (let statement of block.statements) { >+ this._add(`// ${this._debugName} @ ${statement.origin.originString}`); >+ statement.visit(this); >+ } >+ } >+ >+ visitReturn(node) >+ { >+ const expr = node.value.visit(this); >+ this._add(`return ${expr};`); >+ } >+ >+ _visitAndIndent(node) >+ { >+ return this._indent(() => node.visit(this)); >+ } >+ >+ visitIfStatement(node) >+ { >+ let condition = node.conditional.visit(this); >+ this._add(`if (${condition}) {`); >+ this._visitAndIndent(node.body); >+ // At the moment the parser emits Block nodes for the if and else bodies, so this allows us >+ // to check whether or not the else body is actually empty, and therefore doesn't need to be emitted. >+ // (This isn't necessary, it just yields shorter, easier to read output). >+ const shouldEmitElseBody = node.elseBody && (!(node.elseBody instanceof Block) || node.elseBody.statements.length); >+ if (shouldEmitElseBody) { >+ this._add(`} else {`); >+ this._visitAndIndent(node.elseBody); >+ this._add('}'); >+ } else >+ this._add('}'); >+ } >+ >+ visitIdentityExpression(node) >+ { >+ return node.target.visit(this); >+ } >+ >+ visitLogicalNot(node) >+ { >+ const type = typeOf(node); >+ let expr = Node.visit(node.operand, this); >+ let id = this._fresh(); >+ this._add(mslVarDeclaration(this._typeNamer, type, id) + ";"); >+ this._add(`${id} = !(${expr});`); >+ return id; >+ } >+ >+ visitDereferenceExpression(node) >+ { >+ return `(*(${node.ptr.visit(this)}))`; >+ } >+ >+ _isOperatorAnder(node) >+ { >+ const anderRegex = /^operator\&\.(.*?)$/; >+ return node instanceof NativeFunc && anderRegex.test(node.name); >+ } >+ >+ _isOperatorGetter(node) >+ { >+ const getterRegex = /^operator\.(.*?)$/; >+ return node instanceof NativeFunc && getterRegex.test(node.name); >+ } >+ >+ _isOperatorIndexer(node) >+ { >+ return node instanceof NativeFunc && node.name == "operator&[]"; >+ } >+ >+ _isOperatorSetter(node) >+ { >+ const setterRegex = /^operator\.(.*?)=$/; >+ return node instanceof NativeFunc && setterRegex.test(node.name) >+ } >+ >+ _isOperatorCast(node) >+ { >+ return node instanceof NativeFunc && node.name == "operator cast"; >+ } >+ >+ _isUnaryOperator(node) >+ { >+ const operatorRegex = /^operator\~$/; >+ return node instanceof NativeFunc && operatorRegex.test(node.name); >+ } >+ >+ _isBinaryOperator(node) >+ { >+ const operatorRegex = /operator(\+|\-|\*|\/|\^|\&|\||\&\&|\|\||\<\<|\>\>|\<|\<\=|\>|\>\=|\=\=|\!\=)$/; >+ return node instanceof NativeFunc && operatorRegex.test(node.name); >+ } >+ >+ _isOperatorValue(node) >+ { >+ return node instanceof NativeFunc && node.name == "operator.value"; >+ } >+ >+ _isOperatorLength(node) >+ { >+ return node instanceof NativeFunc && node.name == "operator.length"; >+ } >+ >+ _extractOperatorName(node) >+ { >+ return node.name.substring("operator".length); >+ } >+ >+ visitVariableDecl(node) >+ { >+ let id = this._fresh(); >+ this._nameMap.set(node, id); >+ >+ this._add(`${mslVarDeclaration(this._typeNamer, node.type, id)}; // ${node.name}`); >+ >+ if (node.initializer) { >+ let expr = node.initializer.visit(this); >+ this._add(`${id} = ${expr};`); >+ } else >+ this._zeroInitialize(node.type, id); >+ } >+ >+ visitVariableRef(node) >+ { >+ if (!this._nameMap.has(node.variable)) >+ throw new Error(`${node.variable} not found in this function's (${this._func.name}) variable map`); >+ return this._nameMap.get(node.variable); >+ } >+ >+ visitMakeArrayRefExpression(node) >+ { >+ const elemName = Node.visit(node.lValue, this); >+ const arrayType = typeOf(node.lValue); >+ const id = this._fresh(); >+ this._add(mslVarDeclaration(this._typeNamer, node.type, id) + ";"); >+ this._add(`${id}.length = ${node.numElements.value};`); >+ if (arrayType.isArray) >+ this._add(`${id}.ptr = ${elemName};`); >+ else >+ this._add(`${id}.ptr = &(${elemName});`); >+ return id; >+ } >+ >+ visitConvertPtrToArrayRefExpression(node) >+ { >+ const lValue = node.lValue.visit(this); >+ const type = typeOf(node); >+ const id = this._fresh(); >+ this._add(mslVarDeclaration(this._typeNamer, type, id) + ";"); >+ this._add(`${id}.length = 1;`); >+ this._add(`${id}.ptr = ${lValue};`); >+ return id; >+ } >+ >+ visitAnonymousVariable(node) >+ { >+ let id = this._fresh(); >+ this._nameMap.set(node, id); >+ this._add(mslVarDeclaration(this._typeNamer, node.type, id) + `; // ${node.name}`); >+ this._zeroInitialize(node.type, id); >+ return id; >+ } >+ >+ visitAssignment(node) >+ { >+ const lhs = Node.visit(node.lhs, this); >+ const rhs = Node.visit(node.rhs, this); >+ this._add(`${lhs} = ${rhs};`); >+ return lhs; >+ } >+ >+ visitCommaExpression(node) >+ { >+ let result; >+ for (let expr of node.list) >+ result = Node.visit(expr, this); >+ return result; >+ } >+ >+ visitCallExpression(node) >+ { >+ const args = []; >+ for (let i = node.argumentList.length; i--;) >+ args.unshift(node.argumentList[i].visit(this)); >+ >+ let resultVariable; >+ if (node.func.returnType.name !== "void") { >+ resultVariable = this._fresh(); >+ this._add(`// Result variable for call ${node.func.name}(${args.join(", ")})`); >+ this._add(`${mslVarDeclaration(this._typeNamer, node.resultType, resultVariable)};`); >+ } >+ >+ if (node.func instanceof FuncDef) { >+ const mangledCallName = this._funcMangler.mangle(node.func); >+ const callString = `${mangledCallName}(${args.join(", ")})`; >+ if (resultVariable) >+ this._add(`${resultVariable} = ${callString};`); >+ else >+ this._add(`${callString};`); >+ } else >+ this._makeNativeFunctionCall(node.func, resultVariable, args); >+ >+ return resultVariable; >+ } >+ >+ _makeNativeFunctionCall(node, resultVariable, args) >+ { >+ if (!(node instanceof NativeFunc)) >+ throw new Error(`${node} should be a native function.`); >+ >+ if (this._isOperatorAnder(node)) >+ this._emitOperatorAnder(node, resultVariable, args); >+ else if (node.implementationData instanceof BuiltinVectorGetter) >+ this._emitBuiltinVectorGetter(node, resultVariable, args); >+ else if (node.implementationData instanceof BuiltinVectorSetter) >+ this._emitBuiltinVectorSetter(node, resultVariable, args); >+ else if (node.implementationData instanceof BuiltinMatrixGetter) >+ this._emitBuiltinMatrixGetter(node, resultVariable, args); >+ else if (node.implementationData instanceof BuiltinMatrixSetter) >+ this._emitBuiltinMatrixSetter(node, resultVariable, args); >+ else if (this._isOperatorValue(node)) >+ this._add(`${resultVariable} = ${args[0]};`); >+ else if (this._isOperatorLength(node)) >+ this._emitOperatorLength(node, resultVariable, args); >+ else if (this._isOperatorSetter(node)) >+ this._emitOperatorSetter(node, resultVariable, args); >+ else if (this._isOperatorGetter(node)) >+ this._emitOperatorGetter(node, resultVariable, args); >+ else if (this._isOperatorIndexer(node)) >+ this._emitOperatorIndexer(node, resultVariable, args); >+ else if (this._isOperatorCast(node)) >+ this._emitOperatorCast(node, resultVariable, args); >+ else if (this._isUnaryOperator(node)) >+ this._add(`${resultVariable} = ${this._extractOperatorName(node)}(${args[0]});`); >+ else if (this._isBinaryOperator(node)) >+ this._add(`${resultVariable} = ${args[0]} ${this._extractOperatorName(node)} ${args[1]};`); >+ else >+ this._add(mslNativeFunctionCall(node, resultVariable, args)); >+ >+ return resultVariable; >+ } >+ >+ _emitCallToMetalFunction(name, result, args) >+ { >+ this._add(`${result} = ${name}(${args.join(", ")});`); >+ } >+ >+ _emitBuiltinVectorGetter(node, result, args) >+ { >+ this._add(`${result} = ${args[0]}.${node.implementationData.elementName};`); >+ } >+ >+ _emitBuiltinVectorSetter(node, result, args) >+ { >+ this._add(`${result} = ${args[0]};`); >+ this._add(`${result}.${node.implementationData.elementName} = ${args[1]};`); >+ } >+ >+ _emitBuiltinMatrixGetter(node, result, args) >+ { >+ this._add(`if (${args[1]} >= ${node.implementationData.height}) {`); >+ this._indent(() => this._emitTrap()); >+ this._add('}'); >+ this._add(`${result} = ${args[0]}[${args[1]}];`); >+ } >+ >+ _emitBuiltinMatrixSetter(node, result, args) >+ { >+ this._add(`if (${args[1]} >= ${node.implementationData.height}) {`); >+ this._indent(() => this._emitTrap()); >+ this._add('}'); >+ this._add(`${result} = ${args[0]};`); >+ this._add(`${result}[${args[1]}] = ${args[2]};`); >+ } >+ >+ _emitOperatorLength(node, result, args) >+ { >+ const paramType = typeOf(node.parameters[0]); >+ if (paramType instanceof ArrayRefType) >+ this._add(`${result} = ${args[0]}.length;`); >+ else if (paramType instanceof ArrayType) >+ this._add(`${result} = ${paramType.numElements.visit(this)};`); >+ else >+ throw new Error(`Unhandled paramter type ${paramType} for operator.length`); >+ } >+ >+ _emitOperatorCast(node, result, args) >+ { >+ const retType = this._typeNamer.mslTypeName(node.returnType); >+ this._add(`${result} = ${retType}(${args.join(", ")});`); >+ } >+ >+ _emitOperatorIndexer(node, result, args) >+ { >+ if (!(typeOf(node.parameters[0]) instanceof ArrayRefType)) >+ throw new Error(`Support for operator&[] ${node.parameters[0]} not implemented.`); >+ >+ this._add(`if (${args[1]} >= ${args[0]}.length) {`); >+ this._indent(() => this._emitTrap()); >+ this._add(`}`); >+ this._add(`// Operator indexer`); >+ this._add(`${result} = &(${args[0]}.ptr[${args[1]}]);`); >+ } >+ >+ _emitOperatorAnder(node, result, args) >+ { >+ const type = node.implementationData.type; >+ const field = this._typeAttributes.attributesForType(type).mangledFieldName(node.implementationData.name); >+ this._add(`${result} = &((${args[0]})->${field});`); >+ } >+ >+ _emitOperatorGetter(node, result, args) >+ { >+ const type = node.implementationData.type; >+ const field = this._typeAttributes.attributesForType(type).mangledFieldName(node.implementationData.name); >+ this._add(`${result} = ${args[0]}.${field};`); >+ } >+ >+ _emitOperatorSetter(node, result, args) >+ { >+ // FIXME: Currently no WHLSL source produces structs that only have getters/setters rather than the ander, >+ // and the ander is always preferred over the getter and setter. Therefore this code is untested. >+ const type = node.implementationData.type; >+ const field = this._typeAttributes.attributesForType(type).mangledFieldName(node.implementationData.name); >+ this._add(`${args[0]}.${field} = ${args[1]};`); >+ this._add(`${result} = ${args[0]}`); >+ } >+ >+ visitMakePtrExpression(node) >+ { >+ return `&(${node.lValue.visit(this)})`; >+ } >+ >+ // Loop code generation. Loops all follow the same style where they declare a conditional variable (boolean) >+ // which is checked on each iteration (all loops are compiled to a while loop or do/while loop). The check is >+ // emitted in _emitLoopCondition. For loops additionally have _emitLoopBodyEnd for the increment on each iteration. >+ >+ visitForLoop(node) >+ { >+ this._emitAsLoop(node.condition, node.increment, (conditionVar) => { >+ Node.visit(node.initialization, this); >+ this._emitLoopCondition(); >+ this._add(`while (${conditionVar}) {`); >+ this._indent(() => { >+ node.body.visit(this); >+ this._emitLoopBodyEnd(); >+ }); >+ this._add('}'); >+ }); >+ } >+ >+ visitWhileLoop(node) >+ { >+ this._emitAsLoop(node.conditional, null, (conditionVar) => { >+ this._add(`while (${conditionVar}) {`); >+ this._indent(() => { >+ node.body.visit(this); >+ this._emitLoopCondition(); >+ }); >+ this._add('}'); >+ }); >+ } >+ >+ visitDoWhileLoop(node) >+ { >+ this._emitAsLoop(node.conditional, null, conditionVar => { >+ this._add("do {"); >+ this._indent(() => { >+ node.body.visit(this); >+ this._emitLoopBodyEnd(); >+ }); >+ this._add(`} while (${conditionVar});`); >+ }); >+ } >+ >+ _emitAsLoop(conditional, increment, emitLoopBody) >+ { >+ const conditionVar = this._fresh(); >+ this._loopConditionVariableStack.push(conditionVar); >+ this._loopConditionNodeStack.push(conditional); >+ this._loopIncrementNodeStack.push(increment); >+ this._add(`bool ${conditionVar} = true;`); >+ >+ emitLoopBody(conditionVar); >+ >+ this._loopIncrementNodeStack.pop(); >+ this._loopConditionVariableStack.pop(); >+ this._loopConditionNodeStack.pop(); >+ } >+ >+ _emitLoopBodyEnd() >+ { >+ this._emitLoopIncrement(); >+ this._emitLoopCondition(); >+ } >+ >+ _emitLoopIncrement() >+ { >+ Node.visit(this._loopIncrement, this); >+ } >+ >+ _emitLoopCondition() >+ { >+ if (this._loopCondition) { >+ const conditionResult = this._loopCondition.visit(this); >+ this._add(`${this._loopConditionVariable} = ${conditionResult};`); >+ } >+ } >+ >+ // Switch statements. >+ >+ visitSwitchStatement(node) >+ { >+ const caseValueEmitter = new MSLConstexprEmitter(); >+ >+ let switchValue = Node.visit(node.value, this); >+ this._add(`switch (${switchValue}) {`); >+ this._indent(() => { >+ for (let i = 0; i < node.switchCases.length; i++) { >+ let switchCase = node.switchCases[i]; >+ if (!switchCase.isDefault) >+ this._add(`case ${switchCase.value.visit(caseValueEmitter)}: {`); >+ else >+ this._add("default: {"); >+ this._visitAndIndent(switchCase.body); >+ this._add("}"); >+ } >+ }); >+ this._add("}"); >+ } >+ >+ visitSwitchCase(node) >+ { >+ throw new Error(`MSLStatementEmitter.visitSwitchCase called; switch statements should be fully handled by MSLStatementEmitter.visitSwitchStatement.`); >+ } >+ >+ // Literals >+ >+ visitBoolLiteral(node) >+ { >+ const fresh = this._fresh(); >+ this._add(`bool ${fresh} = ${node.value};`); >+ return fresh; >+ } >+ >+ visitEnumLiteral(node) >+ { >+ return node.member.value.visit(this); >+ } >+ >+ visitGenericLiteral(node) >+ { >+ const fresh = this._fresh(); >+ this._add(mslVarDeclaration(this._typeNamer, node.type, fresh) + ";"); >+ this._add(`${fresh} = ${node.value};`); >+ return fresh; >+ } >+ >+ visitNullLiteral(node) >+ { >+ return `nullptr`; >+ } >+ >+ visitDotExpression(node) >+ { >+ throw new Error(`MSLStatementEmitter.visitDotExpression called; ${node} should have been converted to an operator function call.`); >+ } >+ >+ visitTrapStatement(node) >+ { >+ this._emitTrap(); >+ } >+ >+ visitLogicalExpression(node) >+ { >+ const result = this._fresh(); >+ this._add(`// Result variable for ${node.text}`); >+ this._add(`bool ${result};`); >+ if (node.text == "&&") { >+ const left = node.left.visit(this); >+ this._add(`if (!${left}) {`) >+ this._indent(() => this._add(`${result} = false;`)); >+ this._add('} else {'); >+ this._indent(() => this._add(`${result} = ${node.right.visit(this)};`)); >+ this._add('}'); >+ } else if (node.text == "||") { >+ const left = node.left.visit(this); >+ this._add(`${result} = ${left};`); >+ this._add(`if (!${result}) {`); >+ this._indent(() => this._add(`${result} = ${node.right.visit(this)};`)); >+ this._add("}"); >+ } else >+ throw new Error(`Unrecognized logical expression ${node.text}`); >+ return result; >+ } >+ >+ visitTernaryExpression(node) >+ { >+ // FIXME: If each of the three expressions isn't a compound expression or statement then just use ternary syntax. >+ let resultType = typeOf(node.bodyExpression); >+ if (node.isLValue) >+ resultType = new PtrType(node.origin, "thread", resultType); >+ let resultVar = this._fresh(); >+ this._add(mslVarDeclaration(this._typeNamer, resultType, resultVar) + ";"); >+ const predicate = node.predicate.visit(this); >+ this._add(`if (${predicate}) {`); >+ this._indent(() => { >+ const bodyExpression = node.bodyExpression.visit(this); >+ if (node.isLValue) >+ this._add(`${resultVar} = &(${bodyExpression});`); >+ else >+ this._add(`${resultVar} = ${bodyExpression};`); >+ }); >+ this._add("} else {"); >+ this._indent(() => { >+ const elseExpression = node.elseExpression.visit(this); >+ if (node.isLValue) >+ this._add(`${resultVar} = &(${elseExpression});`); >+ else >+ this._add(`${resultVar} = ${elseExpression};`); >+ }); >+ this._add("}"); >+ >+ if (node.isLValue) >+ resultVar = `*(${resultVar})`; >+ >+ return resultVar; >+ } >+ >+ visitIndexExpression(node) >+ { >+ throw new Error("MSLStatementEmitter.visitIndexExpression is not implemented; IndexExpression should not appear in the AST for Metal codegen."); >+ } >+ >+ visitNativeFunc(node) >+ { >+ throw new Error("MSLStatementEmitter.visitNativeFunc is not implemented; NativeFunction is not compiled by the Metal codegen."); >+ } >+ >+ visitNativeTypeInstance(node) >+ { >+ throw new Error("MSLStatementEmitter.visitNativeTypeInstance is not implemented."); >+ } >+ >+ visitReadModifyWriteExpression(node) >+ { >+ throw new Error("MSLStatementEmitter.visitReadModifyWriteExpression is not implemented; it should have been transformed out the tree in earlier stage."); >+ } >+} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/MSLTypeAttributes.js b/Tools/WebGPUShadingLanguageRI/Metal/MSLTypeAttributes.js >new file mode 100644 >index 0000000000000000000000000000000000000000..d6f1676130a8d03fb2f757b9c2b7ed8c41ca1750 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/MSLTypeAttributes.js >@@ -0,0 +1,86 @@ >+/* >+ * Copyright (C) 2018 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. ``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 >+ * 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. >+ */ >+ >+class MSLTypeAttributes { >+ >+ constructor(type) >+ { >+ this._type = type; >+ this._isVertexAttribute = false; >+ this._isVertexOutputOrFragmentInput = false; >+ this._isFragmentOutput = false; >+ this._fieldMangler = new MSLNameMangler('field'); >+ >+ if (type instanceof StructType) { >+ for (let field of type.fields) >+ this._fieldMangler.mangle(field.name) >+ } >+ } >+ >+ get type() >+ { >+ return this._type; >+ } >+ >+ get isVertexAttribute() >+ { >+ return this._isVertexAttribute; >+ } >+ >+ set isVertexAttribute(va) >+ { >+ this._isVertexAttribute = va; >+ } >+ >+ get isVertexOutputOrFragmentInput() >+ { >+ return this._isVertexOutputOrFragmentInput; >+ } >+ >+ set isVertexOutputOrFragmentInput(vo) >+ { >+ this._isVertexOutputOrFragmentInput = vo; >+ } >+ >+ get isFragmentOutput() >+ { >+ return this._isFragmentOutput; >+ } >+ >+ set isFragmentOutput(fo) >+ { >+ this._isFragmentOutput = fo; >+ } >+ >+ get fieldMangler() >+ { >+ return this._fieldMangler; >+ } >+ >+ mangledFieldName(fieldName) >+ { >+ return this.fieldMangler.mangle(fieldName); >+ } >+} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/MSLTypeAttributesMap.js b/Tools/WebGPUShadingLanguageRI/Metal/MSLTypeAttributesMap.js >new file mode 100644 >index 0000000000000000000000000000000000000000..373b0e8c0fe93488988b6f830c7a9c6f703a28f6 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/MSLTypeAttributesMap.js >@@ -0,0 +1,66 @@ >+/* >+ * Copyright (C) 2018 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. ``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 >+ * 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. >+ */ >+ >+// Provides lookup for all the top level types in the program. >+class MSLTypeAttributesMap { >+ >+ constructor(functionDefs, typeUnifier) >+ { >+ this._typeUnifier = typeUnifier; >+ this._typeAttributeMap = new Map(); >+ >+ for (let funcDef of functionDefs) { >+ if (funcDef.shaderType == "vertex") >+ this._visitVertexShader(funcDef); >+ else if (funcDef.shaderType == "fragment") >+ this._visitFragmentShader(funcDef); >+ } >+ } >+ >+ attributesForType(type) >+ { >+ const key = this._typeUnifier.uniqueTypeId(type); >+ let attrs = this._typeAttributeMap.get(key); >+ if (!attrs) >+ this._typeAttributeMap.set(key, attrs = new MSLTypeAttributes(type)); >+ return attrs; >+ } >+ >+ _visitVertexShader(func) >+ { >+ this.attributesForType(func.returnType).isVertexOutputOrFragmentInput = true; >+ for (let param of func.parameters) >+ this.attributesForType(param.type).isVertexAttribute = true; >+ } >+ >+ _visitFragmentShader(func) >+ { >+ this.attributesForType(func.returnType).isFragmentOutput = true; >+ for (let param of func.parameters) >+ this.attributesForType(param.type).isVertexOutputOrFragmentInput = true; >+ } >+ >+ // FIXME: Support compute shaders. >+} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/MSLTypeNamer.js b/Tools/WebGPUShadingLanguageRI/Metal/MSLTypeNamer.js >new file mode 100644 >index 0000000000000000000000000000000000000000..8c4dd61a37216534917cd21ae97bbd608eb9f10a >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/MSLTypeNamer.js >@@ -0,0 +1,148 @@ >+/* >+ * Copyright (C) 2018 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. ``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 >+ * 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. >+ */ >+ >+class MSLTypeNamer { >+ >+ constructor(typeUnifier) >+ { >+ this._typeUnifier = typeUnifier; >+ } >+ >+ get typeUnifier() >+ { >+ return this._typeUnifier; >+ } >+ >+ uniqueTypeId(type) >+ { >+ return this.typeUnifier.uniqueTypeId(type); >+ } >+ >+ // Yields the string that should be used in MSL source for the type. >+ mslTypeName(type) >+ { >+ let name; >+ >+ const typeUnifier = this.typeUnifier; >+ const typeNamer = this; >+ let emittedAddressSpaceForArray = false; >+ >+ class TypeNameVisitor extends Visitor { >+ visitNativeType(node) >+ { >+ // FIXME: Also add samplers and textures here. >+ const nativeTypeNameMap = { >+ "void": "void", >+ "bool": "bool", >+ "uchar": "uint8_t", >+ "ushort": "uint16_t", >+ "uint": "uint32_t", >+ "char": "int8_t", >+ "short": "int16_t", >+ "int": "int32_t", >+ "half": "half", >+ "float": "float", >+ "atomic_int": "atomic_int", >+ "atomic_uint": "atomic_uint" >+ }; >+ >+ name = nativeTypeNameMap[node.name]; >+ } >+ >+ visitStructType(node) >+ { >+ name = typeUnifier.uniqueTypeId(node); >+ } >+ >+ visitEnumType(node) >+ { >+ return Node.visit(node.baseType, this); >+ } >+ >+ visitReferenceType(node) >+ { >+ name = `${node.addressSpace} ${typeNamer.mslTypeName(node.elementType)}*`; >+ } >+ >+ visitArrayType(node) >+ { >+ name = `${node.addressSpace ? node.addressSpace + " " : ""}${typeNamer.mslTypeName(node.elementType)}*`; >+ } >+ >+ visitArrayRefType(node) >+ { >+ name = typeUnifier.uniqueTypeId(node); >+ } >+ >+ visitVectorType(node) >+ { >+ // Vector type names work slightly differently to native type names >+ const elementTypeNameMap = { >+ "bool": "bool", >+ "char": "char", >+ "uchar": "uchar", >+ "short": "short", >+ "ushort": "ushort", >+ "int": "int", >+ "uint": "uint", >+ "half": "half", >+ "float": "float" >+ }; >+ >+ const elementTypeName = elementTypeNameMap[node.elementType.name]; >+ if (!elementTypeName) >+ throw new Error(`${node.elementType.name} is not a supported vector element type`); >+ >+ name = `${elementTypeName}${node.numElementsValue}`; >+ } >+ >+ visitTypeRef(node) >+ { >+ node.type.visit(this); >+ } >+ >+ visitMatrixType(node) >+ { >+ const elementTypeNameMap = { >+ "half": "half", >+ "float": "float" >+ }; >+ >+ const elementTypeName = elementTypeNameMap[node.elementType.name]; >+ if (!elementTypeName) >+ throw new Error(`${node.elementType.name} is not a supported matrix element type`); >+ >+ name = `${elementTypeName}${node.numRowsValue}x${node.numColumnsValue}`; >+ } >+ } >+ >+ type.visit(new TypeNameVisitor()); >+ >+ if (!name) >+ throw new Error(`${type} doesn't have a name`); >+ >+ return name; >+ } >+} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/MSLTypeUnifier.js b/Tools/WebGPUShadingLanguageRI/Metal/MSLTypeUnifier.js >new file mode 100644 >index 0000000000000000000000000000000000000000..8b9bbcbb5b0eb837569c88c2fb1ffda8ca7e46bd >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/MSLTypeUnifier.js >@@ -0,0 +1,132 @@ >+/* >+ * Copyright (C) 2018 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. ``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 >+ * 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. >+ */ >+ >+ >+class MSLTypeUnifier extends Visitor { >+ >+ constructor() >+ { >+ super(); >+ >+ this._typeNameMangler = new MSLNameMangler('T'); >+ this._allTypes = new Set(); >+ } >+ >+ get allTypes() >+ { >+ return this._allTypes; >+ } >+ >+ uniqueTypeId(type) >+ { >+ return type.visit(this); >+ } >+ >+ visitTypeRef(node) >+ { >+ if ((node.typeArguments && node.typeArguments.length) || !node.name) { >+ return node.type.visit(this); >+ } >+ >+ if (!this._allTypes.has(node.type)) >+ node.type.visit(this); >+ >+ const baseType = typeOf(node); >+ >+ if (baseType instanceof NativeType || baseType instanceof VectorType) >+ return baseType.visit(this); >+ >+ return this._typeNameMangler.mangle(node.name); >+ } >+ >+ visitStructType(node) >+ { >+ this._allTypes.add(node); >+ for (let field of node.fields) >+ field.visit(this); >+ return this._typeNameMangler.mangle(node.name); >+ } >+ >+ visitEnumType(node) >+ { >+ this._allTypes.add(node); >+ node.baseType.visit(this); >+ return this._typeNameMangler.mangle(node.name); >+ } >+ >+ visitNativeType(node) >+ { >+ this._allTypes.add(node); >+ return node.name; >+ } >+ >+ visitPtrType(node) >+ { >+ this._allTypes.add(node); >+ node.elementType.visit(this); >+ return `${node.elementType.visit(this)}* ${node.addressSpace}`; >+ } >+ >+ visitArrayType(node) >+ { >+ this._allTypes.add(node); >+ node.elementType.visit(this); >+ return `${node.elementType.visit(this)}[${node.numElements}]`; >+ } >+ >+ visitArrayRefType(node) >+ { >+ this._allTypes.add(node); >+ // The name mangler is used here because array refs are "user-defined" types in the sense >+ // that they will need to be defined as structs in the Metal output. >+ return this._typeNameMangler.mangle(`${node.elementType.visit(this)}[] ${node.addressSpace}`); >+ } >+ >+ visitVectorType(node) >+ { >+ this._allTypes.add(node); >+ return node.toString(); >+ } >+ >+ visitMakeArrayRefExpression(node) >+ { >+ super.visitMakeArrayRefExpression(node); >+ return node.type.visit(this); >+ } >+ >+ typesThatNeedDeclaration() >+ { >+ const declSet = new Set(); >+ const nameSet = new Set(); >+ for (let type of this._allTypes) { >+ const name = type.visit(this); >+ if ((type instanceof StructType || type instanceof ArrayRefType) && !nameSet.has(name)) { >+ declSet.add(type); >+ nameSet.add(name); >+ } >+ } >+ return declSet; >+ } >+} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/MSLVarDeclaration.js b/Tools/WebGPUShadingLanguageRI/Metal/MSLVarDeclaration.js >new file mode 100644 >index 0000000000000000000000000000000000000000..355638c87ede6f1baacf8616ab8bf0f0bec76340 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/MSLVarDeclaration.js >@@ -0,0 +1,46 @@ >+/* >+ * Copyright (C) 2018 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. ``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 >+ * 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. >+ */ >+ >+function mslVarDeclaration(typeNamer, type, name, treatArrayAsPointer = false) >+{ >+ type = typeOf(type); // Unwrap TypeRef if necessary >+ if (type.isArray) { >+ let arrayType = type; >+ const sizes = [ arrayType.numElementsValue ]; >+ let elementType = typeOf(arrayType.elementType); >+ while (elementType.isArray) { >+ arrayType = elementType; >+ sizes.push(arrayType.numElementsValue); >+ elementType = arrayType.elementType; >+ } >+ if (treatArrayAsPointer) >+ return `${arrayType.addressSpace ? arrayType.addressSpace : "thread"} ${typeNamer.mslTypeName(elementType)} (*${name})${sizes.slice(1).map(size => `[${size}]`).join('')}`; >+ else >+ return `${typeNamer.mslTypeName(elementType)} ${name}${sizes.map(size => `[${size}]`).join('')}`; >+ } else if (type.isPtr) >+ return (type).addressSpace + " " + mslVarDeclaration(typeNamer, (type).elementType, `(*${name})`); >+ else >+ return `${typeNamer.mslTypeName(type)} ${name}`; >+} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/TypeOf.js b/Tools/WebGPUShadingLanguageRI/Metal/TypeOf.js >new file mode 100644 >index 0000000000000000000000000000000000000000..a1be79332a9c28843228fac3c770d905889b4771 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/TypeOf.js >@@ -0,0 +1,325 @@ >+/* >+ * Copyright (C) 2018 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. ``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 >+ * 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. >+ */ >+ >+// FIXME: Rather than being a separate function this should instead be a separate preparation phase that annotates >+// each Node instance with a "type" property. https://bugs.webkit.org/show_bug.cgi?id=189611 >+function typeOf(node) { >+ class TypeVisitor extends Visitor { >+ visitAnonymousVariable(node) >+ { >+ return node.type.visit(this); >+ } >+ >+ visitArrayRefType(node) >+ { >+ return node; >+ } >+ >+ visitArrayType(node) >+ { >+ return node; >+ } >+ >+ visitAssignment(node) >+ { >+ return node.type.visit(this); >+ } >+ >+ visitCallExpression(node) >+ { >+ return node.func.visit(this); >+ } >+ >+ visitCommaExpression(node) >+ { >+ return node.list[node.list.length - 1].visit(this); >+ } >+ >+ visitConvertPtrToArrayRefExpression(node) >+ { >+ const ptrType = typeOf(node.lValue); >+ return new ArrayRefType(node.origin, ptrType.addressSpace, ptrType.elementType); >+ } >+ >+ visitDotExpression(node) >+ { >+ return node.struct.fieldMap.get(node.fieldName).type.visit(this); >+ } >+ >+ visitElementalType(node) >+ { >+ return node; >+ } >+ >+ visitEnumType(node) >+ { >+ return node; >+ } >+ >+ visitField(node) >+ { >+ return node.type.visit(this); >+ } >+ >+ visitFunc(node) >+ { >+ return node.returnType.visit(this); >+ } >+ >+ visitFuncDef(node) >+ { >+ return node.returnType.visit(this); >+ } >+ >+ visitFuncParameter(node) >+ { >+ return node.type.visit(this); >+ } >+ >+ visitFunctionLikeBlock(node) >+ { >+ return node.returnType.visit(this); >+ } >+ >+ visitGenericLiteralType(node) >+ { >+ return typeOf(node.type); >+ } >+ >+ visitIdentityExpression(node) >+ { >+ return node.target.visit(this); >+ } >+ >+ visitIndexExpression(node) >+ { >+ return node.array.elementType.visit(this); >+ } >+ >+ visitLogicalExpression(node) >+ { >+ throw new Error("FIXME: Implement TypeVisitor.visitLogicalExpression"); >+ } >+ >+ visitLogicalNot(node) >+ { >+ return node.operand.visit(this); >+ } >+ >+ visitMakeArrayRefExpression(node) >+ { >+ return node.type.visit(this); >+ } >+ >+ visitMakePtrExpression(node) >+ { >+ throw new Error("FIXME: Implement TypeVisitor.visitMakePtrExpression"); >+ } >+ >+ visitMatrixType(node) >+ { >+ return node; >+ } >+ >+ visitNativeFunc(node) >+ { >+ return node.returnType.visit(this); >+ } >+ >+ visitNativeFuncInstance(node) >+ { >+ return node.returnType.visit(this); >+ } >+ >+ visitNativeType(node) >+ { >+ return node; >+ } >+ >+ visitNativeTypeInstance(node) >+ { >+ return node; >+ } >+ >+ visitNullLiteral(node) >+ { >+ return node.type.visit(this); >+ } >+ >+ visitNullType(node) >+ { >+ return node; >+ } >+ >+ visitPtrType(node) >+ { >+ return node; >+ } >+ >+ visitReadModifyWriteExpression(node) >+ { >+ throw new Error("FIXME: Implement TypeVisitor.visitReadModifyWriteExpression"); >+ } >+ >+ visitReferenceType(node) >+ { >+ return node; >+ } >+ >+ visitStructType(node) >+ { >+ return node; >+ } >+ >+ visitTypeDef(node) >+ { >+ return node.type.visit(this); >+ } >+ >+ visitTypeRef(node) >+ { >+ return node.type.visit(this); >+ } >+ >+ visitVariableDecl(node) >+ { >+ return node.type.visit(this); >+ } >+ >+ visitVariableRef(node) >+ { >+ return node.variable.type.visit(this); >+ } >+ >+ visitVectorType(node) >+ { >+ return node; >+ } >+ >+ visitBlock(node) >+ { >+ throw new Error("Block has no type"); >+ } >+ >+ visitBoolLiteral(node) >+ { >+ throw new Error("BoolLiteral has no type"); >+ } >+ >+ visitBreak(node) >+ { >+ throw new Error("Break has no type"); >+ } >+ >+ visitConstexprTypeParameter(node) >+ { >+ throw new Error("ConstexprTypeParameter has no type"); >+ } >+ >+ visitContinue(node) >+ { >+ throw new Error("Continue has no type"); >+ } >+ >+ visitDereferenceExpression(node) >+ { >+ return node.type.visit(this); >+ } >+ >+ visitDoWhileLoop(node) >+ { >+ throw new Error("DoWhileLoop has no type"); >+ } >+ >+ visitEnumLiteral(node) >+ { >+ throw new Error("EnumLiteral has no type"); >+ } >+ >+ visitEnumMember(node) >+ { >+ throw new Error("EnumMember has no type"); >+ } >+ >+ visitForLoop(node) >+ { >+ throw new Error("ForLoop has no type"); >+ } >+ visitGenericLiteral(node) >+ { >+ return node.type.visit(this); >+ } >+ visitIfStatement(node) >+ { >+ throw new Error("IfStatement has no type"); >+ } >+ >+ visitProgram(node) >+ { >+ throw new Error("Program has no type"); >+ } >+ >+ visitProtocolDecl(node) >+ { >+ throw new Error("ProtocolDecl has no type"); >+ } >+ >+ visitProtocolFuncDecl(node) >+ { >+ throw new Error("ProtocolFuncDecl has no type"); >+ } >+ >+ visitProtocolRef(node) >+ { >+ throw new Error("ProtocolRef has no type"); >+ } >+ >+ visitReturn(node) >+ { >+ throw new Error("Return has no type"); >+ } >+ >+ visitSwitchCase(node) >+ { >+ throw new Error("SwitchCase has no type"); >+ } >+ >+ visitSwitchStatement(node) >+ { >+ throw new Error("SwitchStatement has no type"); >+ } >+ >+ visitTrapStatement(node) >+ { >+ throw new Error("TrapStatement has no type"); >+ } >+ >+ visitWhileLoop(node) >+ { >+ throw new Error("WhileLoop has no type"); >+ } >+ } >+ return node.visit(new TypeVisitor()); >+} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/.gitignore b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/.gitignore >new file mode 100644 >index 0000000000000000000000000000000000000000..c3b9a22cb1aceb00014bf5682b83c33126c9632b >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/.gitignore >@@ -0,0 +1,3 @@ >+WHLSL Tests.xcodeproj/xcuserdata >+WHLSL Tests.xcodeproj/project.xcworkspace/xcshareddata >+WHLSL Tests.xcodeproj/project.xcworkspace/xcuserdata >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/AppDelegate.h b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/AppDelegate.h >new file mode 100644 >index 0000000000000000000000000000000000000000..8529948d2a69df8fc1c861d7850bc503e9f5e9e6 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/AppDelegate.h >@@ -0,0 +1,15 @@ >+// >+// AppDelegate.h >+// WHLSL Toy >+// >+// Created by Thomas Denney on 7/10/18. >+// Copyright © 2018 Apple, Inc. All rights reserved. >+// >+ >+#import <Cocoa/Cocoa.h> >+ >+@interface AppDelegate : NSObject <NSApplicationDelegate> >+ >+ >+@end >+ >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/AppDelegate.m b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/AppDelegate.m >new file mode 100644 >index 0000000000000000000000000000000000000000..368a84a73fdb85b52447560386af20ce25e86cbc >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/AppDelegate.m >@@ -0,0 +1,27 @@ >+// >+// AppDelegate.m >+// WHLSL Toy >+// >+// Created by Thomas Denney on 7/10/18. >+// Copyright © 2018 Apple, Inc. All rights reserved. >+// >+ >+#import "AppDelegate.h" >+ >+@interface AppDelegate () >+ >+@end >+ >+@implementation AppDelegate >+ >+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { >+ // Insert code here to initialize your application >+} >+ >+ >+- (void)applicationWillTerminate:(NSNotification *)aNotification { >+ // Insert code here to tear down your application >+} >+ >+ >+@end >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Assets.xcassets/AppIcon.appiconset/Contents.json b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Assets.xcassets/AppIcon.appiconset/Contents.json >new file mode 100644 >index 0000000000000000000000000000000000000000..2db2b1c7c6c316500a7a34807648434289494ba1 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Assets.xcassets/AppIcon.appiconset/Contents.json >@@ -0,0 +1,58 @@ >+{ >+ "images" : [ >+ { >+ "idiom" : "mac", >+ "size" : "16x16", >+ "scale" : "1x" >+ }, >+ { >+ "idiom" : "mac", >+ "size" : "16x16", >+ "scale" : "2x" >+ }, >+ { >+ "idiom" : "mac", >+ "size" : "32x32", >+ "scale" : "1x" >+ }, >+ { >+ "idiom" : "mac", >+ "size" : "32x32", >+ "scale" : "2x" >+ }, >+ { >+ "idiom" : "mac", >+ "size" : "128x128", >+ "scale" : "1x" >+ }, >+ { >+ "idiom" : "mac", >+ "size" : "128x128", >+ "scale" : "2x" >+ }, >+ { >+ "idiom" : "mac", >+ "size" : "256x256", >+ "scale" : "1x" >+ }, >+ { >+ "idiom" : "mac", >+ "size" : "256x256", >+ "scale" : "2x" >+ }, >+ { >+ "idiom" : "mac", >+ "size" : "512x512", >+ "scale" : "1x" >+ }, >+ { >+ "idiom" : "mac", >+ "size" : "512x512", >+ "scale" : "2x" >+ } >+ ], >+ "info" : { >+ "version" : 1, >+ "author" : "xcode" >+ } >+} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Assets.xcassets/Contents.json b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Assets.xcassets/Contents.json >new file mode 100644 >index 0000000000000000000000000000000000000000..da4a164c918651cdd1e11dca5cc62c333f097601 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Assets.xcassets/Contents.json >@@ -0,0 +1,6 @@ >+{ >+ "info" : { >+ "version" : 1, >+ "author" : "xcode" >+ } >+} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Base.lproj/Main.storyboard b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Base.lproj/Main.storyboard >new file mode 100644 >index 0000000000000000000000000000000000000000..c676d9f74cc567bff56bed1dd565dcdd70beb3df >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Base.lproj/Main.storyboard >@@ -0,0 +1,847 @@ >+<?xml version="1.0" encoding="UTF-8"?> >+<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="14269.14" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS"> >+ <dependencies> >+ <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14269.14"/> >+ <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> >+ </dependencies> >+ <scenes> >+ <!--Application--> >+ <scene sceneID="JPo-4y-FX3"> >+ <objects> >+ <application id="hnw-xV-0zn" sceneMemberID="viewController"> >+ <menu key="mainMenu" title="Main Menu" systemMenu="main" id="AYu-sK-qS6"> >+ <items> >+ <menuItem title="WHLSL Tests" id="1Xt-HY-uBw"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <menu key="submenu" title="WHLSL Tests" systemMenu="apple" id="uQy-DD-JDr"> >+ <items> >+ <menuItem title="About WHLSL Tests" id="5kV-Vb-QxS"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="orderFrontStandardAboutPanel:" target="Ady-hI-5gd" id="Exp-CZ-Vem"/> >+ </connections> >+ </menuItem> >+ <menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/> >+ <menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/> >+ <menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/> >+ <menuItem title="Services" id="NMo-om-nkz"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/> >+ </menuItem> >+ <menuItem isSeparatorItem="YES" id="4je-JR-u6R"/> >+ <menuItem title="Hide WHLSL Tests" keyEquivalent="h" id="Olw-nP-bQN"> >+ <connections> >+ <action selector="hide:" target="Ady-hI-5gd" id="PnN-Uc-m68"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO"> >+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/> >+ <connections> >+ <action selector="hideOtherApplications:" target="Ady-hI-5gd" id="VT4-aY-XCT"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Show All" id="Kd2-mp-pUS"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="unhideAllApplications:" target="Ady-hI-5gd" id="Dhg-Le-xox"/> >+ </connections> >+ </menuItem> >+ <menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/> >+ <menuItem title="Quit WHLSL Tests" keyEquivalent="q" id="4sb-4s-VLi"> >+ <connections> >+ <action selector="terminate:" target="Ady-hI-5gd" id="Te7-pn-YzF"/> >+ </connections> >+ </menuItem> >+ </items> >+ </menu> >+ </menuItem> >+ <menuItem title="File" id="dMs-cI-mzQ"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <menu key="submenu" title="File" id="bib-Uj-vzu"> >+ <items> >+ <menuItem title="New" keyEquivalent="n" id="Was-JA-tGl"> >+ <connections> >+ <action selector="newDocument:" target="Ady-hI-5gd" id="4Si-XN-c54"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Open…" keyEquivalent="o" id="IAo-SY-fd9"> >+ <connections> >+ <action selector="openDocument:" target="Ady-hI-5gd" id="bVn-NM-KNZ"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Open Default" keyEquivalent="D" id="aei-2z-FdS"> >+ <connections> >+ <action selector="loadDefault:" target="Ady-hI-5gd" id="Qkc-mo-M8q"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Open Mandelbrot" keyEquivalent="d" id="Oo7-Lv-ixZ"> >+ <connections> >+ <action selector="loadMandelbrot:" target="Ady-hI-5gd" id="rBu-TY-q9u"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Open Julia" keyEquivalent="j" id="ghn-TO-Pf8"> >+ <connections> >+ <action selector="loadJulia:" target="Ady-hI-5gd" id="Ld3-NY-hjZ"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Open Recent" id="tXI-mr-wws"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="oas-Oc-fiZ"> >+ <items> >+ <menuItem title="Clear Menu" id="vNY-rz-j42"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="clearRecentDocuments:" target="Ady-hI-5gd" id="Daa-9d-B3U"/> >+ </connections> >+ </menuItem> >+ </items> >+ </menu> >+ </menuItem> >+ <menuItem title="Open Native Flat Color" id="4fF-le-bz2"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="loadNativeFlatColor:" target="Ady-hI-5gd" id="D8V-tT-Uue"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Open Native Mandelbrot" id="vkA-g5-K5f"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="loadNativeMandelbrot:" target="Ady-hI-5gd" id="f0f-zP-EXZ"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Open Native Julia" id="rag-hI-17H"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="loadNativeJulia:" target="Ady-hI-5gd" id="lVh-ll-sg8"/> >+ </connections> >+ </menuItem> >+ <menuItem isSeparatorItem="YES" id="m54-Is-iLE"/> >+ <menuItem title="Close" keyEquivalent="w" id="DVo-aG-piG"> >+ <connections> >+ <action selector="performClose:" target="Ady-hI-5gd" id="HmO-Ls-i7Q"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Save…" keyEquivalent="s" id="pxx-59-PXV"> >+ <connections> >+ <action selector="saveDocument:" target="Ady-hI-5gd" id="teZ-XB-qJY"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Save As…" keyEquivalent="S" id="Bw7-FT-i3A"> >+ <connections> >+ <action selector="saveDocumentAs:" target="Ady-hI-5gd" id="mDf-zr-I0C"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Revert to Saved" keyEquivalent="r" id="KaW-ft-85H"> >+ <connections> >+ <action selector="revertDocumentToSaved:" target="Ady-hI-5gd" id="iJ3-Pv-kwq"/> >+ </connections> >+ </menuItem> >+ <menuItem isSeparatorItem="YES" id="aJh-i4-bef"/> >+ <menuItem title="Page Setup…" keyEquivalent="P" id="qIS-W8-SiK"> >+ <modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/> >+ <connections> >+ <action selector="runPageLayout:" target="Ady-hI-5gd" id="Din-rz-gC5"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Print…" keyEquivalent="p" id="aTl-1u-JFS"> >+ <connections> >+ <action selector="print:" target="Ady-hI-5gd" id="qaZ-4w-aoO"/> >+ </connections> >+ </menuItem> >+ </items> >+ </menu> >+ </menuItem> >+ <menuItem title="Edit" id="5QF-Oa-p0T"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <menu key="submenu" title="Edit" id="W48-6f-4Dl"> >+ <items> >+ <menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg"> >+ <connections> >+ <action selector="undo:" target="Ady-hI-5gd" id="M6e-cu-g7V"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam"> >+ <connections> >+ <action selector="redo:" target="Ady-hI-5gd" id="oIA-Rs-6OD"/> >+ </connections> >+ </menuItem> >+ <menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/> >+ <menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG"> >+ <connections> >+ <action selector="cut:" target="Ady-hI-5gd" id="YJe-68-I9s"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU"> >+ <connections> >+ <action selector="copy:" target="Ady-hI-5gd" id="G1f-GL-Joy"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL"> >+ <connections> >+ <action selector="paste:" target="Ady-hI-5gd" id="UvS-8e-Qdg"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Paste and Match Style" keyEquivalent="V" id="WeT-3V-zwk"> >+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/> >+ <connections> >+ <action selector="pasteAsPlainText:" target="Ady-hI-5gd" id="cEh-KX-wJQ"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Delete" id="pa3-QI-u2k"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="delete:" target="Ady-hI-5gd" id="0Mk-Ml-PaM"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Select All" keyEquivalent="a" id="Ruw-6m-B2m"> >+ <connections> >+ <action selector="selectAll:" target="Ady-hI-5gd" id="VNm-Mi-diN"/> >+ </connections> >+ </menuItem> >+ <menuItem isSeparatorItem="YES" id="uyl-h8-XO2"/> >+ <menuItem title="Find" id="4EN-yA-p0u"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <menu key="submenu" title="Find" id="1b7-l0-nxx"> >+ <items> >+ <menuItem title="Find…" tag="1" keyEquivalent="f" id="Xz5-n4-O0W"> >+ <connections> >+ <action selector="performFindPanelAction:" target="Ady-hI-5gd" id="cD7-Qs-BN4"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="YEy-JH-Tfz"> >+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/> >+ <connections> >+ <action selector="performFindPanelAction:" target="Ady-hI-5gd" id="WD3-Gg-5AJ"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Find Next" tag="2" keyEquivalent="g" id="q09-fT-Sye"> >+ <connections> >+ <action selector="performFindPanelAction:" target="Ady-hI-5gd" id="NDo-RZ-v9R"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Find Previous" tag="3" keyEquivalent="G" id="OwM-mh-QMV"> >+ <connections> >+ <action selector="performFindPanelAction:" target="Ady-hI-5gd" id="HOh-sY-3ay"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="buJ-ug-pKt"> >+ <connections> >+ <action selector="performFindPanelAction:" target="Ady-hI-5gd" id="U76-nv-p5D"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Jump to Selection" keyEquivalent="j" id="S0p-oC-mLd"> >+ <connections> >+ <action selector="centerSelectionInVisibleArea:" target="Ady-hI-5gd" id="IOG-6D-g5B"/> >+ </connections> >+ </menuItem> >+ </items> >+ </menu> >+ </menuItem> >+ <menuItem title="Spelling and Grammar" id="Dv1-io-Yv7"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <menu key="submenu" title="Spelling" id="3IN-sU-3Bg"> >+ <items> >+ <menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="HFo-cy-zxI"> >+ <connections> >+ <action selector="showGuessPanel:" target="Ady-hI-5gd" id="vFj-Ks-hy3"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Check Document Now" keyEquivalent=";" id="hz2-CU-CR7"> >+ <connections> >+ <action selector="checkSpelling:" target="Ady-hI-5gd" id="fz7-VC-reM"/> >+ </connections> >+ </menuItem> >+ <menuItem isSeparatorItem="YES" id="bNw-od-mp5"/> >+ <menuItem title="Check Spelling While Typing" id="rbD-Rh-wIN"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="toggleContinuousSpellChecking:" target="Ady-hI-5gd" id="7w6-Qz-0kB"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Check Grammar With Spelling" id="mK6-2p-4JG"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="toggleGrammarChecking:" target="Ady-hI-5gd" id="muD-Qn-j4w"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Correct Spelling Automatically" id="78Y-hA-62v"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="toggleAutomaticSpellingCorrection:" target="Ady-hI-5gd" id="2lM-Qi-WAP"/> >+ </connections> >+ </menuItem> >+ </items> >+ </menu> >+ </menuItem> >+ <menuItem title="Substitutions" id="9ic-FL-obx"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <menu key="submenu" title="Substitutions" id="FeM-D8-WVr"> >+ <items> >+ <menuItem title="Show Substitutions" id="z6F-FW-3nz"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="orderFrontSubstitutionsPanel:" target="Ady-hI-5gd" id="oku-mr-iSq"/> >+ </connections> >+ </menuItem> >+ <menuItem isSeparatorItem="YES" id="gPx-C9-uUO"/> >+ <menuItem title="Smart Copy/Paste" id="9yt-4B-nSM"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="toggleSmartInsertDelete:" target="Ady-hI-5gd" id="3IJ-Se-DZD"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Smart Quotes" id="hQb-2v-fYv"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="toggleAutomaticQuoteSubstitution:" target="Ady-hI-5gd" id="ptq-xd-QOA"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Smart Dashes" id="rgM-f4-ycn"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="toggleAutomaticDashSubstitution:" target="Ady-hI-5gd" id="oCt-pO-9gS"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Smart Links" id="cwL-P1-jid"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="toggleAutomaticLinkDetection:" target="Ady-hI-5gd" id="Gip-E3-Fov"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Data Detectors" id="tRr-pd-1PS"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="toggleAutomaticDataDetection:" target="Ady-hI-5gd" id="R1I-Nq-Kbl"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Text Replacement" id="HFQ-gK-NFA"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="toggleAutomaticTextReplacement:" target="Ady-hI-5gd" id="DvP-Fe-Py6"/> >+ </connections> >+ </menuItem> >+ </items> >+ </menu> >+ </menuItem> >+ <menuItem title="Transformations" id="2oI-Rn-ZJC"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <menu key="submenu" title="Transformations" id="c8a-y6-VQd"> >+ <items> >+ <menuItem title="Make Upper Case" id="vmV-6d-7jI"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="uppercaseWord:" target="Ady-hI-5gd" id="sPh-Tk-edu"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Make Lower Case" id="d9M-CD-aMd"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="lowercaseWord:" target="Ady-hI-5gd" id="iUZ-b5-hil"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Capitalize" id="UEZ-Bs-lqG"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="capitalizeWord:" target="Ady-hI-5gd" id="26H-TL-nsh"/> >+ </connections> >+ </menuItem> >+ </items> >+ </menu> >+ </menuItem> >+ <menuItem title="Speech" id="xrE-MZ-jX0"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <menu key="submenu" title="Speech" id="3rS-ZA-NoH"> >+ <items> >+ <menuItem title="Start Speaking" id="Ynk-f8-cLZ"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="startSpeaking:" target="Ady-hI-5gd" id="654-Ng-kyl"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Stop Speaking" id="Oyz-dy-DGm"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="stopSpeaking:" target="Ady-hI-5gd" id="dX8-6p-jy9"/> >+ </connections> >+ </menuItem> >+ </items> >+ </menu> >+ </menuItem> >+ </items> >+ </menu> >+ </menuItem> >+ <menuItem title="Format" id="jxT-CU-nIS"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <menu key="submenu" title="Format" id="GEO-Iw-cKr"> >+ <items> >+ <menuItem title="Font" id="Gi5-1S-RQB"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <menu key="submenu" title="Font" systemMenu="font" id="aXa-aM-Jaq"> >+ <items> >+ <menuItem title="Show Fonts" keyEquivalent="t" id="Q5e-8K-NDq"> >+ <connections> >+ <action selector="orderFrontFontPanel:" target="YLy-65-1bz" id="WHr-nq-2xA"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Bold" tag="2" keyEquivalent="b" id="GB9-OM-e27"> >+ <connections> >+ <action selector="addFontTrait:" target="YLy-65-1bz" id="hqk-hr-sYV"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Italic" tag="1" keyEquivalent="i" id="Vjx-xi-njq"> >+ <connections> >+ <action selector="addFontTrait:" target="YLy-65-1bz" id="IHV-OB-c03"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Underline" keyEquivalent="u" id="WRG-CD-K1S"> >+ <connections> >+ <action selector="underline:" target="Ady-hI-5gd" id="FYS-2b-JAY"/> >+ </connections> >+ </menuItem> >+ <menuItem isSeparatorItem="YES" id="5gT-KC-WSO"/> >+ <menuItem title="Bigger" tag="3" keyEquivalent="+" id="Ptp-SP-VEL"> >+ <connections> >+ <action selector="modifyFont:" target="YLy-65-1bz" id="Uc7-di-UnL"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Smaller" tag="4" keyEquivalent="-" id="i1d-Er-qST"> >+ <connections> >+ <action selector="modifyFont:" target="YLy-65-1bz" id="HcX-Lf-eNd"/> >+ </connections> >+ </menuItem> >+ <menuItem isSeparatorItem="YES" id="kx3-Dk-x3B"/> >+ <menuItem title="Kern" id="jBQ-r6-VK2"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <menu key="submenu" title="Kern" id="tlD-Oa-oAM"> >+ <items> >+ <menuItem title="Use Default" id="GUa-eO-cwY"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="useStandardKerning:" target="Ady-hI-5gd" id="6dk-9l-Ckg"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Use None" id="cDB-IK-hbR"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="turnOffKerning:" target="Ady-hI-5gd" id="U8a-gz-Maa"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Tighten" id="46P-cB-AYj"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="tightenKerning:" target="Ady-hI-5gd" id="hr7-Nz-8ro"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Loosen" id="ogc-rX-tC1"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="loosenKerning:" target="Ady-hI-5gd" id="8i4-f9-FKE"/> >+ </connections> >+ </menuItem> >+ </items> >+ </menu> >+ </menuItem> >+ <menuItem title="Ligatures" id="o6e-r0-MWq"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <menu key="submenu" title="Ligatures" id="w0m-vy-SC9"> >+ <items> >+ <menuItem title="Use Default" id="agt-UL-0e3"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="useStandardLigatures:" target="Ady-hI-5gd" id="7uR-wd-Dx6"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Use None" id="J7y-lM-qPV"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="turnOffLigatures:" target="Ady-hI-5gd" id="iX2-gA-Ilz"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Use All" id="xQD-1f-W4t"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="useAllLigatures:" target="Ady-hI-5gd" id="KcB-kA-TuK"/> >+ </connections> >+ </menuItem> >+ </items> >+ </menu> >+ </menuItem> >+ <menuItem title="Baseline" id="OaQ-X3-Vso"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <menu key="submenu" title="Baseline" id="ijk-EB-dga"> >+ <items> >+ <menuItem title="Use Default" id="3Om-Ey-2VK"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="unscript:" target="Ady-hI-5gd" id="0vZ-95-Ywn"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Superscript" id="Rqc-34-cIF"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="superscript:" target="Ady-hI-5gd" id="3qV-fo-wpU"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Subscript" id="I0S-gh-46l"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="subscript:" target="Ady-hI-5gd" id="Q6W-4W-IGz"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Raise" id="2h7-ER-AoG"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="raiseBaseline:" target="Ady-hI-5gd" id="4sk-31-7Q9"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Lower" id="1tx-W0-xDw"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="lowerBaseline:" target="Ady-hI-5gd" id="OF1-bc-KW4"/> >+ </connections> >+ </menuItem> >+ </items> >+ </menu> >+ </menuItem> >+ <menuItem isSeparatorItem="YES" id="Ndw-q3-faq"/> >+ <menuItem title="Show Colors" keyEquivalent="C" id="bgn-CT-cEk"> >+ <connections> >+ <action selector="orderFrontColorPanel:" target="Ady-hI-5gd" id="mSX-Xz-DV3"/> >+ </connections> >+ </menuItem> >+ <menuItem isSeparatorItem="YES" id="iMs-zA-UFJ"/> >+ <menuItem title="Copy Style" keyEquivalent="c" id="5Vv-lz-BsD"> >+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/> >+ <connections> >+ <action selector="copyFont:" target="Ady-hI-5gd" id="GJO-xA-L4q"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Paste Style" keyEquivalent="v" id="vKC-jM-MkH"> >+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/> >+ <connections> >+ <action selector="pasteFont:" target="Ady-hI-5gd" id="JfD-CL-leO"/> >+ </connections> >+ </menuItem> >+ </items> >+ </menu> >+ </menuItem> >+ <menuItem title="Text" id="Fal-I4-PZk"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <menu key="submenu" title="Text" id="d9c-me-L2H"> >+ <items> >+ <menuItem title="Align Left" keyEquivalent="{" id="ZM1-6Q-yy1"> >+ <connections> >+ <action selector="alignLeft:" target="Ady-hI-5gd" id="zUv-R1-uAa"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Center" keyEquivalent="|" id="VIY-Ag-zcb"> >+ <connections> >+ <action selector="alignCenter:" target="Ady-hI-5gd" id="spX-mk-kcS"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Justify" id="J5U-5w-g23"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="alignJustified:" target="Ady-hI-5gd" id="ljL-7U-jND"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Align Right" keyEquivalent="}" id="wb2-vD-lq4"> >+ <connections> >+ <action selector="alignRight:" target="Ady-hI-5gd" id="r48-bG-YeY"/> >+ </connections> >+ </menuItem> >+ <menuItem isSeparatorItem="YES" id="4s2-GY-VfK"/> >+ <menuItem title="Writing Direction" id="H1b-Si-o9J"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <menu key="submenu" title="Writing Direction" id="8mr-sm-Yjd"> >+ <items> >+ <menuItem title="Paragraph" enabled="NO" id="ZvO-Gk-QUH"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ </menuItem> >+ <menuItem id="YGs-j5-SAR"> >+ <string key="title"> Default</string> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="makeBaseWritingDirectionNatural:" target="Ady-hI-5gd" id="qtV-5e-UBP"/> >+ </connections> >+ </menuItem> >+ <menuItem id="Lbh-J2-qVU"> >+ <string key="title"> Left to Right</string> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="makeBaseWritingDirectionLeftToRight:" target="Ady-hI-5gd" id="S0X-9S-QSf"/> >+ </connections> >+ </menuItem> >+ <menuItem id="jFq-tB-4Kx"> >+ <string key="title"> Right to Left</string> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="makeBaseWritingDirectionRightToLeft:" target="Ady-hI-5gd" id="5fk-qB-AqJ"/> >+ </connections> >+ </menuItem> >+ <menuItem isSeparatorItem="YES" id="swp-gr-a21"/> >+ <menuItem title="Selection" enabled="NO" id="cqv-fj-IhA"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ </menuItem> >+ <menuItem id="Nop-cj-93Q"> >+ <string key="title"> Default</string> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="makeTextWritingDirectionNatural:" target="Ady-hI-5gd" id="lPI-Se-ZHp"/> >+ </connections> >+ </menuItem> >+ <menuItem id="BgM-ve-c93"> >+ <string key="title"> Left to Right</string> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="makeTextWritingDirectionLeftToRight:" target="Ady-hI-5gd" id="caW-Bv-w94"/> >+ </connections> >+ </menuItem> >+ <menuItem id="RB4-Sm-HuC"> >+ <string key="title"> Right to Left</string> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="makeTextWritingDirectionRightToLeft:" target="Ady-hI-5gd" id="EXD-6r-ZUu"/> >+ </connections> >+ </menuItem> >+ </items> >+ </menu> >+ </menuItem> >+ <menuItem isSeparatorItem="YES" id="fKy-g9-1gm"/> >+ <menuItem title="Show Ruler" id="vLm-3I-IUL"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="toggleRuler:" target="Ady-hI-5gd" id="FOx-HJ-KwY"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Copy Ruler" keyEquivalent="c" id="MkV-Pr-PK5"> >+ <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/> >+ <connections> >+ <action selector="copyRuler:" target="Ady-hI-5gd" id="71i-fW-3W2"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Paste Ruler" keyEquivalent="v" id="LVM-kO-fVI"> >+ <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/> >+ <connections> >+ <action selector="pasteRuler:" target="Ady-hI-5gd" id="cSh-wd-qM2"/> >+ </connections> >+ </menuItem> >+ </items> >+ </menu> >+ </menuItem> >+ </items> >+ </menu> >+ </menuItem> >+ <menuItem title="View" id="H8h-7b-M4v"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <menu key="submenu" title="View" id="HyV-fh-RgO"> >+ <items> >+ <menuItem title="Show Toolbar" keyEquivalent="t" id="snW-S8-Cw5"> >+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/> >+ <connections> >+ <action selector="toggleToolbarShown:" target="Ady-hI-5gd" id="BXY-wc-z0C"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Customize Toolbar…" id="1UK-8n-QPP"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="runToolbarCustomizationPalette:" target="Ady-hI-5gd" id="pQI-g3-MTW"/> >+ </connections> >+ </menuItem> >+ <menuItem isSeparatorItem="YES" id="hB3-LF-h0Y"/> >+ <menuItem title="Reset viewport" keyEquivalent="R" id="0RE-Am-xSc"> >+ <connections> >+ <action selector="resetViewport:" target="Ady-hI-5gd" id="PdF-ub-35F"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Show Sidebar" keyEquivalent="s" id="kIP-vf-haE"> >+ <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/> >+ <connections> >+ <action selector="toggleSourceList:" target="Ady-hI-5gd" id="iwa-gc-5KM"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Enter Full Screen" keyEquivalent="f" id="4J7-dP-txa"> >+ <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/> >+ <connections> >+ <action selector="toggleFullScreen:" target="Ady-hI-5gd" id="dU3-MA-1Rq"/> >+ </connections> >+ </menuItem> >+ </items> >+ </menu> >+ </menuItem> >+ <menuItem title="Window" id="aUF-d1-5bR"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo"> >+ <items> >+ <menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV"> >+ <connections> >+ <action selector="performMiniaturize:" target="Ady-hI-5gd" id="VwT-WD-YPe"/> >+ </connections> >+ </menuItem> >+ <menuItem title="Zoom" id="R4o-n2-Eq4"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="performZoom:" target="Ady-hI-5gd" id="DIl-cC-cCs"/> >+ </connections> >+ </menuItem> >+ <menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/> >+ <menuItem title="Bring All to Front" id="LE2-aR-0XJ"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <connections> >+ <action selector="arrangeInFront:" target="Ady-hI-5gd" id="DRN-fu-gQh"/> >+ </connections> >+ </menuItem> >+ </items> >+ </menu> >+ </menuItem> >+ <menuItem title="Help" id="wpr-3q-Mcd"> >+ <modifierMask key="keyEquivalentModifierMask"/> >+ <menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ"> >+ <items> >+ <menuItem title="WHLSL Tests Help" keyEquivalent="?" id="FKE-Sm-Kum"> >+ <connections> >+ <action selector="showHelp:" target="Ady-hI-5gd" id="y7X-2Q-9no"/> >+ </connections> >+ </menuItem> >+ </items> >+ </menu> >+ </menuItem> >+ </items> >+ </menu> >+ <connections> >+ <outlet property="delegate" destination="Voe-Tx-rLC" id="PrD-fu-P6m"/> >+ </connections> >+ </application> >+ <customObject id="Voe-Tx-rLC" customClass="AppDelegate"/> >+ <customObject id="YLy-65-1bz" customClass="NSFontManager"/> >+ <customObject id="Ady-hI-5gd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/> >+ </objects> >+ <point key="canvasLocation" x="75" y="0.0"/> >+ </scene> >+ <!--Window Controller--> >+ <scene sceneID="R2V-B0-nI4"> >+ <objects> >+ <windowController id="B8D-0N-5wS" sceneMemberID="viewController"> >+ <window key="window" title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="IQv-IB-iLA"> >+ <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/> >+ <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/> >+ <rect key="contentRect" x="196" y="240" width="480" height="270"/> >+ <rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/> >+ <connections> >+ <outlet property="delegate" destination="B8D-0N-5wS" id="98r-iN-zZc"/> >+ </connections> >+ </window> >+ <connections> >+ <segue destination="XfG-lQ-9wD" kind="relationship" relationship="window.shadowedContentViewController" id="cq2-FE-JQM"/> >+ </connections> >+ </windowController> >+ <customObject id="Oky-zY-oP4" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/> >+ </objects> >+ <point key="canvasLocation" x="75" y="250"/> >+ </scene> >+ <!--View Controller--> >+ <scene sceneID="hIz-AP-VOD"> >+ <objects> >+ <viewController id="XfG-lQ-9wD" customClass="ViewController" sceneMemberID="viewController"> >+ <view key="view" wantsLayer="YES" id="m2S-Jp-Qdl"> >+ <rect key="frame" x="0.0" y="0.0" width="1256" height="439"/> >+ <autoresizingMask key="autoresizingMask"/> >+ <subviews> >+ <button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="zWA-us-Fkf"> >+ <rect key="frame" x="14" y="13" width="90" height="32"/> >+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> >+ <buttonCell key="cell" type="push" title="Compile" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="1K5-PN-nLE"> >+ <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> >+ <font key="font" metaFont="system"/> >+ <string key="keyEquivalent">r</string> >+ <modifierMask key="keyEquivalentModifierMask" command="YES"/> >+ </buttonCell> >+ <connections> >+ <action selector="compileClicked:" target="XfG-lQ-9wD" id="1FR-KE-nty"/> >+ </connections> >+ </button> >+ <scrollView fixedFrame="YES" borderType="none" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" translatesAutoresizingMaskIntoConstraints="NO" id="egF-8L-cI6"> >+ <rect key="frame" x="20" y="61" width="400" height="358"/> >+ <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/> >+ <clipView key="contentView" ambiguous="YES" drawsBackground="NO" copiesOnScroll="NO" id="HW8-L7-3PX"> >+ <rect key="frame" x="0.0" y="0.0" width="400" height="358"/> >+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> >+ <subviews> >+ <textView ambiguous="YES" importsGraphics="NO" richText="NO" verticallyResizable="YES" findStyle="bar" smartInsertDelete="YES" id="pRP-9d-8nB"> >+ <rect key="frame" x="0.0" y="0.0" width="400" height="358"/> >+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> >+ <color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/> >+ <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/> >+ <size key="minSize" width="400" height="358"/> >+ <size key="maxSize" width="1317" height="10000000"/> >+ <attributedString key="textStorage"> >+ <fragment content="WHLSL
TextView"> >+ <attributes> >+ <color key="NSColor" name="textColor" catalog="System" colorSpace="catalog"/> >+ <font key="NSFont" size="12" name="Menlo-Regular"/> >+ <paragraphStyle key="NSParagraphStyle" alignment="natural" lineBreakMode="wordWrapping" baseWritingDirection="natural" tighteningFactorForTruncation="0.0"/> >+ </attributes> >+ </fragment> >+ </attributedString> >+ <color key="insertionPointColor" name="textColor" catalog="System" colorSpace="catalog"/> >+ </textView> >+ </subviews> >+ </clipView> >+ <scroller key="verticalScroller" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="1T4-PL-dI4"> >+ <rect key="frame" x="384" y="0.0" width="16" height="358"/> >+ <autoresizingMask key="autoresizingMask"/> >+ </scroller> >+ </scrollView> >+ <scrollView fixedFrame="YES" borderType="none" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" translatesAutoresizingMaskIntoConstraints="NO" id="tuu-uc-Dxg"> >+ <rect key="frame" x="428" y="61" width="400" height="358"/> >+ <autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/> >+ <clipView key="contentView" ambiguous="YES" drawsBackground="NO" copiesOnScroll="NO" id="1Us-pH-zAs"> >+ <rect key="frame" x="0.0" y="0.0" width="400" height="358"/> >+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> >+ <subviews> >+ <textView ambiguous="YES" importsGraphics="NO" richText="NO" verticallyResizable="YES" findStyle="bar" smartInsertDelete="YES" id="82n-yv-OVo"> >+ <rect key="frame" x="0.0" y="0.0" width="400" height="358"/> >+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> >+ <color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/> >+ <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/> >+ <size key="minSize" width="400" height="358"/> >+ <size key="maxSize" width="1391" height="10000000"/> >+ <color key="insertionPointColor" name="textColor" catalog="System" colorSpace="catalog"/> >+ </textView> >+ </subviews> >+ </clipView> >+ <scroller key="verticalScroller" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="ev9-xr-MSP"> >+ <rect key="frame" x="384" y="0.0" width="16" height="358"/> >+ <autoresizingMask key="autoresizingMask"/> >+ </scroller> >+ </scrollView> >+ <customView fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="9FG-iv-6pr" customClass="CustomMetalView"> >+ <rect key="frame" x="836" y="61" width="400" height="358"/> >+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/> >+ </customView> >+ <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="aSY-2r-vMu"> >+ <rect key="frame" x="106" y="20" width="1132" height="18"/> >+ <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> >+ <textFieldCell key="cell" lineBreakMode="clipping" title="Label" id="JK0-3q-epW"> >+ <font key="font" metaFont="system"/> >+ <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/> >+ <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/> >+ </textFieldCell> >+ </textField> >+ </subviews> >+ </view> >+ <connections> >+ <outlet property="debugLabel" destination="aSY-2r-vMu" id="hSC-9N-nj9"/> >+ <outlet property="metalView" destination="9FG-iv-6pr" id="d1K-E7-8zL"/> >+ <outlet property="mslTextView" destination="82n-yv-OVo" id="eoE-3h-vhV"/> >+ <outlet property="mslViewContainer" destination="tuu-uc-Dxg" id="Z3D-cP-qY2"/> >+ <outlet property="whlslTextView" destination="pRP-9d-8nB" id="Muf-bo-NKk"/> >+ <outlet property="whlslViewContainer" destination="egF-8L-cI6" id="DIG-j2-2tb"/> >+ </connections> >+ </viewController> >+ <customObject id="rPt-NT-nkU" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/> >+ </objects> >+ <point key="canvasLocation" x="-332" y="911.5"/> >+ </scene> >+ </scenes> >+</document> >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/CompileResult.h b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/CompileResult.h >new file mode 100644 >index 0000000000000000000000000000000000000000..871e9c5df58a1e70b05cdebcd88fb366b0c26055 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/CompileResult.h >@@ -0,0 +1,23 @@ >+// >+// CompileResult.h >+// WHLSL Tests >+// >+// Created by Thomas Denney on 7/12/18. >+// Copyright © 2018 Apple, Inc. All rights reserved. >+// >+ >+#import <Foundation/Foundation.h> >+ >+NS_ASSUME_NONNULL_BEGIN >+ >+@interface CompileResult : NSObject >+ >+- (instancetype)initWithMetalSource:(NSString*)source functionNameMap:(NSDictionary<NSString*,NSArray<NSString*>*>*)map; >+ >+@property (readonly) NSString *source; >+// FIXME: This should be NSDictionary<NSString*, NSArray<NSString*>*>* >+@property (readonly) NSDictionary<NSString*, NSString*>* functionNameMap; >+ >+@end >+ >+NS_ASSUME_NONNULL_END >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/CompileResult.m b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/CompileResult.m >new file mode 100644 >index 0000000000000000000000000000000000000000..e207bb437cc05044be3bc2ef6e5ae0dc0bb8dbff >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/CompileResult.m >@@ -0,0 +1,29 @@ >+// >+// CompileResult.m >+// WHLSL Tests >+// >+// Created by Thomas Denney on 7/12/18. >+// Copyright © 2018 Apple, Inc. All rights reserved. >+// >+ >+#import "CompileResult.h" >+ >+@interface CompileResult () >+ >+@property NSString *source; >+@property NSDictionary<NSString*, NSString*>* functionNameMap; >+ >+@end >+ >+@implementation CompileResult >+ >+- (instancetype)initWithMetalSource:(NSString *)source functionNameMap:(NSDictionary<NSString *, NSString *> *)map >+{ >+ if (self = [super init]) { >+ self.source = source; >+ self.functionNameMap = map; >+ } >+ return self; >+} >+ >+@end >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Compiler.h b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Compiler.h >new file mode 100644 >index 0000000000000000000000000000000000000000..0ef3ac2ae260e688df466433d30153ef99a0f744 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Compiler.h >@@ -0,0 +1,22 @@ >+// >+// Compiler.h >+// WHLSL Toy >+// >+// Created by Thomas Denney on 7/10/18. >+// Copyright © 2018 Apple, Inc. All rights reserved. >+// >+ >+@import Foundation; >+@import JavaScriptCore; >+ >+#import "CompileResult.h" >+ >+NS_ASSUME_NONNULL_BEGIN >+ >+@interface Compiler : NSObject >+ >+- (CompileResult*)compileWhlslToMetal:(NSString*)whlslSource error:(NSError**)error; >+ >+@end >+ >+NS_ASSUME_NONNULL_END >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Compiler.m b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Compiler.m >new file mode 100644 >index 0000000000000000000000000000000000000000..995329c742948ab219a4eaad184ca4c7c4cf3d2c >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Compiler.m >@@ -0,0 +1,86 @@ >+// >+// Compiler.m >+// WHLSL Toy >+// >+// Created by Thomas Denney on 7/10/18. >+// Copyright © 2018 Apple, Inc. All rights reserved. >+// >+ >+#import "Compiler.h" >+ >+@import Cocoa; >+@import JavaScriptCore; >+ >+@interface Compiler () >+ >+@property JSContext* context; >+ >+@end >+ >+@implementation Compiler >+ >+- (instancetype)init >+{ >+ self = [super init]; >+ if (self) { >+ self.context = [[JSContext alloc] init]; >+ [self loadScripts]; >+ } >+ return self; >+} >+ >+- (void)loadScripts >+{ >+ __weak JSContext* weakContext = self.context; >+ __block NSMutableSet<NSString*>* alreadyLoaded = [NSMutableSet new]; >+ void (^loadFunction)(NSString *) = ^void(NSString* name) { >+ if (![alreadyLoaded containsObject:name]) { >+ NSString* path = [[NSBundle mainBundle] pathForResource:[name stringByDeletingPathExtension] ofType:@"js"]; >+ NSError* loadError = nil; >+ NSString* src = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&loadError]; >+ if (loadError) >+ NSLog(@"Loading %@ failed: %@", name, loadError.localizedDescription); >+ else { >+ [weakContext evaluateScript:src]; >+ [alreadyLoaded addObject:name]; >+ } >+ } else >+ NSLog(@"Attempting to load duplicate file %@", name); >+ }; >+ self.context[@"load"] = loadFunction; >+ >+ loadFunction(@"All.js"); >+ loadFunction(@"MSLCodegenAll.js"); >+} >+ >+- (CompileResult*)compileWhlslToMetal:(NSString *)whlslSource error:(NSError * _Nullable __autoreleasing *)error >+{ >+ JSValue *compileFunction = [self.context objectForKeyedSubscript:@"whlslToMsl"]; >+ if (compileFunction) { >+ JSValue * result = [compileFunction callWithArguments:@[whlslSource]]; >+ if (result) { >+ if ([result hasProperty:@"_error"] && [result hasProperty:@"_metalShaderLanguageSource"] && [result hasProperty:@"_originalFunctionNameToMangledNames"]) { >+ if ([[result valueForProperty:@"_error"] isNull]) { >+ NSString *src = [[result valueForProperty:@"_metalShaderLanguageSource"] toString]; >+ NSDictionary *map = [[result valueForProperty:@"_originalFunctionNameToMangledNames"] toDictionary]; >+ return [[CompileResult alloc] initWithMetalSource:src functionNameMap:map]; >+ } >+ >+ *error = [NSError errorWithDomain:@"WhlslCompiler" code:1 userInfo:@{ NSLocalizedDescriptionKey: [[result valueForProperty:@"_error"] toString]}]; >+ return nil; >+ } >+ >+ *error = [NSError errorWithDomain:@"WhlslCompiler" code:2 userInfo:@{ NSLocalizedDescriptionKey: @"Keys not present in result" }]; >+ return nil; >+ } >+ >+ *error = [NSError errorWithDomain:@"WhlslCompiler" code:3 userInfo:@{ NSLocalizedDescriptionKey: @"Compilation failed" }]; >+ return nil; >+ >+ } >+ >+ *error = [NSError errorWithDomain:@"WhlslCompiler" code:4 userInfo:@{ NSLocalizedDescriptionKey: @"Didn't find compilation function" }]; >+ return nil; >+} >+ >+@end >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/CustomMetalView.h b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/CustomMetalView.h >new file mode 100644 >index 0000000000000000000000000000000000000000..25771b57e3bcc24b3aa6853bab86d1551004c4f5 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/CustomMetalView.h >@@ -0,0 +1,28 @@ >+// >+// CustomMetalView.h >+// WHLSL Tests >+// >+// Created by Thomas Denney on 8/3/18. >+// Copyright © 2018 Apple, Inc. All rights reserved. >+// >+ >+#import <Foundation/Foundation.h> >+#import <MetalKit/MetalKit.h> >+ >+NS_ASSUME_NONNULL_BEGIN >+ >+@class CustomMetalView; >+ >+@protocol CustomMetalViewDelegate <NSObject> >+ >+- (void)customMetalView:(CustomMetalView*)metalView scrolledDeltaX:(CGFloat)deltaX deltaY:(CGFloat)deltaY; >+ >+@end >+ >+@interface CustomMetalView : MTKView >+ >+@property id<CustomMetalViewDelegate> scrollDelegate; >+ >+@end >+ >+NS_ASSUME_NONNULL_END >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/CustomMetalView.m b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/CustomMetalView.m >new file mode 100644 >index 0000000000000000000000000000000000000000..9bf02a5b1514e6e3f3a74f0d1984539b21a04f47 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/CustomMetalView.m >@@ -0,0 +1,18 @@ >+// >+// CustomMetalView.m >+// WHLSL Tests >+// >+// Created by Thomas Denney on 8/3/18. >+// Copyright © 2018 Apple, Inc. All rights reserved. >+// >+ >+#import "CustomMetalView.h" >+ >+@implementation CustomMetalView >+ >+- (void)scrollWheel:(NSEvent *)event >+{ >+ [self.scrollDelegate customMetalView:self scrolledDeltaX:event.deltaX deltaY:event.deltaY]; >+} >+ >+@end >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Demo shaders/Default.whlsl b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Demo shaders/Default.whlsl >new file mode 100644 >index 0000000000000000000000000000000000000000..2419df7a0bb9ef7b8477ef029dfe89459417eb73 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Demo shaders/Default.whlsl >@@ -0,0 +1,26 @@ >+struct VertexInput { >+ float2 position; >+ float2 uv; >+} >+ >+struct VertexOutput { >+ float4 wsl_Position; >+ float4 color; >+} >+ >+struct FragmentOutput { >+ float4 wsl_Color; >+} >+ >+vertex VertexOutput vertexShader(VertexInput vertexInput) { >+ VertexOutput result; >+ result.wsl_Position = float4(vertexInput.position, 0., 1.); >+ result.color = float4(vertexInput.uv, 0.0, 1.0); >+ return result; >+} >+ >+fragment FragmentOutput fragmentShader(VertexOutput stageIn) { >+ FragmentOutput result; >+ result.wsl_Color = stageIn.color; >+ return result; >+} >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Demo shaders/Julia.whlsl b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Demo shaders/Julia.whlsl >new file mode 100644 >index 0000000000000000000000000000000000000000..54bee30748181d2db81b52f0c1f2fd72b2925577 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Demo shaders/Julia.whlsl >@@ -0,0 +1,103 @@ >+struct VertexInput { >+ float2 position; >+ float2 uv; >+} >+ >+struct VertexOutput { >+ float4 wsl_Position; >+ float2 uv; >+} >+ >+struct FragmentOutput { >+ float4 wsl_Color; >+} >+ >+vertex VertexOutput vertexShader(VertexInput vertexInput) { >+ VertexOutput result; >+ result.wsl_Position = float4(vertexInput.position, 0., 1.); >+ result.uv = vertexInput.uv; >+ return result; >+} >+ >+fragment FragmentOutput fragmentShader(VertexOutput stageIn) { >+ FragmentOutput result; >+ float m = julia(stageIn.uv); >+ float3 hot = float3(1, 1, 1); >+ float3 cold = float3(0, 1, 0.1); >+ float3 res = interpolate(cold, hot, m); >+ res = hslToRgb(res); >+ result.wsl_Color = float4(res, 1); >+ return result; >+} >+ >+float3 interpolate(float3 x, float3 y, float z) >+{ >+ float3 res; >+ res.x = x.x + (y.x - x.x) * z; >+ res.y = x.y + (y.y - x.y) * z; >+ res.z = x.z + (y.z - x.z) * z; >+ return res; >+} >+ >+float hueToRgb(float p, float q, float t) >+{ >+if(t < 0.0) t += 1.0; >+ if(t > 1.0) t -= 1.0; >+ if(t < 1.0/6.0) return p + (q - p) * 6.0 * t; >+ if(t < 1.0/2.0) return q; >+ if(t < 2.0/3.0) return p + (q - p) * (2.0/3.0 - t) * 6.0; >+ return p; >+} >+ >+float3 hslToRgb(float3 hsl) >+{ >+ float3 rgb; >+ float h = hsl.x; >+ float s = hsl.y; >+ float l = hsl.z; >+ if(s == 0){ >+ rgb = float3(l, l, l); >+ } else { >+ float q; >+ if (l < 0.5) { q = l * (1.0 + s); } else { q = l + s - l * s; } >+ float p = 2.0 * l - q; >+ rgb.x = hueToRgb(p, q, h + 1.0/3.0); >+ rgb.y = hueToRgb(p, q, h); >+ rgb.z = hueToRgb(p, q, h - 1.0/3.0); >+ } >+ >+ return rgb; >+ >+} >+ >+float julia(float2 uv) >+{ >+ float n = 2.0f; >+ float2 z; >+ float2 c; >+ float2 scale = float2(2, 2.9); >+ float2 center = float2(0.7, 0); >+ int iter = 100; >+ c.x = 1.3333 * (uv.x - 0.5) * scale.x - center.x; >+ c.y = (uv.y - 0.5) * scale.y - center.y; >+ z = c; >+ int i; >+ for (i = 0; i < iter; i++) { >+ float x = pow(z.x * z.x + z.y * z.y, n / 2.0) * cos(n * atan2(z.y, z.x)) + c.x; >+ float y = pow(z.x * z.x + z.y * z.y, n / 2.0) * sin(n * atan2(z.y, z.x)) + c.y; >+ >+ if(pow(x, 2.0f) + pow(y, 2.0f) > 16.0f) break; >+ z.x = x; >+ z.y = y; >+ } >+ float res; >+ if (i < iter) { >+ float log_zn = log( z.x*z.x + z.y*z.y ) / 2.0f; >+ float nu = log( log_zn / log(n) ) / log(2.0f); >+ res = (float(i) + 1 - nu) / float(iter); >+ } else { >+ res = 1; >+ } >+ return res; >+} >+ >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Demo shaders/Mandelbrot.whlsl b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Demo shaders/Mandelbrot.whlsl >new file mode 100644 >index 0000000000000000000000000000000000000000..521f0ced4060597803d0f867e6cc0d7729b4e91a >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Demo shaders/Mandelbrot.whlsl >@@ -0,0 +1,98 @@ >+struct VertexInput { >+ float2 position; >+ float2 uv; >+} >+ >+struct VertexOutput { >+ float4 wsl_Position; >+ float2 uv; >+} >+ >+struct FragmentOutput { >+ float4 wsl_Color; >+} >+ >+vertex VertexOutput vertexShader(VertexInput vertexInput) { >+ VertexOutput result; >+ result.wsl_Position = float4(vertexInput.position, 0., 1.); >+ result.uv = vertexInput.uv; >+ return result; >+} >+ >+fragment FragmentOutput fragmentShader(VertexOutput stageIn) { >+ FragmentOutput result; >+ float m = mandelbrot(stageIn.uv); >+ float3 hot = float3(1, 1, 1); >+ float3 cold = float3(0, 1, 0.1); >+ float3 res = interpolate(cold, hot, m); >+ res = hslToRgb(res); >+ result.wsl_Color = float4(res, 1); >+ return result; >+} >+ >+float3 interpolate(float3 x, float3 y, float z) >+{ >+ float3 res; >+ res.x = x.x + (y.x - x.x) * z; >+ res.y = x.y + (y.y - x.y) * z; >+ res.z = x.z + (y.z - x.z) * z; >+ return res; >+} >+ >+float hueToRgb(float p, float q, float t) >+{ >+ if(t < 0.0) t += 1.0; >+ if(t > 1.0) t -= 1.0; >+ if(t < 1.0/6.0) return p + (q - p) * 6.0 * t; >+ if(t < 1.0/2.0) return q; >+ if(t < 2.0/3.0) return p + (q - p) * (2.0/3.0 - t) * 6.0; >+ return p; >+} >+ >+float3 hslToRgb(float3 hsl) >+{ >+ float3 rgb; >+ float h = hsl.x; >+ float s = hsl.y; >+ float l = hsl.z; >+ if(s == 0){ >+ rgb = float3(l, l, l); >+ } else { >+ float q; >+ if (l < 0.5) { q = l * (1.0 + s); } else { q = l + s - l * s; } >+ float p = 2.0 * l - q; >+ rgb.x = hueToRgb(p, q, h + 1.0/3.0); >+ rgb.y = hueToRgb(p, q, h); >+ rgb.z = hueToRgb(p, q, h - 1.0/3.0); >+ } >+ >+ return rgb; >+} >+ >+float mandelbrot(float2 uv) >+{ >+ float2 z; >+ float2 c = uv; >+ int iter = 100; >+ z = c; >+ int i; >+ for (i = 0; i < iter; i++) { >+ float x = (z.x * z.x - z.y * z.y) + c.x; >+ float y = (z.y * z.x + z.x * z.y) + c.y; >+ >+ if(pow(x, 2.0f) + pow(y, 2.0f) > 256.0) break; >+ z.x = x; >+ z.y = y; >+ } >+ float res; >+ if (i < iter) { >+ float log_zn = log( z.x*z.x + z.y*z.y ) / 2; >+ float nu = log( log_zn / log(2.0f) ) / log(2.0f); >+ res = (float(i) + 1 - nu) / float(iter); >+ } else { >+ res = 1; >+ } >+return res; >+} >+ >+ >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Info.plist b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Info.plist >new file mode 100644 >index 0000000000000000000000000000000000000000..01857f52dab33c6e0e0c3c3f28da60461a07a57e >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Info.plist >@@ -0,0 +1,32 @@ >+<?xml version="1.0" encoding="UTF-8"?> >+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> >+<plist version="1.0"> >+<dict> >+ <key>CFBundleDevelopmentRegion</key> >+ <string>$(DEVELOPMENT_LANGUAGE)</string> >+ <key>CFBundleExecutable</key> >+ <string>$(EXECUTABLE_NAME)</string> >+ <key>CFBundleIconFile</key> >+ <string></string> >+ <key>CFBundleIdentifier</key> >+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> >+ <key>CFBundleInfoDictionaryVersion</key> >+ <string>6.0</string> >+ <key>CFBundleName</key> >+ <string>$(PRODUCT_NAME)</string> >+ <key>CFBundlePackageType</key> >+ <string>APPL</string> >+ <key>CFBundleShortVersionString</key> >+ <string>1.0</string> >+ <key>CFBundleVersion</key> >+ <string>1</string> >+ <key>LSMinimumSystemVersion</key> >+ <string>$(MACOSX_DEPLOYMENT_TARGET)</string> >+ <key>NSHumanReadableCopyright</key> >+ <string>Copyright © 2018 Apple, Inc. All rights reserved.</string> >+ <key>NSMainStoryboardFile</key> >+ <string>Main</string> >+ <key>NSPrincipalClass</key> >+ <string>NSApplication</string> >+</dict> >+</plist> >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Metal equivalents/Shaders.metal b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Metal equivalents/Shaders.metal >new file mode 100644 >index 0000000000000000000000000000000000000000..111c34b0fce9e72989632bd68f46afbf9fc39da2 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Metal equivalents/Shaders.metal >@@ -0,0 +1,179 @@ >+// >+// FlatColor.metal >+// WHLSL Tests >+// >+// Created by Thomas Denney on 8/10/18. >+// Copyright © 2018 Apple, Inc. All rights reserved. >+// >+ >+// This file is a hand-modified version of the WHLSL compiler output >+ >+#include <metal_stdlib> >+using namespace metal; >+ >+struct VertexOutput { >+ float4 position [[position]]; >+ float2 uv; >+}; >+ >+struct VertexInput { >+ float2 position [[attribute(0)]]; >+ float2 uv [[attribute(1)]]; >+}; >+ >+struct FragmentOutput { >+ float4 color [[color(0)]]; >+}; >+ >+vertex VertexOutput flatColorVertexShader(VertexInput in [[stage_in]]) >+{ >+ VertexOutput out; >+ out.position = float4(in.position, 0, 1); >+ return out; >+} >+ >+fragment FragmentOutput flatColorFragmentShader(VertexOutput in [[stage_in]]) >+{ >+ FragmentOutput out; >+ out.color = float4(0, 1, 0, 1); >+ return out; >+} >+ >+float3 interpolate(float3 x, float3 y, float z); >+float hueToRgb(float p, float q, float t); >+float3 hslToRgb(float3 hsl); >+float mandelbrot(float2 uv); >+ >+vertex VertexOutput mandelbrotVertexShader(VertexInput vertexInput [[stage_in]]) { >+ VertexOutput result; >+ result.position = float4(vertexInput.position, 0., 1.); >+ result.uv = vertexInput.uv; >+ return result; >+} >+ >+fragment FragmentOutput mandelbrotFragmentShader(VertexOutput stageIn [[stage_in]]) { >+ FragmentOutput result; >+ const float m = mandelbrot(stageIn.uv); >+ const float3 hot = float3(1, 1, 1); >+ const float3 cold = float3(0, 1, 0.1); >+ const float3 res = hslToRgb(interpolate(cold, hot, m)); >+ result.color = float4(res, 1); >+ return result; >+} >+ >+float3 interpolate(float3 x, float3 y, float z) >+{ >+ float3 res; >+ res.x = x.x + (y.x - x.x) * z; >+ res.y = x.y + (y.y - x.y) * z; >+ res.z = x.z + (y.z - x.z) * z; >+ return res; >+} >+ >+float hueToRgb(float p, float q, float t) >+{ >+ if(t < 0.0) t += 1.0; >+ if(t > 1.0) t -= 1.0; >+ if(t < 1.0/6.0) return p + (q - p) * 6.0 * t; >+ if(t < 1.0/2.0) return q; >+ if(t < 2.0/3.0) return p + (q - p) * (2.0/3.0 - t) * 6.0; >+ return p; >+} >+ >+float3 hslToRgb(float3 hsl) >+{ >+ float3 rgb; >+ float h = hsl.x; >+ float s = hsl.y; >+ float l = hsl.z; >+ if(s == 0){ >+ rgb = float3(l, l, l); >+ } else { >+ float q; >+ if (l < 0.5) { q = l * (1.0 + s); } else { q = l + s - l * s; } >+ float p = 2.0 * l - q; >+ rgb.x = hueToRgb(p, q, h + 1.0/3.0); >+ rgb.y = hueToRgb(p, q, h); >+ rgb.z = hueToRgb(p, q, h - 1.0/3.0); >+ } >+ >+ return rgb; >+} >+ >+float mandelbrot(float2 uv) >+{ >+ float2 z; >+ float2 c = uv; >+ int iter = 100; >+ z = c; >+ int i; >+ for (i = 0; i < iter; i++) { >+ float x = (z.x * z.x - z.y * z.y) + c.x; >+ float y = (z.y * z.x + z.x * z.y) + c.y; >+ >+ if(pow(x, 2.0f) + pow(y, 2.0f) > 256.0) break; >+ z.x = x; >+ z.y = y; >+ } >+ float res; >+ if (i < iter) { >+ float log_zn = log( z.x*z.x + z.y*z.y ) / 2; >+ float nu = log( log_zn / log(2.0f) ) / log(2.0f); >+ res = (float(i) + 1 - nu) / float(iter); >+ } else { >+ res = 1; >+ } >+ return res; >+} >+ >+float julia(float2 uv); >+ >+vertex VertexOutput juliaVertexShader(VertexInput vertexInput [[stage_in]]) { >+ VertexOutput result; >+ result.position = float4(vertexInput.position, 0., 1.); >+ result.uv = vertexInput.uv; >+ return result; >+} >+ >+fragment FragmentOutput juliaFragmentShader(VertexOutput stageIn [[stage_in]]) { >+ FragmentOutput result; >+ float m = julia(stageIn.uv); >+ float3 hot = float3(1, 1, 1); >+ float3 cold = float3(0, 1, 0.1); >+ float3 res = interpolate(cold, hot, m); >+ res = hslToRgb(res); >+ result.color = float4(res, 1); >+ return result; >+} >+ >+float julia(float2 uv) >+{ >+ float n = 2.0f; >+ float2 z; >+ float2 c; >+ float2 scale = float2(2, 2.9); >+ float2 center = float2(0.7, 0); >+ int iter = 100; >+ c.x = 1.3333 * (uv.x - 0.5) * scale.x - center.x; >+ c.y = (uv.y - 0.5) * scale.y - center.y; >+ z = c; >+ int i; >+ for (i = 0; i < iter; i++) { >+ float x = pow(z.x * z.x + z.y * z.y, n / 2.0) * cos(n * atan2(z.y, z.x)) + c.x; >+ float y = pow(z.x * z.x + z.y * z.y, n / 2.0) * sin(n * atan2(z.y, z.x)) + c.y; >+ >+ if(pow(x, 2.0f) + pow(y, 2.0f) > 16.0f) break; >+ z.x = x; >+ z.y = y; >+ } >+ float res; >+ if (i < iter) { >+ float log_zn = log( z.x*z.x + z.y*z.y ) / 2.0f; >+ float nu = log( log_zn / log(n) ) / log(2.0f); >+ res = (float(i) + 1 - nu) / float(iter); >+ } else { >+ res = 1; >+ } >+ return res; >+} >+ >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Renderer/OffscreenRenderer.h b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Renderer/OffscreenRenderer.h >new file mode 100644 >index 0000000000000000000000000000000000000000..54e4e08d3897fdca7a34ffeecd3f02b8bbd43629 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Renderer/OffscreenRenderer.h >@@ -0,0 +1,26 @@ >+// >+// OffscreenRenderer.h >+// WHLSL Tests >+// >+// Created by Thomas Denney on 7/11/18. >+// Copyright © 2018 Apple, Inc. All rights reserved. >+// >+ >+#import "Renderer.h" >+ >+NS_ASSUME_NONNULL_BEGIN >+ >+@interface OffscreenRenderer : Renderer >+ >+@property MTLPixelFormat outputPixelFormat; >+ >+- (void)setLibrary:(id<MTLLibrary>)library vertexShaderName:(NSString*)vertexShader fragmentShaderName:(NSString*)fragmentShaderName; >+- (void)readTextureDataToBuffer:(uint8_t*)buffer bytesPerRow:(NSUInteger)bytesPerRow; >+ >+- (int)intValue; >+- (unsigned int)uintValue; >+- (float)floatValue; >+ >+@end >+ >+NS_ASSUME_NONNULL_END >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Renderer/OffscreenRenderer.m b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Renderer/OffscreenRenderer.m >new file mode 100644 >index 0000000000000000000000000000000000000000..95f7c4f7f982de11c763305b89f268a7b3e37c6b >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Renderer/OffscreenRenderer.m >@@ -0,0 +1,87 @@ >+// >+// OffscreenRenderer.m >+// WHLSL Tests >+// >+// Created by Thomas Denney on 7/11/18. >+// Copyright © 2018 Apple, Inc. All rights reserved. >+// >+ >+#import "OffscreenRenderer.h" >+ >+@interface OffscreenRenderer () >+{ >+ id<MTLTexture> _outputTexture; >+} >+ >+@end >+ >+@implementation OffscreenRenderer >+ >+- (void)setLibrary:(id<MTLLibrary>)library vertexShaderName:(NSString*)vertexShader fragmentShaderName:(NSString*)fragmentShaderName >+{ >+ [super setLibrary:library vertexShaderName:vertexShader fragmentShaderName:fragmentShaderName pixelFormat:self.outputPixelFormat]; >+} >+ >+- (void)setTargetWidth:(NSUInteger)width setTargetHeight:(NSUInteger)height >+{ >+ [super setTargetWidth:width setTargetHeight:height]; >+ MTLTextureDescriptor *outputDescriptor = [MTLTextureDescriptor texture2DDescriptorWithPixelFormat:self.outputPixelFormat width:self.targetWidth height:self.targetHeight mipmapped:NO]; >+ outputDescriptor.usage = MTLTextureUsageRenderTarget; >+ outputDescriptor.storageMode = MTLStorageModeManaged; >+ _outputTexture = [self.device newTextureWithDescriptor:outputDescriptor]; >+} >+ >+- (MTLRenderPassDescriptor*)renderPassDescriptor >+{ >+ MTLRenderPassDescriptor *renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]; >+ renderPassDescriptor.colorAttachments[0].texture = _outputTexture; >+ return renderPassDescriptor; >+} >+ >+- (void)configureCommandBufferBeforeCommit:(id<MTLCommandBuffer>)commandBuffer >+{ >+ id <MTLBlitCommandEncoder> blitEncoder = [commandBuffer blitCommandEncoder]; >+ [blitEncoder synchronizeResource:_outputTexture]; >+ [blitEncoder endEncoding]; >+} >+ >+- (void)readTextureDataToBuffer:(uint8_t *)buffer bytesPerRow:(NSUInteger)bytesPerRow >+{ >+ // The texture isn't mipmapped, so we use the default level of 0 >+ [_outputTexture getBytes:buffer bytesPerRow:bytesPerRow fromRegion:MTLRegionMake2D(0, 0, self.targetWidth, self.targetHeight) mipmapLevel:0]; >+} >+ >+- (int)intValue >+{ >+ // We always have 4 bytes per pixel >+ NSUInteger length = self.targetWidth * self.targetHeight * 4; >+ uint8_t *buffer = calloc(length, sizeof(uint8_t)); >+ [self readTextureDataToBuffer:(uint8_t*)buffer bytesPerRow:4 * self.targetWidth]; >+ int intValue = ((int*)buffer)[0]; >+ free(buffer); >+ return intValue; >+} >+ >+- (unsigned int)uintValue >+{ >+ // We always have 4 bytes per pixel >+ NSUInteger length = self.targetWidth * self.targetHeight * 4; >+ uint8_t *buffer = calloc(length, sizeof(uint8_t)); >+ [self readTextureDataToBuffer:(uint8_t*)buffer bytesPerRow:4 * self.targetWidth]; >+ unsigned int uintValue = ((unsigned int*)buffer)[0]; >+ free(buffer); >+ return uintValue; >+} >+ >+- (float)floatValue >+{ >+ // We always have 4 bytes per pixel >+ NSUInteger length = self.targetWidth * self.targetHeight * 4; >+ uint8_t *buffer = calloc(length, sizeof(uint8_t)); >+ [self readTextureDataToBuffer:(uint8_t*)buffer bytesPerRow:4 * self.targetWidth]; >+ float floatValue = ((float*)buffer)[0]; >+ free(buffer); >+ return floatValue; >+} >+ >+@end >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Renderer/OnscreenRenderer.h b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Renderer/OnscreenRenderer.h >new file mode 100644 >index 0000000000000000000000000000000000000000..14a3b02078725ffdc4a736f057c9c59353b5c11e >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Renderer/OnscreenRenderer.h >@@ -0,0 +1,25 @@ >+// >+// Renderer.h >+// WHLSL Toy >+// >+// Created by Thomas Denney on 7/10/18. >+// Copyright © 2018 Apple, Inc. All rights reserved. >+// >+ >+#import <Foundation/Foundation.h> >+ >+#import "Renderer.h" >+ >+NS_ASSUME_NONNULL_BEGIN >+ >+@interface OnscreenRenderer : Renderer<MTKViewDelegate> >+ >+- (instancetype)initWithView:(MTKView*)view device:(id<MTLDevice>)device; >+ >+@property (readonly) MTKView *view; >+ >+- (void)setShaderSource:(NSString*)source vertexShaderName:(NSString*)vertexShader fragmentShaderName:(NSString*)fragmentShader; >+ >+@end >+ >+NS_ASSUME_NONNULL_END >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Renderer/OnscreenRenderer.m b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Renderer/OnscreenRenderer.m >new file mode 100644 >index 0000000000000000000000000000000000000000..f01b44f8e2c9624de15630aa41971b722c5085ca >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Renderer/OnscreenRenderer.m >@@ -0,0 +1,65 @@ >+// >+// Renderer.m >+// WHLSL Toy >+// >+// Created by Thomas Denney on 7/10/18. >+// Copyright © 2018 Apple, Inc. All rights reserved. >+// >+ >+#import "OnscreenRenderer.h" >+ >+#import <simd/simd.h> >+ >+@interface OnscreenRenderer () >+ >+@property MTKView *view; >+@property CGSize drawableSize; >+ >+@end >+ >+@implementation OnscreenRenderer >+ >+- (instancetype)initWithView:(MTKView *)view device:(nonnull id<MTLDevice>)device >+{ >+ self = [super initWithDevice:device]; >+ if (self) { >+ self.view = view; >+ self.view.delegate = self; >+ } >+ return self; >+} >+ >+- (void)mtkView:(MTKView *)view drawableSizeWillChange:(CGSize)size >+{ >+ [self setTargetWidth:size.width setTargetHeight:size.height]; >+} >+ >+- (void)drawInMTKView:(MTKView *)view >+{ >+ [self draw]; >+} >+ >+- (MTLRenderPassDescriptor*)renderPassDescriptor >+{ >+ return self.view.currentRenderPassDescriptor; >+} >+ >+- (void)configureCommandBufferBeforeCommit:(id<MTLCommandBuffer>)commandBuffer >+{ >+ [commandBuffer presentDrawable:self.view.currentDrawable]; >+} >+ >+- (void)setShaderSource:(NSString *)source vertexShaderName:(NSString *)vertexShaderName fragmentShaderName:(NSString *)fragmentShaderName >+{ >+ MTLCompileOptions *compileOptions = [[MTLCompileOptions alloc] init]; >+ NSError *error = nil; >+ id<MTLLibrary> library = [self.device newLibraryWithSource:source options:compileOptions error:&error]; >+ if (!library && error) { >+ NSLog(@"Compile error: %@", error.localizedDescription); >+ return; >+ } >+ >+ [self setLibrary:library vertexShaderName:vertexShaderName fragmentShaderName:fragmentShaderName pixelFormat:self.view.colorPixelFormat]; >+} >+ >+@end >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Renderer/Renderer.h b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Renderer/Renderer.h >new file mode 100644 >index 0000000000000000000000000000000000000000..e3ccfb7205c5909aa14835132d0c2e8d99d8b62d >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Renderer/Renderer.h >@@ -0,0 +1,37 @@ >+// >+// Renderer.h >+// WHLSL Tests >+// >+// Created by Thomas Denney on 7/11/18. >+// Copyright © 2018 Apple, Inc. All rights reserved. >+// >+ >+#import <Foundation/Foundation.h> >+#import <MetalKit/MetalKit.h> >+ >+NS_ASSUME_NONNULL_BEGIN >+ >+@interface Renderer : NSObject >+ >+- (instancetype)initWithDevice:(id<MTLDevice>)device; >+ >+@property (nonatomic) simd_float3x3 transformMatrix; >+ >+@property (readonly) id<MTLDevice> device; >+ >+@property (readonly) NSUInteger targetWidth; >+@property (readonly) NSUInteger targetHeight; >+ >+- (void)setTargetWidth:(NSUInteger)width setTargetHeight:(NSUInteger)height; >+ >+- (void)setLibrary:(id<MTLLibrary>)library vertexShaderName:(NSString*)vertexShader fragmentShaderName:(NSString*)fragmentShaderName pixelFormat:(MTLPixelFormat)pixelFormat; >+ >+- (void)draw; >+ >+// Methods that can be overloaded to configure the render pipeline >+- (MTLRenderPassDescriptor*)renderPassDescriptor; >+- (void)configureCommandBufferBeforeCommit:(id<MTLCommandBuffer>)commandBuffer; >+ >+@end >+ >+NS_ASSUME_NONNULL_END >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Renderer/Renderer.m b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Renderer/Renderer.m >new file mode 100644 >index 0000000000000000000000000000000000000000..64b45bdca57962a3fdb5ab4cc4beabcc018497da >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/Renderer/Renderer.m >@@ -0,0 +1,155 @@ >+// >+// Renderer.m >+// WHLSL Tests >+// >+// Created by Thomas Denney on 7/11/18. >+// Copyright © 2018 Apple, Inc. All rights reserved. >+// >+ >+#import "Renderer.h" >+ >+// This should mirror the structure that is used for the vertex shaders >+typedef struct { >+ vector_float2 position; >+ vector_float2 uv; >+} VertexStruct; >+ >+// A quad that fills the viewport >+static VertexStruct vertexData[] = >+{ >+ // 2D positions >+ { { -1.0, -1.0 }, { 0, 0 } }, >+ { { 1.0, -1.0 }, { 1, 0 } }, >+ { { -1.0, 1.0 }, { 0, 1 } }, >+ { { 1.0, 1.0 }, { 1, 1 } } >+}; >+ >+@interface Renderer () >+ >+@property id<MTLDevice> device; >+@property NSUInteger targetWidth; >+@property NSUInteger targetHeight; >+ >+@end >+ >+@implementation Renderer { >+ id<MTLCommandQueue> _commandQueue; >+ id<MTLLibrary> _library; >+ >+ MTLRenderPipelineDescriptor *_pipelineStateDescriptor; >+ >+ id<MTLRenderPipelineState> _pipelineState; >+} >+ >+- (instancetype)initWithDevice:(id<MTLDevice>)device >+{ >+ self = [super init]; >+ if (self) { >+ _device = device; >+ _commandQueue = [_device newCommandQueue]; >+ self.transformMatrix = matrix_identity_float3x3; >+ } >+ return self; >+} >+ >+- (void)setLibrary:(id<MTLLibrary>)library vertexShaderName:(NSString*)vertexShaderName fragmentShaderName:(NSString*)fragmentShaderName pixelFormat:(MTLPixelFormat)pixelFormat >+{ >+ _library = library; >+ id<MTLFunction> vertexFunction = [_library newFunctionWithName:vertexShaderName]; >+ id<MTLFunction> fragmentFunction = [_library newFunctionWithName:fragmentShaderName]; >+ >+ // Configure a pipeline descriptor that is used to create a pipeline state >+ _pipelineStateDescriptor = [[MTLRenderPipelineDescriptor alloc] init]; >+ >+ MTLVertexDescriptor *vertexDescriptor = [MTLVertexDescriptor vertexDescriptor]; >+ vertexDescriptor.attributes[0].format = MTLVertexFormatFloat2; >+ vertexDescriptor.attributes[0].bufferIndex = 0; >+ vertexDescriptor.attributes[0].offset = 0; >+ >+ vertexDescriptor.attributes[1].format = MTLVertexFormatFloat2; >+ vertexDescriptor.attributes[1].bufferIndex = 0; >+ vertexDescriptor.attributes[1].offset = offsetof(VertexStruct, uv); >+ >+ vertexDescriptor.layouts[0].stride = sizeof(VertexStruct); >+ vertexDescriptor.layouts[0].stepFunction = MTLVertexStepFunctionPerVertex; >+ >+ _pipelineStateDescriptor.vertexDescriptor = vertexDescriptor; >+ >+ _pipelineStateDescriptor.label = @"Simple Pipeline"; >+ _pipelineStateDescriptor.vertexFunction = vertexFunction; >+ _pipelineStateDescriptor.fragmentFunction = fragmentFunction; >+ _pipelineStateDescriptor.colorAttachments[0].pixelFormat = pixelFormat; >+ >+ NSError *error = nil; >+ _pipelineState = [_device newRenderPipelineStateWithDescriptor:_pipelineStateDescriptor error:&error]; >+ >+ NSAssert(_pipelineState, @"Failed to created pipeline state: %@", error.localizedDescription); >+} >+ >+- (void)setTargetWidth:(NSUInteger)width setTargetHeight:(NSUInteger)height >+{ >+ _targetWidth = width; >+ _targetHeight = height; >+} >+ >+- (void)draw >+{ >+ if (!_pipelineState) >+ return; >+ >+ // Create a new command buffer for each render pass to the current drawable >+ id<MTLCommandBuffer> commandBuffer = [_commandQueue commandBuffer]; >+ commandBuffer.label = @"MyCommand"; >+ >+ MTLRenderPassDescriptor *renderPassDescriptor = [self renderPassDescriptor]; >+ >+ NSAssert(renderPassDescriptor, @"nil MTLRenderPassDescriptor"); >+ >+ renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(0, 0, 0, 0); >+ renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear; >+ renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore; >+ >+ // Create a render command encoder so we can render into something >+ id<MTLRenderCommandEncoder> renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor]; >+ renderEncoder.label = @"MyRenderEncoder"; >+ >+ [renderEncoder setViewport:(MTLViewport) { 0.0, 0.0, _targetWidth, _targetHeight, -1.0, 1.0 }]; >+ >+ [renderEncoder setRenderPipelineState:_pipelineState]; >+ >+ [renderEncoder setVertexBytes:vertexData length:sizeof(vertexData) atIndex:0]; >+ >+ [renderEncoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4]; >+ >+ [renderEncoder endEncoding]; >+ >+ [self configureCommandBufferBeforeCommit:commandBuffer]; >+ >+ [commandBuffer commit]; >+ [commandBuffer waitUntilCompleted]; >+} >+ >+- (void)setTransformMatrix:(simd_float3x3)transformMatrix >+{ >+ _transformMatrix = transformMatrix; >+ simd_float3 v0 = matrix_multiply(_transformMatrix, vector3(0.0f, 0.0f, 1.0f)); >+ simd_float3 v1 = matrix_multiply(_transformMatrix, vector3(1.0f, 0.0f, 1.0f)); >+ simd_float3 v2 = matrix_multiply(_transformMatrix, vector3(0.0f, 1.0f, 1.0f)); >+ simd_float3 v3 = matrix_multiply(_transformMatrix, vector3(1.0f, 1.0f, 1.0f)); >+ >+ vertexData[0].uv = vector2(v0.x, v0.y); >+ vertexData[1].uv = vector2(v1.x, v1.y); >+ vertexData[2].uv = vector2(v2.x, v2.y); >+ vertexData[3].uv = vector2(v3.x, v3.y); >+} >+ >+- (MTLRenderPassDescriptor *)renderPassDescriptor >+{ >+ return nil; >+} >+ >+- (void)configureCommandBufferBeforeCommit:(id<MTLCommandBuffer>)commandBuffer >+{ >+} >+ >+@end >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/TestCallArgument.h b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/TestCallArgument.h >new file mode 100644 >index 0000000000000000000000000000000000000000..4d8b0346a2b8d3602628f489a67ea63b4878646f >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/TestCallArgument.h >@@ -0,0 +1,37 @@ >+// >+// TestCallArgument.h >+// WHLSL Tests >+// >+// Created by Thomas Denney on 8/3/18. >+// Copyright © 2018 Apple, Inc. All rights reserved. >+// >+ >+#import <Foundation/Foundation.h> >+ >+typedef enum : NSUInteger { >+ WHLSLTypeBool, >+ WHLSLTypeUchar, >+ WHLSLTypeShort, >+ WHLSLTypeInt, >+ WHLSLTypeUshort, >+ WHLSLTypeUint, >+ WHLSLTypeHalf, >+ WHLSLTypeFloat >+} WHLSLType; >+ >+NSString* WHLSLTypeString(WHLSLType type); >+ >+NS_ASSUME_NONNULL_BEGIN >+ >+@interface TestCallArgument : NSObject >+ >+- (instancetype)initWithValue:(NSNumber*)value type:(WHLSLType)type; >+ >+@property (readonly) NSNumber* value; >+@property (readonly) WHLSLType type; >+ >+- (NSString*)whlslSource; >+ >+@end >+ >+NS_ASSUME_NONNULL_END >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/TestCallArgument.m b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/TestCallArgument.m >new file mode 100644 >index 0000000000000000000000000000000000000000..cb8a8275f8a90f2c30c4f270c6e1a6917393eefe >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/TestCallArgument.m >@@ -0,0 +1,76 @@ >+// >+// TestCallArgument.m >+// WHLSL Tests >+// >+// Created by Thomas Denney on 8/3/18. >+// Copyright © 2018 Apple, Inc. All rights reserved. >+// >+ >+#import "TestCallArgument.h" >+ >+NSString* WHLSLTypeString(WHLSLType type) >+{ >+ switch (type) { >+ case WHLSLTypeBool: >+ return @"bool"; >+ case WHLSLTypeUchar: >+ return @"uchar"; >+ case WHLSLTypeShort: >+ return @"ushort"; >+ case WHLSLTypeInt: >+ return @"int"; >+ case WHLSLTypeUshort: >+ return @"ushort"; >+ case WHLSLTypeUint: >+ return @"uint"; >+ case WHLSLTypeHalf: >+ return @"half"; >+ case WHLSLTypeFloat: >+ return @"float"; >+ default: >+ return nil; >+ } >+} >+ >+@interface TestCallArgument () >+ >+@property NSNumber* value; >+@property WHLSLType type; >+ >+@end >+ >+@implementation TestCallArgument >+ >+- (instancetype)initWithValue:(NSNumber *)value type:(WHLSLType)type >+{ >+ if (self = [super init]) { >+ self.value = value; >+ self.type = type; >+ } >+ return self; >+} >+ >+// FIXME: This should probably be MSL source >+- (NSString*)whlslSource >+{ >+ switch (self.type) { >+ case WHLSLTypeBool: >+ return self.value.boolValue ? @"true" : @"false"; >+ case WHLSLTypeUchar: >+ return [NSString stringWithFormat:@"uint8_t(%uu)", self.value.unsignedIntValue]; >+ case WHLSLTypeShort: >+ return [NSString stringWithFormat:@"int16_t(%d)", self.value.intValue]; >+ case WHLSLTypeUshort: >+ return [NSString stringWithFormat:@"uint16_t(%uu)", self.value.unsignedIntValue]; >+ case WHLSLTypeInt: >+ return [NSString stringWithFormat:@"%d", self.value.intValue]; >+ case WHLSLTypeUint: >+ return [NSString stringWithFormat:@"%uu", self.value.unsignedIntValue]; >+ case WHLSLTypeHalf: >+ return [NSString stringWithFormat:@"%f", self.value.floatValue]; >+ case WHLSLTypeFloat: >+ return [NSString stringWithFormat:@"half(%f)", self.value.floatValue]; >+ } >+} >+ >+@end >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/TestDescription.h b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/TestDescription.h >new file mode 100644 >index 0000000000000000000000000000000000000000..2968e7d0bacdfc17f134acb8f7e4bae9d37a825d >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/TestDescription.h >@@ -0,0 +1,33 @@ >+// >+// TestDescription.h >+// WHLSL Tests >+// >+// Created by Thomas Denney on 8/3/18. >+// Copyright © 2018 Apple, Inc. All rights reserved. >+// >+ >+@import Foundation; >+#import "TestCallArgument.h" >+ >+@class TestFamily; >+ >+NS_ASSUME_NONNULL_BEGIN >+ >+@interface TestDescription : NSObject >+ >+- (instancetype)initWithFunctionName:(NSString*)functionName arguments:(NSArray<TestCallArgument*>*)arguments; >+ >+@property NSString* functionName; >+@property NSArray<TestCallArgument*>* arguments; >+ >+@property WHLSLType returnType; >+@property NSNumber* expectation; >+ >+@property (weak) TestFamily* testFamily; >+@property NSString* fragmentShaderName; >+ >+- (NSString*)metalFragmentShaderSourceForCallToMetalFunction:(NSString*)compiledNameOfFunction; >+ >+@end >+ >+NS_ASSUME_NONNULL_END >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/TestDescription.m b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/TestDescription.m >new file mode 100644 >index 0000000000000000000000000000000000000000..21f20d38131301273a9065f2312e7d63a128f952 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/TestDescription.m >@@ -0,0 +1,105 @@ >+// >+// TestDescription.m >+// WHLSL Tests >+// >+// Created by Thomas Denney on 8/3/18. >+// Copyright © 2018 Apple, Inc. All rights reserved. >+// >+ >+#import "TestDescription.h" >+ >+@implementation TestDescription >+ >+- (instancetype)initWithFunctionName:(NSString *)functionName arguments:(NSArray<TestCallArgument *> *)arguments >+{ >+ if (self = [super init]) { >+ self.functionName = functionName; >+ self.arguments = arguments; >+ } >+ return self; >+} >+ >+- (NSString*)callString:(NSString*)compiledNameOfFunction >+{ >+ NSMutableString* string = [NSMutableString new]; >+ [string appendFormat:@"%@(", compiledNameOfFunction]; >+ >+ BOOL first = YES; >+ for (TestCallArgument* argument in self.arguments) { >+ if (!first) >+ [string appendFormat:@", %@", argument.whlslSource]; >+ else >+ [string appendString:argument.whlslSource]; >+ first = NO; >+ } >+ >+ [string appendString:@")"]; >+ return string; >+} >+ >+- (NSString*)description >+{ >+ NSMutableString* string = [NSMutableString new]; >+ [string appendFormat:@"%@ %@(", WHLSLTypeString(self.returnType), self.functionName]; >+ BOOL first = YES; >+ for (TestCallArgument* argument in self.arguments) { >+ if (!first) >+ [string appendFormat:@", %@ %@", WHLSLTypeString(self.returnType), argument.whlslSource]; >+ else >+ [string appendFormat:@"%@ %@", WHLSLTypeString(self.returnType), argument.whlslSource]; >+ first = NO; >+ } >+ [string appendString:@")"]; >+ return string; >+} >+ >+- (NSString*)metalFragmentShaderSourceForCallToMetalFunction:(NSString *)compiledNameOfFunction >+{ >+ NSString* returnTypeString; >+ switch (self.returnType) { >+ case WHLSLTypeBool: >+ case WHLSLTypeUchar: >+ case WHLSLTypeUshort: >+ case WHLSLTypeUint: >+ returnTypeString = @"FragmentOutputUint"; >+ break; >+ case WHLSLTypeShort: >+ case WHLSLTypeInt: >+ returnTypeString = @"FragmentOutputInt"; >+ break; >+ case WHLSLTypeHalf: >+ case WHLSLTypeFloat: >+ returnTypeString = @"FragmentOutputFloat"; >+ break; >+ } >+ NSMutableString* string = [NSMutableString new]; >+ [string appendFormat:@"fragment %@ %@(VertexOutput stageIn [[stage_in]])\n", returnTypeString, self.fragmentShaderName]; >+ [string appendString:@"{\n"]; >+ [string appendFormat:@" %@ fragmentOutput;\n", returnTypeString]; >+ >+ NSString * call = [self callString:compiledNameOfFunction]; >+ >+ switch (self.returnType) { >+ case WHLSLTypeBool: >+ case WHLSLTypeUchar: >+ case WHLSLTypeUshort: >+ case WHLSLTypeUint: >+ [string appendFormat:@" fragmentOutput.result = uint32_t(%@);\n", call]; >+ break; >+ case WHLSLTypeShort: >+ case WHLSLTypeInt: >+ [string appendFormat:@" fragmentOutput.result = int32_t(%@);\n", call]; >+ break; >+ case WHLSLTypeHalf: >+ case WHLSLTypeFloat: >+ [string appendFormat:@" fragmentOutput.result = float(%@);\n", call]; >+ break; >+ } >+ >+ [string appendString:@" return fragmentOutput;\n"]; >+ [string appendString:@"}\n"]; >+ >+ return string; >+} >+ >+@end >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/TestFamily.h b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/TestFamily.h >new file mode 100644 >index 0000000000000000000000000000000000000000..98e88d77d014fb3a1e692f2d80b810b13e4b4e1e >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/TestFamily.h >@@ -0,0 +1,37 @@ >+// >+// TestFamily.h >+// WHLSL Tests >+// >+// Created by Thomas Denney on 8/3/18. >+// Copyright © 2018 Apple, Inc. All rights reserved. >+// >+ >+#import <Foundation/Foundation.h> >+#import "TestCallArgument.h" >+#import "TestDescription.h" >+ >+NS_ASSUME_NONNULL_BEGIN >+ >+@interface TestFamily : NSObject >+ >+- (instancetype)initWithName:(NSString*)name source:(NSString*)source; >+ >+@property (readonly) NSString* name; >+@property (readonly) NSString* whlslSource; >+@property (readonly) NSUInteger totalTestCaseCount; >+ >+- (void)addTestDescription:(TestDescription*)testDescription; >+- (NSArray<TestDescription*>*)testsForReturnType:(WHLSLType)type; >+ >++ (NSString*)sharedMetalSource; >+- (NSString*)metalSourceForCallingFunctionsWithCompiledNames:(NSDictionary<NSString*,NSString*>*)compiledNames; >+ >++ (NSArray<TestFamily*>*)allTests; >+ >+- (NSArray<TestDescription*>*)integerTests; >+- (NSArray<TestDescription*>*)unsignedIntegerTests; >+- (NSArray<TestDescription*>*)floatTests; >+ >+@end >+ >+NS_ASSUME_NONNULL_END >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/TestFamily.m b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/TestFamily.m >new file mode 100644 >index 0000000000000000000000000000000000000000..dd2e4d56fa375d972a6446da3cb55b9845d94055 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/TestFamily.m >@@ -0,0 +1,222 @@ >+// >+// TestFamily.m >+// WHLSL Tests >+// >+// Created by Thomas Denney on 8/3/18. >+// Copyright © 2018 Apple, Inc. All rights reserved. >+// >+ >+#import "TestFamily.h" >+ >+@import JavaScriptCore; >+ >+@interface TestFamily () >+ >+@property NSString* name; >+@property NSString* whlslSource; >+@property NSUInteger totalTestCaseCount; >+ >+@property NSMutableDictionary<NSNumber*, NSMutableArray<TestDescription*>*>* tests; >+ >+@end >+ >+@implementation TestFamily >+ >+- (instancetype)initWithName:(NSString *)name source:(NSString *)source >+{ >+ if (self = [super init]) { >+ self.name = name; >+ self.whlslSource = source; >+ self.tests = [NSMutableDictionary new]; >+ self.tests[@(WHLSLTypeBool)] = [NSMutableArray new]; >+ self.tests[@(WHLSLTypeUchar)] = [NSMutableArray new]; >+ self.tests[@(WHLSLTypeShort)] = [NSMutableArray new]; >+ self.tests[@(WHLSLTypeUshort)] = [NSMutableArray new]; >+ self.tests[@(WHLSLTypeUint)] = [NSMutableArray new]; >+ self.tests[@(WHLSLTypeInt)] = [NSMutableArray new]; >+ self.tests[@(WHLSLTypeFloat)] = [NSMutableArray new]; >+ self.tests[@(WHLSLTypeHalf)] = [NSMutableArray new]; >+ } >+ return self; >+} >+ >+- (void)addTestDescription:(TestDescription *)testDescription >+{ >+ [self.tests[@(testDescription.returnType)] addObject:testDescription]; >+ testDescription.testFamily = self; >+ testDescription.fragmentShaderName = [NSString stringWithFormat:@"fragment_%@_%ld", self.name, self.totalTestCaseCount++]; >+} >+ >+- (NSArray<TestDescription*>*)testsForReturnType:(WHLSLType)type >+{ >+ return self.tests[@(type)]; >+} >+ >+- (NSArray<TestDescription*>*)integerTests >+{ >+ NSMutableArray<TestDescription*>* result = [NSMutableArray new]; >+ [result addObjectsFromArray:[self testsForReturnType:WHLSLTypeShort]]; >+ [result addObjectsFromArray:[self testsForReturnType:WHLSLTypeInt]]; >+ return result; >+} >+ >+- (NSArray<TestDescription*>*)unsignedIntegerTests >+{ >+ NSMutableArray<TestDescription*>* result = [NSMutableArray new]; >+ [result addObjectsFromArray:[self testsForReturnType:WHLSLTypeBool]]; >+ [result addObjectsFromArray:[self testsForReturnType:WHLSLTypeUchar]]; >+ [result addObjectsFromArray:[self testsForReturnType:WHLSLTypeUshort]]; >+ [result addObjectsFromArray:[self testsForReturnType:WHLSLTypeUint]]; >+ return result; >+} >+ >+- (NSArray<TestDescription*>*)floatTests >+{ >+ NSMutableArray<TestDescription*>* result = [NSMutableArray new]; >+ [result addObjectsFromArray:[self testsForReturnType:WHLSLTypeHalf]]; >+ [result addObjectsFromArray:[self testsForReturnType:WHLSLTypeFloat]]; >+ return result; >+} >+ >++ (NSString*)sharedMetalSource >+{ >+ static NSString* result; >+ static dispatch_once_t onceToken; >+ dispatch_once(&onceToken, ^{ >+ NSString* path = [[NSBundle mainBundle] pathForResource:@"_SharedMetal" ofType:@"txt"]; >+ result = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil]; >+ }); >+ return result; >+} >+ >+- (NSString*)metalSourceForCallingFunctionsWithCompiledNames:(NSDictionary<NSString *,NSString *> *)compiledNames >+{ >+ NSMutableString* source = [NSMutableString new]; >+ >+ [self.tests enumerateKeysAndObjectsUsingBlock:^(NSNumber * _Nonnull type, NSMutableArray<TestDescription *> * _Nonnull tests, BOOL * _Nonnull stop) { >+ for (TestDescription* testDescription in tests) { >+ [source appendFormat:@"%@\n", [testDescription metalFragmentShaderSourceForCallToMetalFunction:compiledNames[testDescription.functionName]]]; >+ } >+ }]; >+ >+ return source; >+} >+ >++ (NSArray<TestFamily*>*)allTests >+{ >+ JSContext* compilerContext = [JSContext new]; >+ // The test suite doesn't actually need to load any of its dependencies in order to generate the data needed for test execution. >+ compilerContext[@"load"] = ^void(NSString* filePath) {}; >+ // Some of the tests directly call prepare; but these tests can be ignored because they are testing aspects of the interpreter. >+ compilerContext[@"prepare"] = ^id(NSString* filePath, NSNumber* lineNumber, NSString* src, NSNumber* enableInlining) { >+ return nil; >+ }; >+ >+ NSString* testFile = [NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Test" ofType:@"js"] encoding:NSUTF8StringEncoding error:nil]; >+ [compilerContext evaluateScript:testFile]; >+ >+ __block NSString *currentTestName = nil; >+ __block BOOL includeTest = YES; >+ >+ NSMutableArray<TestFamily*>* testFamilies = [NSMutableArray new]; >+ >+ // See the bottom of Test.js >+ compilerContext[@"runningInCocoaHost"] = [JSValue valueWithBool:YES inContext:compilerContext]; >+ >+ compilerContext[@"doPrep"] = ^TestFamily*(NSString* code) { >+ TestFamily* family = [[TestFamily alloc] initWithName:currentTestName source:code]; >+ [testFamilies addObject:family]; >+ includeTest = YES; >+ return family; >+ }; >+ >+ compilerContext.exceptionHandler = ^(JSContext *context, JSValue *exception) { >+ includeTest = NO; >+ }; >+ // FIXME: In line with Test.js, these should raise some kind of error if the value cannot be cast safely. >+ // However, the conversion to an NSNumber may have already lost the precision. >+ >+ compilerContext[@"makeInt"] = ^TestCallArgument*(TestFamily* program, NSNumber* number) { >+ return [[TestCallArgument alloc] initWithValue:number type:WHLSLTypeInt]; >+ }; >+ >+ compilerContext[@"makeUint"] = ^TestCallArgument*(TestFamily* program, NSNumber* number) { >+ return [[TestCallArgument alloc] initWithValue:number type:WHLSLTypeUint]; >+ }; >+ >+ compilerContext[@"makeUchar"] = ^TestCallArgument*(TestFamily* program, NSNumber* number) { >+ return [[TestCallArgument alloc] initWithValue:number type:WHLSLTypeUchar]; >+ }; >+ >+ compilerContext[@"makeBool"] = ^TestCallArgument*(TestFamily* program, NSNumber* number) { >+ return [[TestCallArgument alloc] initWithValue:number type:WHLSLTypeBool]; >+ }; >+ >+ compilerContext[@"makeFloat"] = ^TestCallArgument*(TestFamily* program, NSNumber* number) { >+ return [[TestCallArgument alloc] initWithValue:number type:WHLSLTypeFloat]; >+ }; >+ >+ // FIXME: This should have the same logic as the implementation in Tests.js >+ compilerContext[@"makeCastedFloat"] = ^TestCallArgument*(TestFamily* program, NSNumber* number) { >+ return [[TestCallArgument alloc] initWithValue:number type:WHLSLTypeFloat]; >+ }; >+ >+ compilerContext[@"makeHalf"] = ^TestCallArgument*(TestFamily* program, NSNumber* number) { >+ return [[TestCallArgument alloc] initWithValue:number type:WHLSLTypeHalf]; >+ }; >+ >+ compilerContext[@"callFunction"] = ^TestDescription*(TestFamily* program, NSString* functionName, NSArray* args) { >+ return [[TestDescription alloc] initWithFunctionName:functionName arguments:args]; >+ }; >+ >+ void(^addTest)(TestFamily*,TestDescription*,NSNumber*,WHLSLType) = ^void(TestFamily* program, TestDescription* testDesc, NSNumber* expectation, WHLSLType type) { >+ if (includeTest) { >+ testDesc.returnType = type; >+ testDesc.expectation = expectation; >+ [program addTestDescription:testDesc]; >+ } >+ }; >+ >+ compilerContext[@"checkInt"] = ^void(TestFamily* program, TestDescription* testDesc, NSNumber* expectation) { >+ addTest(program, testDesc, expectation, WHLSLTypeInt); >+ }; >+ >+ compilerContext[@"checkUint"] = ^void(TestFamily* program, TestDescription* testDesc, NSNumber* expectation) { >+ addTest(program, testDesc, expectation, WHLSLTypeUint); >+ }; >+ >+ compilerContext[@"checkHalf"] = ^void(TestFamily* program, TestDescription* testDesc, NSNumber* expectation) { >+ addTest(program, testDesc, expectation, WHLSLTypeHalf); >+ }; >+ >+ compilerContext[@"checkFloat"] = ^void(TestFamily* program, TestDescription* testDesc, NSNumber* expectation) { >+ addTest(program, testDesc, expectation, WHLSLTypeFloat); >+ }; >+ >+ compilerContext[@"checkBool"] = ^void(TestFamily* program, TestDescription* testDesc, NSNumber* expectation) { >+ addTest(program, testDesc, expectation, WHLSLTypeBool); >+ }; >+ >+ compilerContext[@"checkUchar"] = ^void(TestFamily* program, TestDescription* testDesc, NSNumber* expectation) { >+ addTest(program, testDesc, expectation, WHLSLTypeUchar); >+ }; >+ >+ // Deliberately not included >+ compilerContext[@"checkEnum"] = ^void(TestFamily* program, TestDescription* testDesc, NSNumber* expectation) {}; >+ compilerContext[@"checkFloat4"] = ^void(TestFamily* program, TestDescription* testDesc, NSNumber* expectation) {}; >+ compilerContext[@"checkFail"] = ^void(id callback, id errorCallback) {}; >+ compilerContext[@"checkLexerToken"] = ^void(NSString* token, NSNumber* id, NSString* name, NSString* tokenText) {}; >+ >+ JSValue* tests = [compilerContext evaluateScript:@"tests"]; >+ >+ NSArray<NSString*>* testNames = [tests.toDictionary.allKeys sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)]; >+ >+ for (currentTestName in testNames) { >+ JSValue* func = [tests objectForKeyedSubscript:currentTestName]; >+ [func callWithArguments:@[]]; >+ } >+ >+ return testFamilies; >+} >+ >+@end >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/TestFamilyRunner.h b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/TestFamilyRunner.h >new file mode 100644 >index 0000000000000000000000000000000000000000..1589e3e8cd081018fa1f7dc3caab67812830f92e >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/TestFamilyRunner.h >@@ -0,0 +1,26 @@ >+// >+// TestFamilyRunner.h >+// WHLSL Tests >+// >+// Created by Thomas Denney on 8/3/18. >+// Copyright © 2018 Apple, Inc. All rights reserved. >+// >+ >+#import <Foundation/Foundation.h> >+#import "TestFamily.h" >+ >+NS_ASSUME_NONNULL_BEGIN >+ >+@interface TestFamilyRunner : NSObject >+ >+- (instancetype)initWithTestFamily:(TestFamily*)testFamily; >+ >+@property (readonly) TestFamily* testFamily; >+ >+- (BOOL)executeAllTests; >+ >++ (NSUInteger)executionCount; >+ >+@end >+ >+NS_ASSUME_NONNULL_END >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/TestFamilyRunner.m b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/TestFamilyRunner.m >new file mode 100644 >index 0000000000000000000000000000000000000000..527bf761acf9ff2a1a11c75502882b28908197c4 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/TestFamilyRunner.m >@@ -0,0 +1,175 @@ >+// >+// TestFamilyRunner.m >+// WHLSL Tests >+// >+// Created by Thomas Denney on 8/3/18. >+// Copyright © 2018 Apple, Inc. All rights reserved. >+// >+ >+#import "TestFamilyRunner.h" >+ >+#import "Compiler.h" >+#import "OffscreenRenderer.h" >+ >+static NSUInteger executionCount = 0; >+ >+@interface TestFamilyRunner () >+ >+@property TestFamily* testFamily; >+ >+@end >+ >+@implementation TestFamilyRunner >+ >+- (instancetype)initWithTestFamily:(TestFamily *)testFamily >+{ >+ if (self = [super init]) { >+ self.testFamily = testFamily; >+ } >+ return self; >+} >+ >++ (id<MTLDevice>)defaultTestingDevice >+{ >+ NSArray<id<MTLDevice>>* allDevices = MTLCopyAllDevices(); >+ for (id<MTLDevice> device in allDevices) { >+ if (device.isLowPower) >+ return device; >+ } >+ return MTLCreateSystemDefaultDevice(); >+} >+ >++ (OffscreenRenderer*)intOffscreenRenderer >+{ >+ static OffscreenRenderer* offscreenRenderer; >+ static dispatch_once_t onceToken; >+ dispatch_once(&onceToken, ^{ >+ offscreenRenderer = [[OffscreenRenderer alloc] initWithDevice:[TestFamilyRunner defaultTestingDevice]]; >+ [offscreenRenderer setOutputPixelFormat:MTLPixelFormatR32Sint]; >+ [offscreenRenderer setTargetWidth:1 setTargetHeight:1]; >+ }); >+ return offscreenRenderer; >+} >+ >++ (OffscreenRenderer*)uintOffscreenRenderer >+{ >+ static OffscreenRenderer* offscreenRenderer; >+ static dispatch_once_t onceToken; >+ dispatch_once(&onceToken, ^{ >+ offscreenRenderer = [[OffscreenRenderer alloc] initWithDevice:[TestFamilyRunner defaultTestingDevice]]; >+ [offscreenRenderer setOutputPixelFormat:MTLPixelFormatR32Uint]; >+ [offscreenRenderer setTargetWidth:1 setTargetHeight:1]; >+ }); >+ return offscreenRenderer; >+} >+ >++ (OffscreenRenderer*)floatOffscreenRenderer >+{ >+ static OffscreenRenderer* offscreenRenderer; >+ static dispatch_once_t onceToken; >+ dispatch_once(&onceToken, ^{ >+ offscreenRenderer = [[OffscreenRenderer alloc] initWithDevice:[TestFamilyRunner defaultTestingDevice]]; >+ [offscreenRenderer setOutputPixelFormat:MTLPixelFormatR32Float]; >+ [offscreenRenderer setTargetWidth:1 setTargetHeight:1]; >+ }); >+ return offscreenRenderer; >+} >+ >++ (Compiler*)compiler >+{ >+ static Compiler* compiler; >+ static dispatch_once_t onceToken; >+ dispatch_once(&onceToken, ^{ >+ compiler = [Compiler new]; >+ }); >+ return compiler; >+} >+ >+- (BOOL)executeAllTests >+{ >+ if (!self.testFamily.totalTestCaseCount) >+ return YES; >+ >+ NSString* whlslSource = self.testFamily.whlslSource; >+ NSError* whlslCompileError = nil; >+ CompileResult* result = [[TestFamilyRunner compiler] compileWhlslToMetal:whlslSource error:&whlslCompileError]; >+ if (!result) { >+ NSLog(@"[%@]: WHLSL Compile Error: %@", self.testFamily.name, whlslCompileError.localizedDescription); >+ return NO; >+ } >+ >+ NSLog(@"Compiled WHLSL"); >+ >+ NSMutableString* mslString = [NSMutableString new]; >+ [mslString appendString:result.source]; >+ [mslString appendString:@"\n"]; >+ [mslString appendString:[TestFamily sharedMetalSource]]; >+ [mslString appendString:[self.testFamily metalSourceForCallingFunctionsWithCompiledNames:result.functionNameMap]]; >+ >+ id<MTLDevice> device = MTLCreateSystemDefaultDevice(); >+ NSError *error = nil; >+ id<MTLLibrary> library = [device newLibraryWithSource:mslString options:nil error:&error]; >+ if (!library) { >+ NSLog(@"[Library]: %@", error.localizedDescription); >+ return NO; >+ } >+ >+ if (error) >+ NSLog(@"[Library compiled with warnings]: %@", error.localizedDescription); >+ NSLog(@"Compiled metal"); >+ >+ BOOL status = YES; >+ >+ NSString *vertexShaderName = @"vertexShader"; >+ >+ OffscreenRenderer *intRenderer = [TestFamilyRunner intOffscreenRenderer]; >+ for (TestDescription* test in self.testFamily.integerTests) { >+ [intRenderer setLibrary:library vertexShaderName:vertexShaderName fragmentShaderName:test.fragmentShaderName]; >+ [intRenderer draw]; >+ >+ int result = intRenderer.intValue; >+ if (result != test.expectation.intValue) { >+ NSLog(@"%@ = %d, should be %d", test, result, test.expectation.intValue); >+ status = NO; >+ } else >+ NSLog(@"%@ = %d", test, result); >+ executionCount++; >+ } >+ >+ OffscreenRenderer *uintRenderer = [TestFamilyRunner uintOffscreenRenderer]; >+ for (TestDescription* test in self.testFamily.unsignedIntegerTests) { >+ [uintRenderer setLibrary:library vertexShaderName:vertexShaderName fragmentShaderName:test.fragmentShaderName]; >+ [uintRenderer draw]; >+ >+ unsigned int result = uintRenderer.uintValue; >+ if (result != test.expectation.unsignedIntValue) { >+ NSLog(@"%@ = %u, should be %u", test, result, test.expectation.unsignedIntValue); >+ status = NO; >+ } else >+ NSLog(@"%@ = %u", test, result); >+ executionCount++; >+ } >+ >+ OffscreenRenderer *floatRenderer = [TestFamilyRunner floatOffscreenRenderer]; >+ for (TestDescription* test in self.testFamily.floatTests) { >+ [floatRenderer setLibrary:library vertexShaderName:vertexShaderName fragmentShaderName:test.fragmentShaderName]; >+ [floatRenderer draw]; >+ >+ float result = floatRenderer.floatValue; >+ if (result != test.expectation.floatValue) { >+ NSLog(@"%@ = %f, should be %f", test, result, test.expectation.floatValue); >+ status = NO; >+ } else >+ NSLog(@"%@ = %f", test, result); >+ executionCount++; >+ } >+ >+ return status; >+} >+ >++ (NSUInteger)executionCount >+{ >+ return executionCount; >+} >+ >+@end >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/ViewController.h b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/ViewController.h >new file mode 100644 >index 0000000000000000000000000000000000000000..3bbf229155c82229ca0d93a508e70845eb52d7f6 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/ViewController.h >@@ -0,0 +1,24 @@ >+// >+// ViewController.h >+// WHLSL Toy >+// >+// Created by Thomas Denney on 7/10/18. >+// Copyright © 2018 Apple, Inc. All rights reserved. >+// >+ >+#import <Cocoa/Cocoa.h> >+#import <MetalKit/MetalKit.h> >+#import "CustomMetalView.h" >+ >+#import "Compiler.h" >+ >+@interface ViewController : NSViewController<NSGestureRecognizerDelegate, CustomMetalViewDelegate> >+ >+@property (unsafe_unretained) IBOutlet NSTextView *whlslTextView; >+@property (unsafe_unretained) IBOutlet NSTextView *mslTextView; >+@property (weak) IBOutlet CustomMetalView *metalView; >+ >+@property Compiler *compiler; >+ >+@end >+ >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/ViewController.m b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/ViewController.m >new file mode 100644 >index 0000000000000000000000000000000000000000..12b85648eb61e98cb6c4abdaa194a644d9146024 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/ViewController.m >@@ -0,0 +1,209 @@ >+// >+// ViewController.m >+// WHLSL Toy >+// >+// Created by Thomas Denney on 7/10/18. >+// Copyright © 2018 Apple, Inc. All rights reserved. >+// >+ >+#import "ViewController.h" >+#import "OnscreenRenderer.h" >+ >+@interface ViewController () >+ >+@property OnscreenRenderer *renderer; >+@property NSMagnificationGestureRecognizer *magnifyGesture; >+@property NSRotationGestureRecognizer *rotationGesture; >+@property (weak) IBOutlet NSTextField *debugLabel; >+@property (weak) IBOutlet NSScrollView *whlslViewContainer; >+@property (weak) IBOutlet NSScrollView *mslViewContainer; >+@property id<MTLLibrary> library; >+ >+@end >+ >+@implementation ViewController >+ >+- (void)viewDidLoad { >+ [super viewDidLoad]; >+ >+ [self loadFile:@"Default"]; >+ >+ self.compiler = [[Compiler alloc] init]; >+ >+ self.metalView.device = MTLCreateSystemDefaultDevice(); >+ self.renderer = [[OnscreenRenderer alloc] initWithView:self.metalView device:self.metalView.device]; >+ >+ self.magnifyGesture = [[NSMagnificationGestureRecognizer alloc] initWithTarget:self action:@selector(zoom:)]; >+ self.magnifyGesture.delegate = self; >+ [self.metalView addGestureRecognizer:self.magnifyGesture]; >+ >+ self.rotationGesture = [[NSRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotate:)]; >+ self.rotationGesture.delegate = self; >+ [self.metalView addGestureRecognizer:self.rotationGesture]; >+ >+ self.metalView.scrollDelegate = self; >+ >+ [self viewDidLayout]; >+ >+ self.library = [self.renderer.device newDefaultLibraryWithBundle:[NSBundle mainBundle] error:nil]; >+} >+ >+- (BOOL)gestureRecognizer:(NSGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(nonnull NSGestureRecognizer *)otherGestureRecognizer >+{ >+ return YES; >+} >+ >+- (void)viewDidLayout >+{ >+ [super viewDidLayout]; >+ >+ CGFloat width = CGRectGetWidth(self.view.frame); >+ CGFloat boxWidth = (width - 20 * 2 - 10 * 2) / 3; >+ CGFloat height = CGRectGetHeight(self.view.frame); >+ CGFloat boxHeight = height - 60 - 20; >+ >+ self.whlslViewContainer.frame = CGRectMake(20, 60, boxWidth, boxHeight); >+ self.mslViewContainer.frame = CGRectMake(20 + boxWidth + 10, 60, boxWidth, boxHeight); >+ self.metalView.frame = CGRectMake(20 + boxWidth + 10 + boxWidth + 10, 60, boxWidth, boxHeight); >+ >+ float ratio = boxHeight / (boxWidth / 3); >+ // NOTE: simd_matrix takes columns, not rows! >+ self.renderer.transformMatrix = simd_matrix(simd_make_float3(3, 0, 0), >+ simd_make_float3(0, ratio, 0), >+ simd_make_float3(-2.2, -ratio / 2, 1)); >+ >+ self.debugLabel.stringValue = [NSString stringWithFormat:@"Width = %f, height = %f", boxWidth, boxHeight]; >+} >+ >+- (IBAction)resetViewport:(id)sender >+{ >+ [self viewDidLayout]; >+ [self.metalView setNeedsDisplay:YES]; >+} >+ >+- (IBAction)loadDefault:(id)sender >+{ >+ [self loadFile:@"Default"]; >+} >+ >+- (IBAction)loadMandelbrot:(id)sender >+{ >+ [self loadFile:@"Mandelbrot"]; >+} >+ >+- (IBAction)loadJulia:(id)sender >+{ >+ [self loadFile:@"Julia"]; >+} >+ >+- (void)loadFile:(NSString*)name >+{ >+ NSString* defaultFilePath = [[NSBundle mainBundle] pathForResource:name ofType:@"whlsl"]; >+ NSString* defaultContents = [NSString stringWithContentsOfFile:defaultFilePath encoding:NSUTF8StringEncoding error:nil]; >+ >+ // Do any additional setup after loading the view. >+ self.whlslTextView.string = defaultContents; >+ self.mslTextView.string = @""; >+ self.metalView.hidden = YES; >+} >+ >+- (IBAction)compileClicked:(id)sender { >+ NSError *error = nil; >+ CompileResult *output = [self.compiler compileWhlslToMetal:self.whlslTextView.string error:&error]; >+ if (error) >+ self.mslTextView.string = error.localizedDescription; >+ else { >+ self.metalView.hidden = NO; >+ self.mslTextView.string = output.source; >+ NSString *vertexShaderName = output.functionNameMap[@"vertexShader"]; >+ NSString *fragmentShaderName = output.functionNameMap[@"fragmentShader"]; >+ [self viewDidLayout]; >+ [self.renderer setShaderSource:output.source vertexShaderName:vertexShaderName fragmentShaderName:fragmentShaderName]; >+ [self.metalView setNeedsDisplay:YES]; >+ } >+ self.mslTextView.font = [NSFont fontWithName:@"Menlo" size:12]; >+} >+ >+- (IBAction)loadNativeFlatColor:(id)sender >+{ >+ [self loadNativeFlatColor:@"flatColor"]; >+} >+ >+- (IBAction)loadNativeMandelbrot:(id)sender >+{ >+ [self loadNativeMetalShaderWithName:@"mandelbrot"]; >+} >+ >+- (IBAction)loadNativeJulia:(id)sender >+{ >+ [self loadNativeMetalShaderWithName:@"julia"]; >+} >+ >+- (void)loadNativeMetalShaderWithName:(NSString*)name >+{ >+ NSString* vertexShaderName = [name stringByAppendingString:@"VertexShader"]; >+ NSString* fragmentShaderName = [name stringByAppendingString:@"FragmentShader"]; >+ [self viewDidLayout]; >+ [self.renderer setLibrary:self.library vertexShaderName:vertexShaderName fragmentShaderName:fragmentShaderName pixelFormat:self.metalView.colorPixelFormat]; >+ [self.metalView setNeedsDisplay:YES]; >+} >+ >+- (IBAction)zoom:(id)sender >+{ >+ float factor = 1.0f / (1 + self.magnifyGesture.magnification); >+ NSPoint location = [self.magnifyGesture locationInView:self.metalView]; >+ float normalizedX = location.x / CGRectGetWidth(self.metalView.frame); >+ float normalizedY = location.y / CGRectGetHeight(self.metalView.frame); >+ simd_float3 normalized = simd_make_float3(normalizedX, normalizedY, 1); >+ normalized = matrix_multiply(self.renderer.transformMatrix, normalized); >+ simd_float3x3 initTransform = simd_matrix(simd_make_float3(1, 0, 0), >+ simd_make_float3(0, 1, 0), >+ simd_make_float3(-normalized.x, -normalized.y, 1)); >+ simd_float3x3 scaleMatrix = simd_matrix(simd_make_float3(factor, 0.f, 0.f), >+ simd_make_float3(0.f, factor, 0.f), >+ simd_make_float3(0.f, 0.f, 1)); >+ simd_float3x3 backTransform = simd_matrix(simd_make_float3(1, 0, 0), >+ simd_make_float3(0, 1, 0), >+ simd_make_float3(normalized.x, normalized.y, 1)); >+ self.renderer.transformMatrix = matrix_multiply(matrix_multiply(backTransform, matrix_multiply(scaleMatrix, initTransform)), self.renderer.transformMatrix); >+ self.magnifyGesture.magnification = 0; >+ [self.metalView setNeedsDisplay:YES]; >+} >+ >+- (IBAction)rotate:(id)sender >+{ >+ float angle = -self.rotationGesture.rotation; >+ NSPoint location = [self.rotationGesture locationInView:self.metalView]; >+ float normalizedX = location.x / CGRectGetWidth(self.metalView.frame); >+ float normalizedY = location.y / CGRectGetHeight(self.metalView.frame); >+ simd_float3 normalized = simd_make_float3(normalizedX, normalizedY, 1); >+ normalized = matrix_multiply(self.renderer.transformMatrix, normalized); >+ // NSLog(@"%f %f", normalized.x, normalized.y); >+ simd_float3x3 initTransform = simd_matrix(simd_make_float3(1, 0, 0), >+ simd_make_float3(0, 1, 0), >+ simd_make_float3(-normalized.x, -normalized.y, 1)); >+ simd_float3x3 rotationMatrix = simd_matrix(simd_make_float3(cos(angle), sin(angle), 0.f), >+ simd_make_float3(-sin(angle), cos(angle), 0.f), >+ simd_make_float3(0.f, 0.f, 1)); >+ simd_float3x3 backTransform = simd_matrix(simd_make_float3(1, 0, 0), >+ simd_make_float3(0, 1, 0), >+ simd_make_float3(normalized.x, normalized.y, 1)); >+ self.renderer.transformMatrix = matrix_multiply(matrix_multiply(backTransform, matrix_multiply(rotationMatrix, initTransform)), self.renderer.transformMatrix); >+ self.rotationGesture.rotation = 0; >+ [self.metalView setNeedsDisplay:YES]; >+} >+ >+- (void)customMetalView:(CustomMetalView *)metalView scrolledDeltaX:(CGFloat)deltaX deltaY:(CGFloat)deltaY >+{ >+ float width = self.metalView.bounds.size.width; >+ float height = self.metalView.bounds.size.height; >+ float scrollVelocity = 6; >+ float x = -deltaX / width * scrollVelocity; >+ float y = deltaY / height * scrollVelocity; >+ simd_float3x3 m = simd_matrix(simd_make_float3(1, 0, 0), >+ simd_make_float3(0, 1, 0), >+ simd_make_float3(x, y, 1)); >+ self.renderer.transformMatrix = matrix_multiply(self.renderer.transformMatrix, m); >+} >+ >+@end >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/WHLSL.entitlements b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/WHLSL.entitlements >new file mode 100644 >index 0000000000000000000000000000000000000000..f2ef3ae0265b40c475e8ef90e3a311c31786c594 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/WHLSL.entitlements >@@ -0,0 +1,10 @@ >+<?xml version="1.0" encoding="UTF-8"?> >+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> >+<plist version="1.0"> >+<dict> >+ <key>com.apple.security.app-sandbox</key> >+ <true/> >+ <key>com.apple.security.files.user-selected.read-only</key> >+ <true/> >+</dict> >+</plist> >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/_SharedMetal.txt b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/_SharedMetal.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..bd64e41de42ef5911a4ddc21797a54d6af07d3ed >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/_SharedMetal.txt >@@ -0,0 +1,12 @@ >+struct VertexInput { float2 position [[attribute(0)]]; float2 uv [[attribute(1)]]; }; >+struct VertexOutput { float4 position [[position]]; }; >+struct FragmentOutputFloat { float result; }; >+struct FragmentOutputInt { int result; }; >+struct FragmentOutputUint { uint result; }; >+ >+vertex VertexOutput vertexShader(VertexInput vertexInput [[stage_in]]) >+{ >+ VertexOutput result; >+ result.position = float4(vertexInput.position, 0., 1.); >+ return result; >+} >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/main.m b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/main.m >new file mode 100644 >index 0000000000000000000000000000000000000000..22bf7ee48b4d29565d0b7256054a624fc5f47994 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/Core/main.m >@@ -0,0 +1,14 @@ >+// >+// main.m >+// WHLSL Toy >+// >+// Created by Thomas Denney on 7/10/18. >+// Copyright © 2018 Apple, Inc. All rights reserved. >+// >+ >+#import <Cocoa/Cocoa.h> >+ >+int main(int argc, const char * argv[]) >+{ >+ return NSApplicationMain(argc, argv); >+} >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/WHLSL Tests.xcodeproj/project.pbxproj b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/WHLSL Tests.xcodeproj/project.pbxproj >new file mode 100644 >index 0000000000000000000000000000000000000000..6ba8460019881a8e32d7b8f39490be11125d76d4 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/WHLSL Tests.xcodeproj/project.pbxproj >@@ -0,0 +1,1306 @@ >+// !$*UTF8*$! >+{ >+ archiveVersion = 1; >+ classes = { >+ }; >+ objectVersion = 50; >+ objects = { >+ >+/* Begin PBXBuildFile section */ >+ E906B04621139B7700AD1C5E /* Julia.whlsl in Resources */ = {isa = PBXBuildFile; fileRef = E906B04521139B7700AD1C5E /* Julia.whlsl */; }; >+ E921D6362138C02600775099 /* OperatorAnderIndexer.js in Resources */ = {isa = PBXBuildFile; fileRef = E921D6322138C02600775099 /* OperatorAnderIndexer.js */; }; >+ E921D6372138C02600775099 /* MatrixType.js in Resources */ = {isa = PBXBuildFile; fileRef = E921D6332138C02600775099 /* MatrixType.js */; }; >+ E921D6382138C02600775099 /* BuiltinMatrixGetter.js in Resources */ = {isa = PBXBuildFile; fileRef = E921D6342138C02600775099 /* BuiltinMatrixGetter.js */; }; >+ E921D6392138C02600775099 /* BuiltinMatrixSetter.js in Resources */ = {isa = PBXBuildFile; fileRef = E921D6352138C02600775099 /* BuiltinMatrixSetter.js */; }; >+ E92D108A20F56F0600D776B2 /* Compiler.m in Sources */ = {isa = PBXBuildFile; fileRef = E92D108920F56F0600D776B2 /* Compiler.m */; }; >+ E92D108D20F56F4500D776B2 /* MetalKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E92D108C20F56F4500D776B2 /* MetalKit.framework */; }; >+ E92D108F20F56F4F00D776B2 /* Metal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E92D108E20F56F4F00D776B2 /* Metal.framework */; }; >+ E92D109120F56F5700D776B2 /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E92D109020F56F5700D776B2 /* JavaScriptCore.framework */; }; >+ E92D109320F5734900D776B2 /* Default.whlsl in Resources */ = {isa = PBXBuildFile; fileRef = E92D109220F5734900D776B2 /* Default.whlsl */; }; >+ E92D10AF20F57C9F00D776B2 /* OnscreenRenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = E92D10AE20F57C9F00D776B2 /* OnscreenRenderer.m */; }; >+ E92D111520F6FFB600D776B2 /* Renderer.m in Sources */ = {isa = PBXBuildFile; fileRef = E92D111420F6FFB600D776B2 /* Renderer.m */; }; >+ E92D111620F7060E00D776B2 /* AddressSpace.js in Resources */ = {isa = PBXBuildFile; fileRef = E95569BA20F56CD600F5CF34 /* AddressSpace.js */; }; >+ E92D111720F7060E00D776B2 /* All.js in Resources */ = {isa = PBXBuildFile; fileRef = E95569BC20F56CD700F5CF34 /* All.js */; }; >+ E92D111820F7060E00D776B2 /* AnonymousVariable.js in Resources */ = {isa = PBXBuildFile; fileRef = E95569BD20F56CD700F5CF34 /* AnonymousVariable.js */; }; >+ E92D111920F7060E00D776B2 /* ArrayRefType.js in Resources */ = {isa = PBXBuildFile; fileRef = E95569B520F56CD600F5CF34 /* ArrayRefType.js */; }; >+ E92D111A20F7060E00D776B2 /* ArrayType.js in Resources */ = {isa = PBXBuildFile; fileRef = E95569B420F56CD600F5CF34 /* ArrayType.js */; }; >+ E92D111B20F7060E00D776B2 /* Assignment.js in Resources */ = {isa = PBXBuildFile; fileRef = E95569B920F56CD600F5CF34 /* Assignment.js */; }; >+ E92D111C20F7060E00D776B2 /* AutoWrapper.js in Resources */ = {isa = PBXBuildFile; fileRef = E95569BE20F56CD700F5CF34 /* AutoWrapper.js */; }; >+ E92D111D20F7060E00D776B2 /* Block.js in Resources */ = {isa = PBXBuildFile; fileRef = E94C06FC20F56CA300672992 /* Block.js */; }; >+ E92D111E20F7060E00D776B2 /* BoolLiteral.js in Resources */ = {isa = PBXBuildFile; fileRef = E95569B120F56CD600F5CF34 /* BoolLiteral.js */; }; >+ E92D111F20F7060E00D776B2 /* Break.js in Resources */ = {isa = PBXBuildFile; fileRef = E95569B020F56CD600F5CF34 /* Break.js */; }; >+ E92D112020F7060E00D776B2 /* CallExpression.js in Resources */ = {isa = PBXBuildFile; fileRef = E95569BF20F56CD700F5CF34 /* CallExpression.js */; }; >+ E92D112120F7060E00D776B2 /* CallFunction.js in Resources */ = {isa = PBXBuildFile; fileRef = E95569C020F56CD700F5CF34 /* CallFunction.js */; }; >+ E92D112220F7060E00D776B2 /* Check.js in Resources */ = {isa = PBXBuildFile; fileRef = E95569B820F56CD600F5CF34 /* Check.js */; }; >+ E92D112320F7060E00D776B2 /* Checker.js in Resources */ = {isa = PBXBuildFile; fileRef = E95569C120F56CD700F5CF34 /* Checker.js */; }; >+ E92D112420F7060E00D776B2 /* CheckLiteralTypes.js in Resources */ = {isa = PBXBuildFile; fileRef = E95569B620F56CD600F5CF34 /* CheckLiteralTypes.js */; }; >+ E92D112520F7060E00D776B2 /* CheckLoops.js in Resources */ = {isa = PBXBuildFile; fileRef = E95569B320F56CD600F5CF34 /* CheckLoops.js */; }; >+ E92D112620F7060E00D776B2 /* CheckRecursion.js in Resources */ = {isa = PBXBuildFile; fileRef = E94C06FA20F56CA300672992 /* CheckRecursion.js */; }; >+ E92D112720F7060E00D776B2 /* CheckRecursiveTypes.js in Resources */ = {isa = PBXBuildFile; fileRef = E95569BB20F56CD600F5CF34 /* CheckRecursiveTypes.js */; }; >+ E92D112820F7060E00D776B2 /* CheckReturns.js in Resources */ = {isa = PBXBuildFile; fileRef = E95569B220F56CD600F5CF34 /* CheckReturns.js */; }; >+ E92D112920F7060E00D776B2 /* CheckUnreachableCode.js in Resources */ = {isa = PBXBuildFile; fileRef = E95569B720F56CD600F5CF34 /* CheckUnreachableCode.js */; }; >+ E92D112A20F7060E00D776B2 /* CheckWrapped.js in Resources */ = {isa = PBXBuildFile; fileRef = E95569D420F56CED00F5CF34 /* CheckWrapped.js */; }; >+ E92D112B20F7060E00D776B2 /* CloneProgram.js in Resources */ = {isa = PBXBuildFile; fileRef = E95569DB20F56CEE00F5CF34 /* CloneProgram.js */; }; >+ E92D112C20F7060E00D776B2 /* CommaExpression.js in Resources */ = {isa = PBXBuildFile; fileRef = E95569DC20F56CEE00F5CF34 /* CommaExpression.js */; }; >+ E92D112E20F7060E00D776B2 /* ConstexprFolder.js in Resources */ = {isa = PBXBuildFile; fileRef = E95569D520F56CED00F5CF34 /* ConstexprFolder.js */; }; >+ E92D113020F7060E00D776B2 /* Continue.js in Resources */ = {isa = PBXBuildFile; fileRef = E95569D720F56CED00F5CF34 /* Continue.js */; }; >+ E92D113120F7060E00D776B2 /* ConvertPtrToArrayRefExpression.js in Resources */ = {isa = PBXBuildFile; fileRef = E95569D920F56CED00F5CF34 /* ConvertPtrToArrayRefExpression.js */; }; >+ E92D113220F7060E00D776B2 /* CreateLiteral.js in Resources */ = {isa = PBXBuildFile; fileRef = E95569D820F56CED00F5CF34 /* CreateLiteral.js */; }; >+ E92D113320F7060E00D776B2 /* CreateLiteralType.js in Resources */ = {isa = PBXBuildFile; fileRef = E95569D620F56CED00F5CF34 /* CreateLiteralType.js */; }; >+ E92D113420F7060E00D776B2 /* DereferenceExpression.js in Resources */ = {isa = PBXBuildFile; fileRef = E94C06F920F56CA300672992 /* DereferenceExpression.js */; }; >+ E92D113520F7060E00D776B2 /* DotExpression.js in Resources */ = {isa = PBXBuildFile; fileRef = E9AD074B20F56D5B007F2466 /* DotExpression.js */; }; >+ E92D113820F7060E00D776B2 /* DoWhileLoop.js in Resources */ = {isa = PBXBuildFile; fileRef = E9AD074620F56D5A007F2466 /* DoWhileLoop.js */; }; >+ E92D113920F7060E00D776B2 /* EArrayRef.js in Resources */ = {isa = PBXBuildFile; fileRef = E9AD074920F56D5A007F2466 /* EArrayRef.js */; }; >+ E92D113A20F7060E00D776B2 /* EBuffer.js in Resources */ = {isa = PBXBuildFile; fileRef = E9AD074820F56D5A007F2466 /* EBuffer.js */; }; >+ E92D113B20F7060E00D776B2 /* EBufferBuilder.js in Resources */ = {isa = PBXBuildFile; fileRef = E9AD074A20F56D5B007F2466 /* EBufferBuilder.js */; }; >+ E92D113C20F7060E00D776B2 /* EnumLiteral.js in Resources */ = {isa = PBXBuildFile; fileRef = E94C06FD20F56CA300672992 /* EnumLiteral.js */; }; >+ E92D113D20F7060E00D776B2 /* EnumMember.js in Resources */ = {isa = PBXBuildFile; fileRef = E9AD075520F56D69007F2466 /* EnumMember.js */; }; >+ E92D113E20F7060E00D776B2 /* EnumType.js in Resources */ = {isa = PBXBuildFile; fileRef = E9AD075A20F56D69007F2466 /* EnumType.js */; }; >+ E92D113F20F7060E00D776B2 /* EPtr.js in Resources */ = {isa = PBXBuildFile; fileRef = E95569E720F56D0500F5CF34 /* EPtr.js */; }; >+ E92D114020F7060E00D776B2 /* EvaluationCommon.js in Resources */ = {isa = PBXBuildFile; fileRef = E9AD075320F56D69007F2466 /* EvaluationCommon.js */; }; >+ E92D114120F7060E00D776B2 /* Evaluator.js in Resources */ = {isa = PBXBuildFile; fileRef = E9AD075720F56D69007F2466 /* Evaluator.js */; }; >+ E92D114220F7060E00D776B2 /* Expression.js in Resources */ = {isa = PBXBuildFile; fileRef = E9AD075420F56D69007F2466 /* Expression.js */; }; >+ E92D114320F7060E00D776B2 /* ExpressionFinder.js in Resources */ = {isa = PBXBuildFile; fileRef = E9AD075920F56D69007F2466 /* ExpressionFinder.js */; }; >+ E92D114420F7060E00D776B2 /* ExternalOrigin.js in Resources */ = {isa = PBXBuildFile; fileRef = E9AD075B20F56D69007F2466 /* ExternalOrigin.js */; }; >+ E92D114520F7060E00D776B2 /* Field.js in Resources */ = {isa = PBXBuildFile; fileRef = E9FCEB5B20F56D93009B3629 /* Field.js */; }; >+ E92D114620F7060E00D776B2 /* FindHighZombies.js in Resources */ = {isa = PBXBuildFile; fileRef = E9AD075820F56D69007F2466 /* FindHighZombies.js */; }; >+ E92D114720F7060E00D776B2 /* FlattenedStructOffsetGatherer.js in Resources */ = {isa = PBXBuildFile; fileRef = E9AD075620F56D69007F2466 /* FlattenedStructOffsetGatherer.js */; }; >+ E92D114920F7060E00D776B2 /* FloatLiteral.js in Resources */ = {isa = PBXBuildFile; fileRef = E9AD075C20F56D69007F2466 /* FloatLiteral.js */; }; >+ E92D114A20F7060E00D776B2 /* FloatLiteralType.js in Resources */ = {isa = PBXBuildFile; fileRef = E95569EA20F56D0500F5CF34 /* FloatLiteralType.js */; }; >+ E92D114B20F7060E00D776B2 /* FoldConstexprs.js in Resources */ = {isa = PBXBuildFile; fileRef = E95569EB20F56D0500F5CF34 /* FoldConstexprs.js */; }; >+ E92D114C20F7060E00D776B2 /* ForLoop.js in Resources */ = {isa = PBXBuildFile; fileRef = E9FCEB5A20F56D93009B3629 /* ForLoop.js */; }; >+ E92D114D20F7060E00D776B2 /* Func.js in Resources */ = {isa = PBXBuildFile; fileRef = E9FCEB5520F56D92009B3629 /* Func.js */; }; >+ E92D114E20F7060E00D776B2 /* FuncDef.js in Resources */ = {isa = PBXBuildFile; fileRef = E95569E820F56D0500F5CF34 /* FuncDef.js */; }; >+ E92D115020F7060E00D776B2 /* FuncParameter.js in Resources */ = {isa = PBXBuildFile; fileRef = E95569E920F56D0500F5CF34 /* FuncParameter.js */; }; >+ E92D115120F7060E00D776B2 /* FunctionLikeBlock.js in Resources */ = {isa = PBXBuildFile; fileRef = E95569E620F56D0500F5CF34 /* FunctionLikeBlock.js */; }; >+ E92D115220F7060E00D776B2 /* HighZombieFinder.js in Resources */ = {isa = PBXBuildFile; fileRef = E94C06FB20F56CA300672992 /* HighZombieFinder.js */; }; >+ E92D115320F7060E00D776B2 /* IdentityExpression.js in Resources */ = {isa = PBXBuildFile; fileRef = E9FCEB5820F56D93009B3629 /* IdentityExpression.js */; }; >+ E92D115420F7060E00D776B2 /* IfStatement.js in Resources */ = {isa = PBXBuildFile; fileRef = E9FCEB5720F56D93009B3629 /* IfStatement.js */; }; >+ E92D115520F7060E00D776B2 /* IndexExpression.js in Resources */ = {isa = PBXBuildFile; fileRef = E9FCEB6320F56DA4009B3629 /* IndexExpression.js */; }; >+ E92D115620F7060E00D776B2 /* InferTypesForCall.js in Resources */ = {isa = PBXBuildFile; fileRef = E9FCEB6520F56DA5009B3629 /* InferTypesForCall.js */; }; >+ E92D115720F7060E00D776B2 /* Inline.js in Resources */ = {isa = PBXBuildFile; fileRef = E9FCEB6620F56DA5009B3629 /* Inline.js */; }; >+ E92D115820F7060E00D776B2 /* Inliner.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D0FE820F56DDD00D776B2 /* Inliner.js */; }; >+ E92D115A20F7060E00D776B2 /* IntLiteral.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D0FE420F56DDD00D776B2 /* IntLiteral.js */; }; >+ E92D115B20F7060E00D776B2 /* IntLiteralType.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D0FE520F56DDD00D776B2 /* IntLiteralType.js */; }; >+ E92D115C20F7060E00D776B2 /* Intrinsics.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D0FE720F56DDD00D776B2 /* Intrinsics.js */; }; >+ E92D115D20F7060E00D776B2 /* LateChecker.js in Resources */ = {isa = PBXBuildFile; fileRef = E9FCEB6420F56DA5009B3629 /* LateChecker.js */; }; >+ E92D115E20F7060E00D776B2 /* Lexer.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D0FF120F56DEC00D776B2 /* Lexer.js */; }; >+ E92D115F20F7060E00D776B2 /* LexerToken.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D0FF020F56DEB00D776B2 /* LexerToken.js */; }; >+ E92D116020F7060E00D776B2 /* LiteralTypeChecker.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D0FF220F56DEC00D776B2 /* LiteralTypeChecker.js */; }; >+ E92D116120F7060E00D776B2 /* LogicalExpression.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D0FEE20F56DEB00D776B2 /* LogicalExpression.js */; }; >+ E92D116220F7060E00D776B2 /* LogicalNot.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D0FEF20F56DEB00D776B2 /* LogicalNot.js */; }; >+ E92D116320F7060E00D776B2 /* LoopChecker.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D0FFB20F56DFB00D776B2 /* LoopChecker.js */; }; >+ E92D116420F7060E00D776B2 /* MakeArrayRefExpression.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D0FFC20F56DFB00D776B2 /* MakeArrayRefExpression.js */; }; >+ E92D116520F7060E00D776B2 /* MakePtrExpression.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D0FF920F56DFA00D776B2 /* MakePtrExpression.js */; }; >+ E92D116620F7060E00D776B2 /* NameContext.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D0FF820F56DFA00D776B2 /* NameContext.js */; }; >+ E92D116720F7060E00D776B2 /* NameFinder.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D0FFA20F56DFB00D776B2 /* NameFinder.js */; }; >+ E92D116820F7060E00D776B2 /* NameResolver.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D100320F56E0900D776B2 /* NameResolver.js */; }; >+ E92D116920F7060E00D776B2 /* NativeFunc.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D100520F56E0900D776B2 /* NativeFunc.js */; }; >+ E92D116B20F7060E00D776B2 /* NativeType.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D100620F56E0900D776B2 /* NativeType.js */; }; >+ E92D116D20F7060E00D776B2 /* Node.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D100F20F56E1500D776B2 /* Node.js */; }; >+ E92D116E20F7060E00D776B2 /* NormalUsePropertyResolver.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D100D20F56E1500D776B2 /* NormalUsePropertyResolver.js */; }; >+ E92D116F20F7060E00D776B2 /* NullLiteral.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D100C20F56E1500D776B2 /* NullLiteral.js */; }; >+ E92D117020F7060E00D776B2 /* NullType.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D101020F56E1500D776B2 /* NullType.js */; }; >+ E92D117120F7060E00D776B2 /* OriginKind.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D100E20F56E1500D776B2 /* OriginKind.js */; }; >+ E92D117220F7060E00D776B2 /* OverloadResolutionFailure.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D101920F56E2200D776B2 /* OverloadResolutionFailure.js */; }; >+ E92D117320F7060E00D776B2 /* Parse.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D101720F56E2200D776B2 /* Parse.js */; }; >+ E92D117420F7060E00D776B2 /* Prepare.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D101820F56E2200D776B2 /* Prepare.js */; }; >+ E92D117520F7060E00D776B2 /* Program.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D101A20F56E2200D776B2 /* Program.js */; }; >+ E92D117620F7060E00D776B2 /* ProgramWithUnnecessaryThingsRemoved.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D101620F56E2100D776B2 /* ProgramWithUnnecessaryThingsRemoved.js */; }; >+ E92D117720F7060E00D776B2 /* PropertyAccessExpression.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D102320F56E2F00D776B2 /* PropertyAccessExpression.js */; }; >+ E92D117820F7060E00D776B2 /* PropertyResolver.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D102020F56E2F00D776B2 /* PropertyResolver.js */; }; >+ E92D117D20F7060E00D776B2 /* PtrType.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D102B20F56E3F00D776B2 /* PtrType.js */; }; >+ E92D117E20F7060E00D776B2 /* ReadModifyWriteExpression.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D102A20F56E3F00D776B2 /* ReadModifyWriteExpression.js */; }; >+ E92D117F20F7060E00D776B2 /* RecursionChecker.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D102C20F56E3F00D776B2 /* RecursionChecker.js */; }; >+ E92D118020F7060E00D776B2 /* RecursiveTypeChecker.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D102E20F56E4000D776B2 /* RecursiveTypeChecker.js */; }; >+ E92D118120F7060E00D776B2 /* ReferenceType.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D103520F56E4F00D776B2 /* ReferenceType.js */; }; >+ E92D118220F7060E00D776B2 /* ResolveNames.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D103420F56E4F00D776B2 /* ResolveNames.js */; }; >+ E92D118320F7060E00D776B2 /* ResolveOverloadImpl.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D103820F56E4F00D776B2 /* ResolveOverloadImpl.js */; }; >+ E92D118420F7060E00D776B2 /* ResolveProperties.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D103620F56E4F00D776B2 /* ResolveProperties.js */; }; >+ E92D118520F7060E00D776B2 /* ResolveTypeDefs.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D103720F56E4F00D776B2 /* ResolveTypeDefs.js */; }; >+ E92D118620F7060E00D776B2 /* Return.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D103E20F56E6100D776B2 /* Return.js */; }; >+ E92D118720F7060E00D776B2 /* ReturnChecker.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D104020F56E6200D776B2 /* ReturnChecker.js */; }; >+ E92D118820F7060E00D776B2 /* ReturnException.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D104220F56E6200D776B2 /* ReturnException.js */; }; >+ E92D118920F7060E00D776B2 /* Rewriter.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D104120F56E6200D776B2 /* Rewriter.js */; }; >+ E92D118A20F7060E00D776B2 /* StandardLibrary.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D103F20F56E6200D776B2 /* StandardLibrary.js */; }; >+ E92D118B20F7060E00D776B2 /* StatementCloner.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D104820F56E7300D776B2 /* StatementCloner.js */; }; >+ E92D118C20F7060E00D776B2 /* StructLayoutBuilder.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D104920F56E7300D776B2 /* StructLayoutBuilder.js */; }; >+ E92D118D20F7060E00D776B2 /* StructType.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D104A20F56E7300D776B2 /* StructType.js */; }; >+ E92D118F20F7060E00D776B2 /* SwitchCase.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D104B20F56E7300D776B2 /* SwitchCase.js */; }; >+ E92D119020F7060E00D776B2 /* SwitchStatement.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D105220F56E8400D776B2 /* SwitchStatement.js */; }; >+ E92D119120F7060E00D776B2 /* SynthesizeEnumFunctions.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D105420F56E8500D776B2 /* SynthesizeEnumFunctions.js */; }; >+ E92D119220F7060E00D776B2 /* SynthesizeStructAccessors.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D105320F56E8400D776B2 /* SynthesizeStructAccessors.js */; }; >+ E92D119320F7060E00D776B2 /* TrapStatement.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D105620F56E8500D776B2 /* TrapStatement.js */; }; >+ E92D119420F7060E00D776B2 /* Type.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D105520F56E8500D776B2 /* Type.js */; }; >+ E92D119520F7060E00D776B2 /* TypeDef.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D105F20F56E9500D776B2 /* TypeDef.js */; }; >+ E92D119620F7060E00D776B2 /* TypeDefResolver.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D105E20F56E9500D776B2 /* TypeDefResolver.js */; }; >+ E92D119720F7060E00D776B2 /* TypedValue.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D106020F56E9500D776B2 /* TypedValue.js */; }; >+ E92D119A20F7060E00D776B2 /* TypeRef.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D106620F56EA400D776B2 /* TypeRef.js */; }; >+ E92D119D20F7060E00D776B2 /* UintLiteral.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D106820F56EA400D776B2 /* UintLiteral.js */; }; >+ E92D119E20F7060E00D776B2 /* UintLiteralType.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D106720F56EA400D776B2 /* UintLiteralType.js */; }; >+ E92D119F20F7060E00D776B2 /* UnificationContext.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D107220F56EBB00D776B2 /* UnificationContext.js */; }; >+ E92D11A020F7060E00D776B2 /* UnreachableCodeChecker.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D107320F56EBC00D776B2 /* UnreachableCodeChecker.js */; }; >+ E92D11A120F7060E00D776B2 /* Value.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D107420F56EBC00D776B2 /* Value.js */; }; >+ E92D11A220F7060E00D776B2 /* VariableDecl.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D107020F56EBB00D776B2 /* VariableDecl.js */; }; >+ E92D11A320F7060E00D776B2 /* VariableRef.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D107120F56EBB00D776B2 /* VariableRef.js */; }; >+ E92D11A420F7060E00D776B2 /* VisitingSet.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D107C20F56ECF00D776B2 /* VisitingSet.js */; }; >+ E92D11A520F7060E00D776B2 /* Visitor.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D107A20F56ECF00D776B2 /* Visitor.js */; }; >+ E92D11A620F7060E00D776B2 /* WhileLoop.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D107D20F56ECF00D776B2 /* WhileLoop.js */; }; >+ E92D11A720F7060E00D776B2 /* WrapChecker.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D107B20F56ECF00D776B2 /* WrapChecker.js */; }; >+ E92D11A820F7060E00D776B2 /* WSyntaxError.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D108220F56EDE00D776B2 /* WSyntaxError.js */; }; >+ E92D11A920F7060E00D776B2 /* WTrapError.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D108420F56EDE00D776B2 /* WTrapError.js */; }; >+ E92D11AA20F7060E00D776B2 /* WTypeError.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D108320F56EDE00D776B2 /* WTypeError.js */; }; >+ E92D11AD20F7081500D776B2 /* OffscreenRenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = E92D11AC20F7081500D776B2 /* OffscreenRenderer.m */; }; >+ E92D11BB20F7F67300D776B2 /* CompileResult.m in Sources */ = {isa = PBXBuildFile; fileRef = E92D11BA20F7F67300D776B2 /* CompileResult.m */; }; >+ E92EDFFB211546A40042F960 /* CustomMetalView.m in Sources */ = {isa = PBXBuildFile; fileRef = E92EDFF6211546A40042F960 /* CustomMetalView.m */; }; >+ E92EDFFC211546A40042F960 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = E92EDFF7211546A40042F960 /* AppDelegate.m */; }; >+ E92EDFFD211546A40042F960 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = E92EDFFA211546A40042F960 /* ViewController.m */; }; >+ E92EE000211546AB0042F960 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E92EDFFE211546AB0042F960 /* Main.storyboard */; }; >+ E92EE004211549C50042F960 /* TestCallArgument.m in Sources */ = {isa = PBXBuildFile; fileRef = E92EE003211549C50042F960 /* TestCallArgument.m */; }; >+ E92EE00721154AC40042F960 /* TestFamily.m in Sources */ = {isa = PBXBuildFile; fileRef = E92EE00621154AC40042F960 /* TestFamily.m */; }; >+ E92EE00A21154B5A0042F960 /* TestDescription.m in Sources */ = {isa = PBXBuildFile; fileRef = E92EE00921154B5A0042F960 /* TestDescription.m */; }; >+ E92EE00C211554980042F960 /* _SharedMetal.txt in Resources */ = {isa = PBXBuildFile; fileRef = E92EE00B211554980042F960 /* _SharedMetal.txt */; }; >+ E92EE00F211563300042F960 /* TestFamilyRunner.m in Sources */ = {isa = PBXBuildFile; fileRef = E92EE00E211563300042F960 /* TestFamilyRunner.m */; }; >+ E941ACBF2134A5BC00392BA9 /* CheckTypesWithArguments.js in Resources */ = {isa = PBXBuildFile; fileRef = E941ACAE2134A5BA00392BA9 /* CheckTypesWithArguments.js */; }; >+ E941ACC02134A5BC00392BA9 /* SynthesizeCopyConstructorOperator.js in Resources */ = {isa = PBXBuildFile; fileRef = E941ACAF2134A5BA00392BA9 /* SynthesizeCopyConstructorOperator.js */; }; >+ E941ACC42134A5BC00392BA9 /* SynthesizeDefaultConstructorOperator.js in Resources */ = {isa = PBXBuildFile; fileRef = E941ACB32134A5BB00392BA9 /* SynthesizeDefaultConstructorOperator.js */; }; >+ E941ACC62134A5BC00392BA9 /* TernaryExpression.js in Resources */ = {isa = PBXBuildFile; fileRef = E941ACB52134A5BB00392BA9 /* TernaryExpression.js */; }; >+ E941ACC72134A5BC00392BA9 /* OperatorArrayRefLength.js in Resources */ = {isa = PBXBuildFile; fileRef = E941ACB62134A5BB00392BA9 /* OperatorArrayRefLength.js */; }; >+ E941ACC82134A5BC00392BA9 /* SynthesizeArrayOperatorLength.js in Resources */ = {isa = PBXBuildFile; fileRef = E941ACB72134A5BB00392BA9 /* SynthesizeArrayOperatorLength.js */; }; >+ E941ACCA2134A5BC00392BA9 /* BuiltinVectorGetter.js in Resources */ = {isa = PBXBuildFile; fileRef = E941ACB92134A5BB00392BA9 /* BuiltinVectorGetter.js */; }; >+ E941ACCB2134A5BC00392BA9 /* TypeOverloadResolutionFailure.js in Resources */ = {isa = PBXBuildFile; fileRef = E941ACBA2134A5BB00392BA9 /* TypeOverloadResolutionFailure.js */; }; >+ E941ACCC2134A5BC00392BA9 /* VectorType.js in Resources */ = {isa = PBXBuildFile; fileRef = E941ACBB2134A5BB00392BA9 /* VectorType.js */; }; >+ E941ACCD2134A5BC00392BA9 /* BuiltinVectorSetter.js in Resources */ = {isa = PBXBuildFile; fileRef = E941ACBC2134A5BB00392BA9 /* BuiltinVectorSetter.js */; }; >+ E94C06CA20F56A4200672992 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E94C06C920F56A4200672992 /* Assets.xcassets */; }; >+ E94C06D020F56A4200672992 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = E94C06CF20F56A4200672992 /* main.m */; }; >+ E94C06DB20F56A4200672992 /* WHLSL_ToyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E94C06DA20F56A4200672992 /* WHLSL_ToyTests.m */; }; >+ E94D124F2114BD7600B0F967 /* Mandelbrot.whlsl in Resources */ = {isa = PBXBuildFile; fileRef = E94D124E2114BD7600B0F967 /* Mandelbrot.whlsl */; }; >+ E94D127F2114C6FF00B0F967 /* Test.js in Resources */ = {isa = PBXBuildFile; fileRef = E94D127E2114C6FF00B0F967 /* Test.js */; }; >+ E973E5CB213F3385005D79FC /* MSLTypeNamer.js in Resources */ = {isa = PBXBuildFile; fileRef = E973E5C4213F3385005D79FC /* MSLTypeNamer.js */; }; >+ E973E5CE213F3385005D79FC /* MSLFunctionForwardDeclaration.js in Resources */ = {isa = PBXBuildFile; fileRef = E973E5C7213F3385005D79FC /* MSLFunctionForwardDeclaration.js */; }; >+ E973E5CF213F3385005D79FC /* MSLStatementEmitter.js in Resources */ = {isa = PBXBuildFile; fileRef = E973E5C8213F3385005D79FC /* MSLStatementEmitter.js */; }; >+ E973E5DE213F341D005D79FC /* MSLFunctionDeclaration.js in Resources */ = {isa = PBXBuildFile; fileRef = E92789AC213F3364001EA73E /* MSLFunctionDeclaration.js */; }; >+ E973E5DF213F341D005D79FC /* MSLFunctionDefinition.js in Resources */ = {isa = PBXBuildFile; fileRef = E92789AB213F3364001EA73E /* MSLFunctionDefinition.js */; }; >+ E973E5E3213F341D005D79FC /* TypeOf.js in Resources */ = {isa = PBXBuildFile; fileRef = E92789B0213F3364001EA73E /* TypeOf.js */; }; >+ E9D7CB97214B824200F1C918 /* WhlslToMsl.js in Resources */ = {isa = PBXBuildFile; fileRef = E9D7CB94214B824200F1C918 /* WhlslToMsl.js */; }; >+ E9D7CB98214B824200F1C918 /* MSLBackend.js in Resources */ = {isa = PBXBuildFile; fileRef = E9D7CB95214B824200F1C918 /* MSLBackend.js */; }; >+ E9D7CB99214B824200F1C918 /* MSLConstexprEmitter.js in Resources */ = {isa = PBXBuildFile; fileRef = E9D7CB96214B824200F1C918 /* MSLConstexprEmitter.js */; }; >+ E9D7CBA0214B82B800F1C918 /* Texture.js in Resources */ = {isa = PBXBuildFile; fileRef = E9D7CB9A214B82B700F1C918 /* Texture.js */; }; >+ E9D7CBA1214B82B800F1C918 /* LateCheckAndLayoutBuffers.js in Resources */ = {isa = PBXBuildFile; fileRef = E9D7CB9B214B82B700F1C918 /* LateCheckAndLayoutBuffers.js */; }; >+ E9D7CBA2214B82B800F1C918 /* Casts.js in Resources */ = {isa = PBXBuildFile; fileRef = E9D7CB9C214B82B700F1C918 /* Casts.js */; }; >+ E9D7CBA3214B82B800F1C918 /* Sampler.js in Resources */ = {isa = PBXBuildFile; fileRef = E9D7CB9D214B82B800F1C918 /* Sampler.js */; }; >+ E9D7CBA4214B82B800F1C918 /* TextureOperations.js in Resources */ = {isa = PBXBuildFile; fileRef = E9D7CB9E214B82B800F1C918 /* TextureOperations.js */; }; >+ E9D7CBA5214B82B800F1C918 /* WLexicalError.js in Resources */ = {isa = PBXBuildFile; fileRef = E9D7CB9F214B82B800F1C918 /* WLexicalError.js */; }; >+ E9D7CBA6214B9E5F00F1C918 /* MSLCodegenAll.js in Resources */ = {isa = PBXBuildFile; fileRef = E97ED7E5214B822900AD1140 /* MSLCodegenAll.js */; }; >+ E9D7CBA7214B9E5F00F1C918 /* MSLCompileResult.js in Resources */ = {isa = PBXBuildFile; fileRef = E97ED7E8214B822900AD1140 /* MSLCompileResult.js */; }; >+ E9D7CBA8214B9E5F00F1C918 /* MSLNameMangler.js in Resources */ = {isa = PBXBuildFile; fileRef = E97ED7E1214B822900AD1140 /* MSLNameMangler.js */; }; >+ E9D7CBA9214B9E5F00F1C918 /* MSLNativeFunctionCall.js in Resources */ = {isa = PBXBuildFile; fileRef = E97ED7E4214B822900AD1140 /* MSLNativeFunctionCall.js */; }; >+ E9D7CBAA214B9E5F00F1C918 /* MSLTypeAttributes.js in Resources */ = {isa = PBXBuildFile; fileRef = E97ED7E7214B822900AD1140 /* MSLTypeAttributes.js */; }; >+ E9D7CBAB214B9E5F00F1C918 /* MSLTypeAttributesMap.js in Resources */ = {isa = PBXBuildFile; fileRef = E97ED7E2214B822900AD1140 /* MSLTypeAttributesMap.js */; }; >+ E9D7CBAC214B9E5F00F1C918 /* MSLTypeUnifier.js in Resources */ = {isa = PBXBuildFile; fileRef = E97ED7E6214B822900AD1140 /* MSLTypeUnifier.js */; }; >+ E9D7CBAD214B9E5F00F1C918 /* MSLVarDeclaration.js in Resources */ = {isa = PBXBuildFile; fileRef = E97ED7E3214B822900AD1140 /* MSLVarDeclaration.js */; }; >+ E9E11933211E61640014D553 /* Shaders.metal in Sources */ = {isa = PBXBuildFile; fileRef = E9E11932211E61640014D553 /* Shaders.metal */; }; >+/* End PBXBuildFile section */ >+ >+/* Begin PBXContainerItemProxy section */ >+ E94C06D720F56A4200672992 /* PBXContainerItemProxy */ = { >+ isa = PBXContainerItemProxy; >+ containerPortal = E94C06B820F56A4000672992 /* Project object */; >+ proxyType = 1; >+ remoteGlobalIDString = E94C06BF20F56A4000672992; >+ remoteInfo = "WHLSL Toy"; >+ }; >+/* End PBXContainerItemProxy section */ >+ >+/* Begin PBXFileReference section */ >+ E906B04521139B7700AD1C5E /* Julia.whlsl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Julia.whlsl; sourceTree = "<group>"; }; >+ E921D6322138C02600775099 /* OperatorAnderIndexer.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = OperatorAnderIndexer.js; path = ../../../OperatorAnderIndexer.js; sourceTree = "<group>"; }; >+ E921D6332138C02600775099 /* MatrixType.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = MatrixType.js; path = ../../../MatrixType.js; sourceTree = "<group>"; }; >+ E921D6342138C02600775099 /* BuiltinMatrixGetter.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = BuiltinMatrixGetter.js; path = ../../../BuiltinMatrixGetter.js; sourceTree = "<group>"; }; >+ E921D6352138C02600775099 /* BuiltinMatrixSetter.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = BuiltinMatrixSetter.js; path = ../../../BuiltinMatrixSetter.js; sourceTree = "<group>"; }; >+ E92789AB213F3364001EA73E /* MSLFunctionDefinition.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = MSLFunctionDefinition.js; path = ../../MSLFunctionDefinition.js; sourceTree = "<group>"; }; >+ E92789AC213F3364001EA73E /* MSLFunctionDeclaration.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = MSLFunctionDeclaration.js; path = ../../MSLFunctionDeclaration.js; sourceTree = "<group>"; }; >+ E92789B0213F3364001EA73E /* TypeOf.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = TypeOf.js; path = ../../TypeOf.js; sourceTree = "<group>"; }; >+ E92D0FE420F56DDD00D776B2 /* IntLiteral.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = IntLiteral.js; path = ../../../IntLiteral.js; sourceTree = "<group>"; }; >+ E92D0FE520F56DDD00D776B2 /* IntLiteralType.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = IntLiteralType.js; path = ../../../IntLiteralType.js; sourceTree = "<group>"; }; >+ E92D0FE720F56DDD00D776B2 /* Intrinsics.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = Intrinsics.js; path = ../../../Intrinsics.js; sourceTree = "<group>"; }; >+ E92D0FE820F56DDD00D776B2 /* Inliner.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = Inliner.js; path = ../../../Inliner.js; sourceTree = "<group>"; }; >+ E92D0FEE20F56DEB00D776B2 /* LogicalExpression.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = LogicalExpression.js; path = ../../../LogicalExpression.js; sourceTree = "<group>"; }; >+ E92D0FEF20F56DEB00D776B2 /* LogicalNot.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = LogicalNot.js; path = ../../../LogicalNot.js; sourceTree = "<group>"; }; >+ E92D0FF020F56DEB00D776B2 /* LexerToken.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = LexerToken.js; path = ../../../LexerToken.js; sourceTree = "<group>"; }; >+ E92D0FF120F56DEC00D776B2 /* Lexer.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = Lexer.js; path = ../../../Lexer.js; sourceTree = "<group>"; }; >+ E92D0FF220F56DEC00D776B2 /* LiteralTypeChecker.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = LiteralTypeChecker.js; path = ../../../LiteralTypeChecker.js; sourceTree = "<group>"; }; >+ E92D0FF820F56DFA00D776B2 /* NameContext.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = NameContext.js; path = ../../../NameContext.js; sourceTree = "<group>"; }; >+ E92D0FF920F56DFA00D776B2 /* MakePtrExpression.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = MakePtrExpression.js; path = ../../../MakePtrExpression.js; sourceTree = "<group>"; }; >+ E92D0FFA20F56DFB00D776B2 /* NameFinder.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = NameFinder.js; path = ../../../NameFinder.js; sourceTree = "<group>"; }; >+ E92D0FFB20F56DFB00D776B2 /* LoopChecker.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = LoopChecker.js; path = ../../../LoopChecker.js; sourceTree = "<group>"; }; >+ E92D0FFC20F56DFB00D776B2 /* MakeArrayRefExpression.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = MakeArrayRefExpression.js; path = ../../../MakeArrayRefExpression.js; sourceTree = "<group>"; }; >+ E92D100320F56E0900D776B2 /* NameResolver.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = NameResolver.js; path = ../../../NameResolver.js; sourceTree = "<group>"; }; >+ E92D100520F56E0900D776B2 /* NativeFunc.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = NativeFunc.js; path = ../../../NativeFunc.js; sourceTree = "<group>"; }; >+ E92D100620F56E0900D776B2 /* NativeType.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = NativeType.js; path = ../../../NativeType.js; sourceTree = "<group>"; }; >+ E92D100C20F56E1500D776B2 /* NullLiteral.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = NullLiteral.js; path = ../../../NullLiteral.js; sourceTree = "<group>"; }; >+ E92D100D20F56E1500D776B2 /* NormalUsePropertyResolver.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = NormalUsePropertyResolver.js; path = ../../../NormalUsePropertyResolver.js; sourceTree = "<group>"; }; >+ E92D100E20F56E1500D776B2 /* OriginKind.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = OriginKind.js; path = ../../../OriginKind.js; sourceTree = "<group>"; }; >+ E92D100F20F56E1500D776B2 /* Node.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = Node.js; path = ../../../Node.js; sourceTree = "<group>"; }; >+ E92D101020F56E1500D776B2 /* NullType.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = NullType.js; path = ../../../NullType.js; sourceTree = "<group>"; }; >+ E92D101620F56E2100D776B2 /* ProgramWithUnnecessaryThingsRemoved.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = ProgramWithUnnecessaryThingsRemoved.js; path = ../../../ProgramWithUnnecessaryThingsRemoved.js; sourceTree = "<group>"; }; >+ E92D101720F56E2200D776B2 /* Parse.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = Parse.js; path = ../../../Parse.js; sourceTree = "<group>"; }; >+ E92D101820F56E2200D776B2 /* Prepare.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = Prepare.js; path = ../../../Prepare.js; sourceTree = "<group>"; }; >+ E92D101920F56E2200D776B2 /* OverloadResolutionFailure.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = OverloadResolutionFailure.js; path = ../../../OverloadResolutionFailure.js; sourceTree = "<group>"; }; >+ E92D101A20F56E2200D776B2 /* Program.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = Program.js; path = ../../../Program.js; sourceTree = "<group>"; }; >+ E92D102020F56E2F00D776B2 /* PropertyResolver.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = PropertyResolver.js; path = ../../../PropertyResolver.js; sourceTree = "<group>"; }; >+ E92D102320F56E2F00D776B2 /* PropertyAccessExpression.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = PropertyAccessExpression.js; path = ../../../PropertyAccessExpression.js; sourceTree = "<group>"; }; >+ E92D102A20F56E3F00D776B2 /* ReadModifyWriteExpression.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = ReadModifyWriteExpression.js; path = ../../../ReadModifyWriteExpression.js; sourceTree = "<group>"; }; >+ E92D102B20F56E3F00D776B2 /* PtrType.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = PtrType.js; path = ../../../PtrType.js; sourceTree = "<group>"; }; >+ E92D102C20F56E3F00D776B2 /* RecursionChecker.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = RecursionChecker.js; path = ../../../RecursionChecker.js; sourceTree = "<group>"; }; >+ E92D102E20F56E4000D776B2 /* RecursiveTypeChecker.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = RecursiveTypeChecker.js; path = ../../../RecursiveTypeChecker.js; sourceTree = "<group>"; }; >+ E92D103420F56E4F00D776B2 /* ResolveNames.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = ResolveNames.js; path = ../../../ResolveNames.js; sourceTree = "<group>"; }; >+ E92D103520F56E4F00D776B2 /* ReferenceType.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = ReferenceType.js; path = ../../../ReferenceType.js; sourceTree = "<group>"; }; >+ E92D103620F56E4F00D776B2 /* ResolveProperties.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = ResolveProperties.js; path = ../../../ResolveProperties.js; sourceTree = "<group>"; }; >+ E92D103720F56E4F00D776B2 /* ResolveTypeDefs.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = ResolveTypeDefs.js; path = ../../../ResolveTypeDefs.js; sourceTree = "<group>"; }; >+ E92D103820F56E4F00D776B2 /* ResolveOverloadImpl.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = ResolveOverloadImpl.js; path = ../../../ResolveOverloadImpl.js; sourceTree = "<group>"; }; >+ E92D103E20F56E6100D776B2 /* Return.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = Return.js; path = ../../../Return.js; sourceTree = "<group>"; }; >+ E92D103F20F56E6200D776B2 /* StandardLibrary.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = StandardLibrary.js; path = ../../../StandardLibrary.js; sourceTree = "<group>"; }; >+ E92D104020F56E6200D776B2 /* ReturnChecker.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = ReturnChecker.js; path = ../../../ReturnChecker.js; sourceTree = "<group>"; }; >+ E92D104120F56E6200D776B2 /* Rewriter.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = Rewriter.js; path = ../../../Rewriter.js; sourceTree = "<group>"; }; >+ E92D104220F56E6200D776B2 /* ReturnException.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = ReturnException.js; path = ../../../ReturnException.js; sourceTree = "<group>"; }; >+ E92D104820F56E7300D776B2 /* StatementCloner.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = StatementCloner.js; path = ../../../StatementCloner.js; sourceTree = "<group>"; }; >+ E92D104920F56E7300D776B2 /* StructLayoutBuilder.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = StructLayoutBuilder.js; path = ../../../StructLayoutBuilder.js; sourceTree = "<group>"; }; >+ E92D104A20F56E7300D776B2 /* StructType.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = StructType.js; path = ../../../StructType.js; sourceTree = "<group>"; }; >+ E92D104B20F56E7300D776B2 /* SwitchCase.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = SwitchCase.js; path = ../../../SwitchCase.js; sourceTree = "<group>"; }; >+ E92D105220F56E8400D776B2 /* SwitchStatement.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = SwitchStatement.js; path = ../../../SwitchStatement.js; sourceTree = "<group>"; }; >+ E92D105320F56E8400D776B2 /* SynthesizeStructAccessors.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = SynthesizeStructAccessors.js; path = ../../../SynthesizeStructAccessors.js; sourceTree = "<group>"; }; >+ E92D105420F56E8500D776B2 /* SynthesizeEnumFunctions.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = SynthesizeEnumFunctions.js; path = ../../../SynthesizeEnumFunctions.js; sourceTree = "<group>"; }; >+ E92D105520F56E8500D776B2 /* Type.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = Type.js; path = ../../../Type.js; sourceTree = "<group>"; }; >+ E92D105620F56E8500D776B2 /* TrapStatement.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = TrapStatement.js; path = ../../../TrapStatement.js; sourceTree = "<group>"; }; >+ E92D105E20F56E9500D776B2 /* TypeDefResolver.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = TypeDefResolver.js; path = ../../../TypeDefResolver.js; sourceTree = "<group>"; }; >+ E92D105F20F56E9500D776B2 /* TypeDef.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = TypeDef.js; path = ../../../TypeDef.js; sourceTree = "<group>"; }; >+ E92D106020F56E9500D776B2 /* TypedValue.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = TypedValue.js; path = ../../../TypedValue.js; sourceTree = "<group>"; }; >+ E92D106620F56EA400D776B2 /* TypeRef.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = TypeRef.js; path = ../../../TypeRef.js; sourceTree = "<group>"; }; >+ E92D106720F56EA400D776B2 /* UintLiteralType.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = UintLiteralType.js; path = ../../../UintLiteralType.js; sourceTree = "<group>"; }; >+ E92D106820F56EA400D776B2 /* UintLiteral.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = UintLiteral.js; path = ../../../UintLiteral.js; sourceTree = "<group>"; }; >+ E92D107020F56EBB00D776B2 /* VariableDecl.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = VariableDecl.js; path = ../../../VariableDecl.js; sourceTree = "<group>"; }; >+ E92D107120F56EBB00D776B2 /* VariableRef.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = VariableRef.js; path = ../../../VariableRef.js; sourceTree = "<group>"; }; >+ E92D107220F56EBB00D776B2 /* UnificationContext.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = UnificationContext.js; path = ../../../UnificationContext.js; sourceTree = "<group>"; }; >+ E92D107320F56EBC00D776B2 /* UnreachableCodeChecker.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = UnreachableCodeChecker.js; path = ../../../UnreachableCodeChecker.js; sourceTree = "<group>"; }; >+ E92D107420F56EBC00D776B2 /* Value.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = Value.js; path = ../../../Value.js; sourceTree = "<group>"; }; >+ E92D107A20F56ECF00D776B2 /* Visitor.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = Visitor.js; path = ../../../Visitor.js; sourceTree = "<group>"; }; >+ E92D107B20F56ECF00D776B2 /* WrapChecker.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = WrapChecker.js; path = ../../../WrapChecker.js; sourceTree = "<group>"; }; >+ E92D107C20F56ECF00D776B2 /* VisitingSet.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = VisitingSet.js; path = ../../../VisitingSet.js; sourceTree = "<group>"; }; >+ E92D107D20F56ECF00D776B2 /* WhileLoop.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = WhileLoop.js; path = ../../../WhileLoop.js; sourceTree = "<group>"; }; >+ E92D108220F56EDE00D776B2 /* WSyntaxError.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = WSyntaxError.js; path = ../../../WSyntaxError.js; sourceTree = "<group>"; }; >+ E92D108320F56EDE00D776B2 /* WTypeError.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = WTypeError.js; path = ../../../WTypeError.js; sourceTree = "<group>"; }; >+ E92D108420F56EDE00D776B2 /* WTrapError.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = WTrapError.js; path = ../../../WTrapError.js; sourceTree = "<group>"; }; >+ E92D108820F56F0600D776B2 /* Compiler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Compiler.h; sourceTree = "<group>"; }; >+ E92D108920F56F0600D776B2 /* Compiler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Compiler.m; sourceTree = "<group>"; }; >+ E92D108C20F56F4500D776B2 /* MetalKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MetalKit.framework; path = System/Library/Frameworks/MetalKit.framework; sourceTree = SDKROOT; }; >+ E92D108E20F56F4F00D776B2 /* Metal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Metal.framework; path = System/Library/Frameworks/Metal.framework; sourceTree = SDKROOT; }; >+ E92D109020F56F5700D776B2 /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; >+ E92D109220F5734900D776B2 /* Default.whlsl */ = {isa = PBXFileReference; lastKnownFileType = text; path = Default.whlsl; sourceTree = "<group>"; }; >+ E92D10AD20F57C9F00D776B2 /* OnscreenRenderer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OnscreenRenderer.h; sourceTree = "<group>"; }; >+ E92D10AE20F57C9F00D776B2 /* OnscreenRenderer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OnscreenRenderer.m; sourceTree = "<group>"; }; >+ E92D111320F6FFB600D776B2 /* Renderer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Renderer.h; sourceTree = "<group>"; }; >+ E92D111420F6FFB600D776B2 /* Renderer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Renderer.m; sourceTree = "<group>"; }; >+ E92D11AB20F7081500D776B2 /* OffscreenRenderer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OffscreenRenderer.h; sourceTree = "<group>"; }; >+ E92D11AC20F7081500D776B2 /* OffscreenRenderer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OffscreenRenderer.m; sourceTree = "<group>"; }; >+ E92D11B920F7F67300D776B2 /* CompileResult.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CompileResult.h; sourceTree = "<group>"; }; >+ E92D11BA20F7F67300D776B2 /* CompileResult.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CompileResult.m; sourceTree = "<group>"; }; >+ E92EDFF5211546A40042F960 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; }; >+ E92EDFF6211546A40042F960 /* CustomMetalView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CustomMetalView.m; sourceTree = "<group>"; }; >+ E92EDFF7211546A40042F960 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; }; >+ E92EDFF8211546A40042F960 /* CustomMetalView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomMetalView.h; sourceTree = "<group>"; }; >+ E92EDFF9211546A40042F960 /* ViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; }; >+ E92EDFFA211546A40042F960 /* ViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = "<group>"; }; >+ E92EDFFF211546AB0042F960 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; }; >+ E92EE002211549C50042F960 /* TestCallArgument.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TestCallArgument.h; sourceTree = "<group>"; }; >+ E92EE003211549C50042F960 /* TestCallArgument.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TestCallArgument.m; sourceTree = "<group>"; }; >+ E92EE00521154AC40042F960 /* TestFamily.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TestFamily.h; sourceTree = "<group>"; }; >+ E92EE00621154AC40042F960 /* TestFamily.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TestFamily.m; sourceTree = "<group>"; }; >+ E92EE00821154B5A0042F960 /* TestDescription.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TestDescription.h; sourceTree = "<group>"; }; >+ E92EE00921154B5A0042F960 /* TestDescription.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TestDescription.m; sourceTree = "<group>"; }; >+ E92EE00B211554980042F960 /* _SharedMetal.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = _SharedMetal.txt; sourceTree = "<group>"; }; >+ E92EE00D211563300042F960 /* TestFamilyRunner.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TestFamilyRunner.h; sourceTree = "<group>"; }; >+ E92EE00E211563300042F960 /* TestFamilyRunner.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TestFamilyRunner.m; sourceTree = "<group>"; }; >+ E941ACAE2134A5BA00392BA9 /* CheckTypesWithArguments.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = CheckTypesWithArguments.js; path = ../../../CheckTypesWithArguments.js; sourceTree = "<group>"; }; >+ E941ACAF2134A5BA00392BA9 /* SynthesizeCopyConstructorOperator.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = SynthesizeCopyConstructorOperator.js; path = ../../../SynthesizeCopyConstructorOperator.js; sourceTree = "<group>"; }; >+ E941ACB32134A5BB00392BA9 /* SynthesizeDefaultConstructorOperator.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = SynthesizeDefaultConstructorOperator.js; path = ../../../SynthesizeDefaultConstructorOperator.js; sourceTree = "<group>"; }; >+ E941ACB52134A5BB00392BA9 /* TernaryExpression.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = TernaryExpression.js; path = ../../../TernaryExpression.js; sourceTree = "<group>"; }; >+ E941ACB62134A5BB00392BA9 /* OperatorArrayRefLength.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = OperatorArrayRefLength.js; path = ../../../OperatorArrayRefLength.js; sourceTree = "<group>"; }; >+ E941ACB72134A5BB00392BA9 /* SynthesizeArrayOperatorLength.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = SynthesizeArrayOperatorLength.js; path = ../../../SynthesizeArrayOperatorLength.js; sourceTree = "<group>"; }; >+ E941ACB92134A5BB00392BA9 /* BuiltinVectorGetter.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = BuiltinVectorGetter.js; path = ../../../BuiltinVectorGetter.js; sourceTree = "<group>"; }; >+ E941ACBA2134A5BB00392BA9 /* TypeOverloadResolutionFailure.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = TypeOverloadResolutionFailure.js; path = ../../../TypeOverloadResolutionFailure.js; sourceTree = "<group>"; }; >+ E941ACBB2134A5BB00392BA9 /* VectorType.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = VectorType.js; path = ../../../VectorType.js; sourceTree = "<group>"; }; >+ E941ACBC2134A5BB00392BA9 /* BuiltinVectorSetter.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = BuiltinVectorSetter.js; path = ../../../BuiltinVectorSetter.js; sourceTree = "<group>"; }; >+ E94C06C020F56A4000672992 /* WHLSL Tests.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "WHLSL Tests.app"; sourceTree = BUILT_PRODUCTS_DIR; }; >+ E94C06C920F56A4200672992 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; >+ E94C06CE20F56A4200672992 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; >+ E94C06CF20F56A4200672992 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; }; >+ E94C06D120F56A4200672992 /* WHLSL.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = WHLSL.entitlements; sourceTree = "<group>"; }; >+ E94C06D620F56A4200672992 /* WHLSL TestsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "WHLSL TestsTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; >+ E94C06DA20F56A4200672992 /* WHLSL_ToyTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = WHLSL_ToyTests.m; sourceTree = "<group>"; }; >+ E94C06DC20F56A4200672992 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; >+ E94C06F920F56CA300672992 /* DereferenceExpression.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = DereferenceExpression.js; path = ../../../DereferenceExpression.js; sourceTree = "<group>"; }; >+ E94C06FA20F56CA300672992 /* CheckRecursion.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = CheckRecursion.js; path = ../../../CheckRecursion.js; sourceTree = "<group>"; }; >+ E94C06FB20F56CA300672992 /* HighZombieFinder.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = HighZombieFinder.js; path = ../../../HighZombieFinder.js; sourceTree = "<group>"; }; >+ E94C06FC20F56CA300672992 /* Block.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = Block.js; path = ../../../Block.js; sourceTree = "<group>"; }; >+ E94C06FD20F56CA300672992 /* EnumLiteral.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = EnumLiteral.js; path = ../../../EnumLiteral.js; sourceTree = "<group>"; }; >+ E94D124E2114BD7600B0F967 /* Mandelbrot.whlsl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Mandelbrot.whlsl; sourceTree = "<group>"; }; >+ E94D127E2114C6FF00B0F967 /* Test.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = Test.js; path = ../../../Test.js; sourceTree = "<group>"; }; >+ E95569B020F56CD600F5CF34 /* Break.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = Break.js; path = ../../../Break.js; sourceTree = "<group>"; }; >+ E95569B120F56CD600F5CF34 /* BoolLiteral.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = BoolLiteral.js; path = ../../../BoolLiteral.js; sourceTree = "<group>"; }; >+ E95569B220F56CD600F5CF34 /* CheckReturns.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = CheckReturns.js; path = ../../../CheckReturns.js; sourceTree = "<group>"; }; >+ E95569B320F56CD600F5CF34 /* CheckLoops.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = CheckLoops.js; path = ../../../CheckLoops.js; sourceTree = "<group>"; }; >+ E95569B420F56CD600F5CF34 /* ArrayType.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = ArrayType.js; path = ../../../ArrayType.js; sourceTree = "<group>"; }; >+ E95569B520F56CD600F5CF34 /* ArrayRefType.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = ArrayRefType.js; path = ../../../ArrayRefType.js; sourceTree = "<group>"; }; >+ E95569B620F56CD600F5CF34 /* CheckLiteralTypes.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = CheckLiteralTypes.js; path = ../../../CheckLiteralTypes.js; sourceTree = "<group>"; }; >+ E95569B720F56CD600F5CF34 /* CheckUnreachableCode.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = CheckUnreachableCode.js; path = ../../../CheckUnreachableCode.js; sourceTree = "<group>"; }; >+ E95569B820F56CD600F5CF34 /* Check.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = Check.js; path = ../../../Check.js; sourceTree = "<group>"; }; >+ E95569B920F56CD600F5CF34 /* Assignment.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = Assignment.js; path = ../../../Assignment.js; sourceTree = "<group>"; }; >+ E95569BA20F56CD600F5CF34 /* AddressSpace.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = AddressSpace.js; path = ../../../AddressSpace.js; sourceTree = "<group>"; }; >+ E95569BB20F56CD600F5CF34 /* CheckRecursiveTypes.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = CheckRecursiveTypes.js; path = ../../../CheckRecursiveTypes.js; sourceTree = "<group>"; }; >+ E95569BC20F56CD700F5CF34 /* All.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = All.js; path = ../../../All.js; sourceTree = "<group>"; }; >+ E95569BD20F56CD700F5CF34 /* AnonymousVariable.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = AnonymousVariable.js; path = ../../../AnonymousVariable.js; sourceTree = "<group>"; }; >+ E95569BE20F56CD700F5CF34 /* AutoWrapper.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = AutoWrapper.js; path = ../../../AutoWrapper.js; sourceTree = "<group>"; }; >+ E95569BF20F56CD700F5CF34 /* CallExpression.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = CallExpression.js; path = ../../../CallExpression.js; sourceTree = "<group>"; }; >+ E95569C020F56CD700F5CF34 /* CallFunction.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = CallFunction.js; path = ../../../CallFunction.js; sourceTree = "<group>"; }; >+ E95569C120F56CD700F5CF34 /* Checker.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = Checker.js; path = ../../../Checker.js; sourceTree = "<group>"; }; >+ E95569D420F56CED00F5CF34 /* CheckWrapped.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = CheckWrapped.js; path = ../../../CheckWrapped.js; sourceTree = "<group>"; }; >+ E95569D520F56CED00F5CF34 /* ConstexprFolder.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = ConstexprFolder.js; path = ../../../ConstexprFolder.js; sourceTree = "<group>"; }; >+ E95569D620F56CED00F5CF34 /* CreateLiteralType.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = CreateLiteralType.js; path = ../../../CreateLiteralType.js; sourceTree = "<group>"; }; >+ E95569D720F56CED00F5CF34 /* Continue.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = Continue.js; path = ../../../Continue.js; sourceTree = "<group>"; }; >+ E95569D820F56CED00F5CF34 /* CreateLiteral.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = CreateLiteral.js; path = ../../../CreateLiteral.js; sourceTree = "<group>"; }; >+ E95569D920F56CED00F5CF34 /* ConvertPtrToArrayRefExpression.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = ConvertPtrToArrayRefExpression.js; path = ../../../ConvertPtrToArrayRefExpression.js; sourceTree = "<group>"; }; >+ E95569DB20F56CEE00F5CF34 /* CloneProgram.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = CloneProgram.js; path = ../../../CloneProgram.js; sourceTree = "<group>"; }; >+ E95569DC20F56CEE00F5CF34 /* CommaExpression.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = CommaExpression.js; path = ../../../CommaExpression.js; sourceTree = "<group>"; }; >+ E95569E620F56D0500F5CF34 /* FunctionLikeBlock.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = FunctionLikeBlock.js; path = ../../../FunctionLikeBlock.js; sourceTree = "<group>"; }; >+ E95569E720F56D0500F5CF34 /* EPtr.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = EPtr.js; path = ../../../EPtr.js; sourceTree = "<group>"; }; >+ E95569E820F56D0500F5CF34 /* FuncDef.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = FuncDef.js; path = ../../../FuncDef.js; sourceTree = "<group>"; }; >+ E95569E920F56D0500F5CF34 /* FuncParameter.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = FuncParameter.js; path = ../../../FuncParameter.js; sourceTree = "<group>"; }; >+ E95569EA20F56D0500F5CF34 /* FloatLiteralType.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = FloatLiteralType.js; path = ../../../FloatLiteralType.js; sourceTree = "<group>"; }; >+ E95569EB20F56D0500F5CF34 /* FoldConstexprs.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = FoldConstexprs.js; path = ../../../FoldConstexprs.js; sourceTree = "<group>"; }; >+ E973E5C4213F3385005D79FC /* MSLTypeNamer.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = MSLTypeNamer.js; path = ../../MSLTypeNamer.js; sourceTree = "<group>"; }; >+ E973E5C7213F3385005D79FC /* MSLFunctionForwardDeclaration.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = MSLFunctionForwardDeclaration.js; path = ../../MSLFunctionForwardDeclaration.js; sourceTree = "<group>"; }; >+ E973E5C8213F3385005D79FC /* MSLStatementEmitter.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = MSLStatementEmitter.js; path = ../../MSLStatementEmitter.js; sourceTree = "<group>"; }; >+ E97ED7E1214B822900AD1140 /* MSLNameMangler.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = MSLNameMangler.js; path = ../../MSLNameMangler.js; sourceTree = "<group>"; }; >+ E97ED7E2214B822900AD1140 /* MSLTypeAttributesMap.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = MSLTypeAttributesMap.js; path = ../../MSLTypeAttributesMap.js; sourceTree = "<group>"; }; >+ E97ED7E3214B822900AD1140 /* MSLVarDeclaration.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = MSLVarDeclaration.js; path = ../../MSLVarDeclaration.js; sourceTree = "<group>"; }; >+ E97ED7E4214B822900AD1140 /* MSLNativeFunctionCall.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = MSLNativeFunctionCall.js; path = ../../MSLNativeFunctionCall.js; sourceTree = "<group>"; }; >+ E97ED7E5214B822900AD1140 /* MSLCodegenAll.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = MSLCodegenAll.js; path = ../../MSLCodegenAll.js; sourceTree = "<group>"; }; >+ E97ED7E6214B822900AD1140 /* MSLTypeUnifier.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = MSLTypeUnifier.js; path = ../../MSLTypeUnifier.js; sourceTree = "<group>"; }; >+ E97ED7E7214B822900AD1140 /* MSLTypeAttributes.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = MSLTypeAttributes.js; path = ../../MSLTypeAttributes.js; sourceTree = "<group>"; }; >+ E97ED7E8214B822900AD1140 /* MSLCompileResult.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = MSLCompileResult.js; path = ../../MSLCompileResult.js; sourceTree = "<group>"; }; >+ E9AD074620F56D5A007F2466 /* DoWhileLoop.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = DoWhileLoop.js; path = ../../../DoWhileLoop.js; sourceTree = "<group>"; }; >+ E9AD074820F56D5A007F2466 /* EBuffer.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = EBuffer.js; path = ../../../EBuffer.js; sourceTree = "<group>"; }; >+ E9AD074920F56D5A007F2466 /* EArrayRef.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = EArrayRef.js; path = ../../../EArrayRef.js; sourceTree = "<group>"; }; >+ E9AD074A20F56D5B007F2466 /* EBufferBuilder.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = EBufferBuilder.js; path = ../../../EBufferBuilder.js; sourceTree = "<group>"; }; >+ E9AD074B20F56D5B007F2466 /* DotExpression.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = DotExpression.js; path = ../../../DotExpression.js; sourceTree = "<group>"; }; >+ E9AD075320F56D69007F2466 /* EvaluationCommon.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = EvaluationCommon.js; path = ../../../EvaluationCommon.js; sourceTree = "<group>"; }; >+ E9AD075420F56D69007F2466 /* Expression.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = Expression.js; path = ../../../Expression.js; sourceTree = "<group>"; }; >+ E9AD075520F56D69007F2466 /* EnumMember.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = EnumMember.js; path = ../../../EnumMember.js; sourceTree = "<group>"; }; >+ E9AD075620F56D69007F2466 /* FlattenedStructOffsetGatherer.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = FlattenedStructOffsetGatherer.js; path = ../../../FlattenedStructOffsetGatherer.js; sourceTree = "<group>"; }; >+ E9AD075720F56D69007F2466 /* Evaluator.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = Evaluator.js; path = ../../../Evaluator.js; sourceTree = "<group>"; }; >+ E9AD075820F56D69007F2466 /* FindHighZombies.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = FindHighZombies.js; path = ../../../FindHighZombies.js; sourceTree = "<group>"; }; >+ E9AD075920F56D69007F2466 /* ExpressionFinder.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = ExpressionFinder.js; path = ../../../ExpressionFinder.js; sourceTree = "<group>"; }; >+ E9AD075A20F56D69007F2466 /* EnumType.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = EnumType.js; path = ../../../EnumType.js; sourceTree = "<group>"; }; >+ E9AD075B20F56D69007F2466 /* ExternalOrigin.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = ExternalOrigin.js; path = ../../../ExternalOrigin.js; sourceTree = "<group>"; }; >+ E9AD075C20F56D69007F2466 /* FloatLiteral.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = FloatLiteral.js; path = ../../../FloatLiteral.js; sourceTree = "<group>"; }; >+ E9D7CB94214B824200F1C918 /* WhlslToMsl.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = WhlslToMsl.js; path = ../../WhlslToMsl.js; sourceTree = "<group>"; }; >+ E9D7CB95214B824200F1C918 /* MSLBackend.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = MSLBackend.js; path = ../../MSLBackend.js; sourceTree = "<group>"; }; >+ E9D7CB96214B824200F1C918 /* MSLConstexprEmitter.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = MSLConstexprEmitter.js; path = ../../MSLConstexprEmitter.js; sourceTree = "<group>"; }; >+ E9D7CB9A214B82B700F1C918 /* Texture.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = Texture.js; path = ../../../Texture.js; sourceTree = "<group>"; }; >+ E9D7CB9B214B82B700F1C918 /* LateCheckAndLayoutBuffers.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = LateCheckAndLayoutBuffers.js; path = ../../../LateCheckAndLayoutBuffers.js; sourceTree = "<group>"; }; >+ E9D7CB9C214B82B700F1C918 /* Casts.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = Casts.js; path = ../../../Casts.js; sourceTree = "<group>"; }; >+ E9D7CB9D214B82B800F1C918 /* Sampler.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = Sampler.js; path = ../../../Sampler.js; sourceTree = "<group>"; }; >+ E9D7CB9E214B82B800F1C918 /* TextureOperations.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = TextureOperations.js; path = ../../../TextureOperations.js; sourceTree = "<group>"; }; >+ E9D7CB9F214B82B800F1C918 /* WLexicalError.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = WLexicalError.js; path = ../../../WLexicalError.js; sourceTree = "<group>"; }; >+ E9E11932211E61640014D553 /* Shaders.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; path = Shaders.metal; sourceTree = "<group>"; }; >+ E9FCEB5520F56D92009B3629 /* Func.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = Func.js; path = ../../../Func.js; sourceTree = "<group>"; }; >+ E9FCEB5720F56D93009B3629 /* IfStatement.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = IfStatement.js; path = ../../../IfStatement.js; sourceTree = "<group>"; }; >+ E9FCEB5820F56D93009B3629 /* IdentityExpression.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = IdentityExpression.js; path = ../../../IdentityExpression.js; sourceTree = "<group>"; }; >+ E9FCEB5A20F56D93009B3629 /* ForLoop.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = ForLoop.js; path = ../../../ForLoop.js; sourceTree = "<group>"; }; >+ E9FCEB5B20F56D93009B3629 /* Field.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = Field.js; path = ../../../Field.js; sourceTree = "<group>"; }; >+ E9FCEB6320F56DA4009B3629 /* IndexExpression.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = IndexExpression.js; path = ../../../IndexExpression.js; sourceTree = "<group>"; }; >+ E9FCEB6420F56DA5009B3629 /* LateChecker.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = LateChecker.js; path = ../../../LateChecker.js; sourceTree = "<group>"; }; >+ E9FCEB6520F56DA5009B3629 /* InferTypesForCall.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = InferTypesForCall.js; path = ../../../InferTypesForCall.js; sourceTree = "<group>"; }; >+ E9FCEB6620F56DA5009B3629 /* Inline.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = Inline.js; path = ../../../Inline.js; sourceTree = "<group>"; }; >+/* End PBXFileReference section */ >+ >+/* Begin PBXFrameworksBuildPhase section */ >+ E94C06BD20F56A4000672992 /* Frameworks */ = { >+ isa = PBXFrameworksBuildPhase; >+ buildActionMask = 2147483647; >+ files = ( >+ E92D109120F56F5700D776B2 /* JavaScriptCore.framework in Frameworks */, >+ E92D108F20F56F4F00D776B2 /* Metal.framework in Frameworks */, >+ E92D108D20F56F4500D776B2 /* MetalKit.framework in Frameworks */, >+ ); >+ runOnlyForDeploymentPostprocessing = 0; >+ }; >+ E94C06D320F56A4200672992 /* Frameworks */ = { >+ isa = PBXFrameworksBuildPhase; >+ buildActionMask = 2147483647; >+ files = ( >+ ); >+ runOnlyForDeploymentPostprocessing = 0; >+ }; >+/* End PBXFrameworksBuildPhase section */ >+ >+/* Begin PBXGroup section */ >+ E906B04A2114BD1D00AD1C5E /* Demo shaders */ = { >+ isa = PBXGroup; >+ children = ( >+ E92D109220F5734900D776B2 /* Default.whlsl */, >+ E906B04521139B7700AD1C5E /* Julia.whlsl */, >+ E94D124E2114BD7600B0F967 /* Mandelbrot.whlsl */, >+ ); >+ path = "Demo shaders"; >+ sourceTree = "<group>"; >+ }; >+ E92D108B20F56F4400D776B2 /* Frameworks */ = { >+ isa = PBXGroup; >+ children = ( >+ E92D109020F56F5700D776B2 /* JavaScriptCore.framework */, >+ E92D108E20F56F4F00D776B2 /* Metal.framework */, >+ E92D108C20F56F4500D776B2 /* MetalKit.framework */, >+ ); >+ name = Frameworks; >+ sourceTree = "<group>"; >+ }; >+ E92D11AE20F70BAE00D776B2 /* Renderer */ = { >+ isa = PBXGroup; >+ children = ( >+ E92D11AB20F7081500D776B2 /* OffscreenRenderer.h */, >+ E92D11AC20F7081500D776B2 /* OffscreenRenderer.m */, >+ E92D10AD20F57C9F00D776B2 /* OnscreenRenderer.h */, >+ E92D10AE20F57C9F00D776B2 /* OnscreenRenderer.m */, >+ E92D111320F6FFB600D776B2 /* Renderer.h */, >+ E92D111420F6FFB600D776B2 /* Renderer.m */, >+ ); >+ path = Renderer; >+ sourceTree = "<group>"; >+ }; >+ E92EDFF4211546910042F960 /* App */ = { >+ isa = PBXGroup; >+ children = ( >+ E92EDFF5211546A40042F960 /* AppDelegate.h */, >+ E92EDFF7211546A40042F960 /* AppDelegate.m */, >+ E92EDFF8211546A40042F960 /* CustomMetalView.h */, >+ E92EDFF6211546A40042F960 /* CustomMetalView.m */, >+ E92EDFFE211546AB0042F960 /* Main.storyboard */, >+ E92EDFF9211546A40042F960 /* ViewController.h */, >+ E92EDFFA211546A40042F960 /* ViewController.m */, >+ ); >+ name = App; >+ sourceTree = "<group>"; >+ }; >+ E92EE0012115499E0042F960 /* Test execution */ = { >+ isa = PBXGroup; >+ children = ( >+ E92EE00B211554980042F960 /* _SharedMetal.txt */, >+ E92EE002211549C50042F960 /* TestCallArgument.h */, >+ E92EE003211549C50042F960 /* TestCallArgument.m */, >+ E92EE00821154B5A0042F960 /* TestDescription.h */, >+ E92EE00921154B5A0042F960 /* TestDescription.m */, >+ E92EE00521154AC40042F960 /* TestFamily.h */, >+ E92EE00621154AC40042F960 /* TestFamily.m */, >+ E92EE00D211563300042F960 /* TestFamilyRunner.h */, >+ E92EE00E211563300042F960 /* TestFamilyRunner.m */, >+ ); >+ name = "Test execution"; >+ sourceTree = "<group>"; >+ }; >+ E94C06B720F56A4000672992 = { >+ isa = PBXGroup; >+ children = ( >+ E94C06C220F56A4000672992 /* Core */, >+ E92D108B20F56F4400D776B2 /* Frameworks */, >+ E94C06C120F56A4000672992 /* Products */, >+ E94C06D920F56A4200672992 /* WHLSL Tests */, >+ ); >+ sourceTree = "<group>"; >+ }; >+ E94C06C120F56A4000672992 /* Products */ = { >+ isa = PBXGroup; >+ children = ( >+ E94C06C020F56A4000672992 /* WHLSL Tests.app */, >+ E94C06D620F56A4200672992 /* WHLSL TestsTests.xctest */, >+ ); >+ name = Products; >+ sourceTree = "<group>"; >+ }; >+ E94C06C220F56A4000672992 /* Core */ = { >+ isa = PBXGroup; >+ children = ( >+ E92EDFF4211546910042F960 /* App */, >+ E906B04A2114BD1D00AD1C5E /* Demo shaders */, >+ E9E11931211E614D0014D553 /* Metal equivalents */, >+ E92D11AE20F70BAE00D776B2 /* Renderer */, >+ E94C06F620F56C4F00672992 /* Scripts */, >+ E92EE0012115499E0042F960 /* Test execution */, >+ E94C06C920F56A4200672992 /* Assets.xcassets */, >+ E92D108820F56F0600D776B2 /* Compiler.h */, >+ E92D108920F56F0600D776B2 /* Compiler.m */, >+ E92D11B920F7F67300D776B2 /* CompileResult.h */, >+ E92D11BA20F7F67300D776B2 /* CompileResult.m */, >+ E94C06CE20F56A4200672992 /* Info.plist */, >+ E94C06CF20F56A4200672992 /* main.m */, >+ E94C06D120F56A4200672992 /* WHLSL.entitlements */, >+ ); >+ path = Core; >+ sourceTree = "<group>"; >+ }; >+ E94C06D920F56A4200672992 /* WHLSL Tests */ = { >+ isa = PBXGroup; >+ children = ( >+ E94C06DC20F56A4200672992 /* Info.plist */, >+ E94C06DA20F56A4200672992 /* WHLSL_ToyTests.m */, >+ ); >+ name = "WHLSL Tests"; >+ path = "WHLSL ToyTests"; >+ sourceTree = "<group>"; >+ }; >+ E94C06F620F56C4F00672992 /* Scripts */ = { >+ isa = PBXGroup; >+ children = ( >+ E95569BA20F56CD600F5CF34 /* AddressSpace.js */, >+ E95569BC20F56CD700F5CF34 /* All.js */, >+ E95569BD20F56CD700F5CF34 /* AnonymousVariable.js */, >+ E95569B520F56CD600F5CF34 /* ArrayRefType.js */, >+ E95569B420F56CD600F5CF34 /* ArrayType.js */, >+ E95569B920F56CD600F5CF34 /* Assignment.js */, >+ E95569BE20F56CD700F5CF34 /* AutoWrapper.js */, >+ E94C06FC20F56CA300672992 /* Block.js */, >+ E95569B120F56CD600F5CF34 /* BoolLiteral.js */, >+ E95569B020F56CD600F5CF34 /* Break.js */, >+ E921D6342138C02600775099 /* BuiltinMatrixGetter.js */, >+ E921D6352138C02600775099 /* BuiltinMatrixSetter.js */, >+ E941ACB92134A5BB00392BA9 /* BuiltinVectorGetter.js */, >+ E941ACBC2134A5BB00392BA9 /* BuiltinVectorSetter.js */, >+ E95569BF20F56CD700F5CF34 /* CallExpression.js */, >+ E95569C020F56CD700F5CF34 /* CallFunction.js */, >+ E9D7CB9C214B82B700F1C918 /* Casts.js */, >+ E95569B820F56CD600F5CF34 /* Check.js */, >+ E95569C120F56CD700F5CF34 /* Checker.js */, >+ E95569B620F56CD600F5CF34 /* CheckLiteralTypes.js */, >+ E95569B320F56CD600F5CF34 /* CheckLoops.js */, >+ E94C06FA20F56CA300672992 /* CheckRecursion.js */, >+ E95569BB20F56CD600F5CF34 /* CheckRecursiveTypes.js */, >+ E95569B220F56CD600F5CF34 /* CheckReturns.js */, >+ E941ACAE2134A5BA00392BA9 /* CheckTypesWithArguments.js */, >+ E95569B720F56CD600F5CF34 /* CheckUnreachableCode.js */, >+ E95569D420F56CED00F5CF34 /* CheckWrapped.js */, >+ E95569DB20F56CEE00F5CF34 /* CloneProgram.js */, >+ E95569DC20F56CEE00F5CF34 /* CommaExpression.js */, >+ E95569D520F56CED00F5CF34 /* ConstexprFolder.js */, >+ E95569D720F56CED00F5CF34 /* Continue.js */, >+ E95569D920F56CED00F5CF34 /* ConvertPtrToArrayRefExpression.js */, >+ E95569D820F56CED00F5CF34 /* CreateLiteral.js */, >+ E95569D620F56CED00F5CF34 /* CreateLiteralType.js */, >+ E94C06F920F56CA300672992 /* DereferenceExpression.js */, >+ E9AD074B20F56D5B007F2466 /* DotExpression.js */, >+ E9AD074620F56D5A007F2466 /* DoWhileLoop.js */, >+ E9AD074920F56D5A007F2466 /* EArrayRef.js */, >+ E9AD074820F56D5A007F2466 /* EBuffer.js */, >+ E9AD074A20F56D5B007F2466 /* EBufferBuilder.js */, >+ E94C06FD20F56CA300672992 /* EnumLiteral.js */, >+ E9AD075520F56D69007F2466 /* EnumMember.js */, >+ E9AD075A20F56D69007F2466 /* EnumType.js */, >+ E95569E720F56D0500F5CF34 /* EPtr.js */, >+ E9AD075320F56D69007F2466 /* EvaluationCommon.js */, >+ E9AD075720F56D69007F2466 /* Evaluator.js */, >+ E9AD075420F56D69007F2466 /* Expression.js */, >+ E9AD075920F56D69007F2466 /* ExpressionFinder.js */, >+ E9AD075B20F56D69007F2466 /* ExternalOrigin.js */, >+ E9FCEB5B20F56D93009B3629 /* Field.js */, >+ E9AD075820F56D69007F2466 /* FindHighZombies.js */, >+ E9AD075620F56D69007F2466 /* FlattenedStructOffsetGatherer.js */, >+ E9AD075C20F56D69007F2466 /* FloatLiteral.js */, >+ E95569EA20F56D0500F5CF34 /* FloatLiteralType.js */, >+ E95569EB20F56D0500F5CF34 /* FoldConstexprs.js */, >+ E9FCEB5A20F56D93009B3629 /* ForLoop.js */, >+ E9FCEB5520F56D92009B3629 /* Func.js */, >+ E95569E820F56D0500F5CF34 /* FuncDef.js */, >+ E95569E920F56D0500F5CF34 /* FuncParameter.js */, >+ E95569E620F56D0500F5CF34 /* FunctionLikeBlock.js */, >+ E94C06FB20F56CA300672992 /* HighZombieFinder.js */, >+ E9FCEB5820F56D93009B3629 /* IdentityExpression.js */, >+ E9FCEB5720F56D93009B3629 /* IfStatement.js */, >+ E9FCEB6320F56DA4009B3629 /* IndexExpression.js */, >+ E9FCEB6520F56DA5009B3629 /* InferTypesForCall.js */, >+ E9FCEB6620F56DA5009B3629 /* Inline.js */, >+ E92D0FE820F56DDD00D776B2 /* Inliner.js */, >+ E92D0FE420F56DDD00D776B2 /* IntLiteral.js */, >+ E92D0FE520F56DDD00D776B2 /* IntLiteralType.js */, >+ E92D0FE720F56DDD00D776B2 /* Intrinsics.js */, >+ E9D7CB9B214B82B700F1C918 /* LateCheckAndLayoutBuffers.js */, >+ E9FCEB6420F56DA5009B3629 /* LateChecker.js */, >+ E92D0FF120F56DEC00D776B2 /* Lexer.js */, >+ E92D0FF020F56DEB00D776B2 /* LexerToken.js */, >+ E92D0FF220F56DEC00D776B2 /* LiteralTypeChecker.js */, >+ E92D0FEE20F56DEB00D776B2 /* LogicalExpression.js */, >+ E92D0FEF20F56DEB00D776B2 /* LogicalNot.js */, >+ E92D0FFB20F56DFB00D776B2 /* LoopChecker.js */, >+ E92D0FFC20F56DFB00D776B2 /* MakeArrayRefExpression.js */, >+ E92D0FF920F56DFA00D776B2 /* MakePtrExpression.js */, >+ E921D6332138C02600775099 /* MatrixType.js */, >+ E9D7CB95214B824200F1C918 /* MSLBackend.js */, >+ E97ED7E5214B822900AD1140 /* MSLCodegenAll.js */, >+ E97ED7E8214B822900AD1140 /* MSLCompileResult.js */, >+ E9D7CB96214B824200F1C918 /* MSLConstexprEmitter.js */, >+ E92789AC213F3364001EA73E /* MSLFunctionDeclaration.js */, >+ E92789AB213F3364001EA73E /* MSLFunctionDefinition.js */, >+ E973E5C7213F3385005D79FC /* MSLFunctionForwardDeclaration.js */, >+ E97ED7E1214B822900AD1140 /* MSLNameMangler.js */, >+ E97ED7E4214B822900AD1140 /* MSLNativeFunctionCall.js */, >+ E973E5C8213F3385005D79FC /* MSLStatementEmitter.js */, >+ E97ED7E7214B822900AD1140 /* MSLTypeAttributes.js */, >+ E97ED7E2214B822900AD1140 /* MSLTypeAttributesMap.js */, >+ E973E5C4213F3385005D79FC /* MSLTypeNamer.js */, >+ E97ED7E6214B822900AD1140 /* MSLTypeUnifier.js */, >+ E97ED7E3214B822900AD1140 /* MSLVarDeclaration.js */, >+ E92D0FF820F56DFA00D776B2 /* NameContext.js */, >+ E92D0FFA20F56DFB00D776B2 /* NameFinder.js */, >+ E92D100320F56E0900D776B2 /* NameResolver.js */, >+ E92D100520F56E0900D776B2 /* NativeFunc.js */, >+ E92D100620F56E0900D776B2 /* NativeType.js */, >+ E92D100F20F56E1500D776B2 /* Node.js */, >+ E92D100D20F56E1500D776B2 /* NormalUsePropertyResolver.js */, >+ E92D100C20F56E1500D776B2 /* NullLiteral.js */, >+ E92D101020F56E1500D776B2 /* NullType.js */, >+ E921D6322138C02600775099 /* OperatorAnderIndexer.js */, >+ E941ACB62134A5BB00392BA9 /* OperatorArrayRefLength.js */, >+ E92D100E20F56E1500D776B2 /* OriginKind.js */, >+ E92D101920F56E2200D776B2 /* OverloadResolutionFailure.js */, >+ E92D101720F56E2200D776B2 /* Parse.js */, >+ E92D101820F56E2200D776B2 /* Prepare.js */, >+ E92D101A20F56E2200D776B2 /* Program.js */, >+ E92D101620F56E2100D776B2 /* ProgramWithUnnecessaryThingsRemoved.js */, >+ E92D102320F56E2F00D776B2 /* PropertyAccessExpression.js */, >+ E92D102020F56E2F00D776B2 /* PropertyResolver.js */, >+ E92D102B20F56E3F00D776B2 /* PtrType.js */, >+ E92D102A20F56E3F00D776B2 /* ReadModifyWriteExpression.js */, >+ E92D102C20F56E3F00D776B2 /* RecursionChecker.js */, >+ E92D102E20F56E4000D776B2 /* RecursiveTypeChecker.js */, >+ E92D103520F56E4F00D776B2 /* ReferenceType.js */, >+ E92D103420F56E4F00D776B2 /* ResolveNames.js */, >+ E92D103820F56E4F00D776B2 /* ResolveOverloadImpl.js */, >+ E92D103620F56E4F00D776B2 /* ResolveProperties.js */, >+ E92D103720F56E4F00D776B2 /* ResolveTypeDefs.js */, >+ E92D103E20F56E6100D776B2 /* Return.js */, >+ E92D104020F56E6200D776B2 /* ReturnChecker.js */, >+ E92D104220F56E6200D776B2 /* ReturnException.js */, >+ E92D104120F56E6200D776B2 /* Rewriter.js */, >+ E9D7CB9D214B82B800F1C918 /* Sampler.js */, >+ E92D103F20F56E6200D776B2 /* StandardLibrary.js */, >+ E92D104820F56E7300D776B2 /* StatementCloner.js */, >+ E92D104920F56E7300D776B2 /* StructLayoutBuilder.js */, >+ E92D104A20F56E7300D776B2 /* StructType.js */, >+ E92D104B20F56E7300D776B2 /* SwitchCase.js */, >+ E92D105220F56E8400D776B2 /* SwitchStatement.js */, >+ E941ACB72134A5BB00392BA9 /* SynthesizeArrayOperatorLength.js */, >+ E941ACAF2134A5BA00392BA9 /* SynthesizeCopyConstructorOperator.js */, >+ E941ACB32134A5BB00392BA9 /* SynthesizeDefaultConstructorOperator.js */, >+ E92D105420F56E8500D776B2 /* SynthesizeEnumFunctions.js */, >+ E92D105320F56E8400D776B2 /* SynthesizeStructAccessors.js */, >+ E941ACB52134A5BB00392BA9 /* TernaryExpression.js */, >+ E94D127E2114C6FF00B0F967 /* Test.js */, >+ E9D7CB9A214B82B700F1C918 /* Texture.js */, >+ E9D7CB9E214B82B800F1C918 /* TextureOperations.js */, >+ E92D105620F56E8500D776B2 /* TrapStatement.js */, >+ E92D105520F56E8500D776B2 /* Type.js */, >+ E92D105F20F56E9500D776B2 /* TypeDef.js */, >+ E92D105E20F56E9500D776B2 /* TypeDefResolver.js */, >+ E92D106020F56E9500D776B2 /* TypedValue.js */, >+ E92789B0213F3364001EA73E /* TypeOf.js */, >+ E941ACBA2134A5BB00392BA9 /* TypeOverloadResolutionFailure.js */, >+ E92D106620F56EA400D776B2 /* TypeRef.js */, >+ E92D106820F56EA400D776B2 /* UintLiteral.js */, >+ E92D106720F56EA400D776B2 /* UintLiteralType.js */, >+ E92D107220F56EBB00D776B2 /* UnificationContext.js */, >+ E92D107320F56EBC00D776B2 /* UnreachableCodeChecker.js */, >+ E92D107420F56EBC00D776B2 /* Value.js */, >+ E92D107020F56EBB00D776B2 /* VariableDecl.js */, >+ E92D107120F56EBB00D776B2 /* VariableRef.js */, >+ E941ACBB2134A5BB00392BA9 /* VectorType.js */, >+ E92D107C20F56ECF00D776B2 /* VisitingSet.js */, >+ E92D107A20F56ECF00D776B2 /* Visitor.js */, >+ E92D107D20F56ECF00D776B2 /* WhileLoop.js */, >+ E9D7CB94214B824200F1C918 /* WhlslToMsl.js */, >+ E9D7CB9F214B82B800F1C918 /* WLexicalError.js */, >+ E92D107B20F56ECF00D776B2 /* WrapChecker.js */, >+ E92D108220F56EDE00D776B2 /* WSyntaxError.js */, >+ E92D108420F56EDE00D776B2 /* WTrapError.js */, >+ E92D108320F56EDE00D776B2 /* WTypeError.js */, >+ ); >+ name = Scripts; >+ sourceTree = "<group>"; >+ }; >+ E9E11931211E614D0014D553 /* Metal equivalents */ = { >+ isa = PBXGroup; >+ children = ( >+ E9E11932211E61640014D553 /* Shaders.metal */, >+ ); >+ path = "Metal equivalents"; >+ sourceTree = "<group>"; >+ }; >+/* End PBXGroup section */ >+ >+/* Begin PBXNativeTarget section */ >+ E94C06BF20F56A4000672992 /* WHLSL Tests */ = { >+ isa = PBXNativeTarget; >+ buildConfigurationList = E94C06EA20F56A4200672992 /* Build configuration list for PBXNativeTarget "WHLSL Tests" */; >+ buildPhases = ( >+ E925653C21234AA1001A89D9 /* ShellScript */, >+ E94C06BC20F56A4000672992 /* Sources */, >+ E94C06BD20F56A4000672992 /* Frameworks */, >+ E94C06BE20F56A4000672992 /* Resources */, >+ ); >+ buildRules = ( >+ ); >+ dependencies = ( >+ ); >+ name = "WHLSL Tests"; >+ productName = "WHLSL Toy"; >+ productReference = E94C06C020F56A4000672992 /* WHLSL Tests.app */; >+ productType = "com.apple.product-type.application"; >+ }; >+ E94C06D520F56A4200672992 /* WHLSL TestsTests */ = { >+ isa = PBXNativeTarget; >+ buildConfigurationList = E94C06ED20F56A4200672992 /* Build configuration list for PBXNativeTarget "WHLSL TestsTests" */; >+ buildPhases = ( >+ E94C06D220F56A4200672992 /* Sources */, >+ E94C06D320F56A4200672992 /* Frameworks */, >+ E94C06D420F56A4200672992 /* Resources */, >+ ); >+ buildRules = ( >+ ); >+ dependencies = ( >+ E94C06D820F56A4200672992 /* PBXTargetDependency */, >+ ); >+ name = "WHLSL TestsTests"; >+ productName = "WHLSL ToyTests"; >+ productReference = E94C06D620F56A4200672992 /* WHLSL TestsTests.xctest */; >+ productType = "com.apple.product-type.bundle.unit-test"; >+ }; >+/* End PBXNativeTarget section */ >+ >+/* Begin PBXProject section */ >+ E94C06B820F56A4000672992 /* Project object */ = { >+ isa = PBXProject; >+ attributes = { >+ LastUpgradeCheck = 1000; >+ ORGANIZATIONNAME = "Apple, Inc."; >+ TargetAttributes = { >+ E94C06BF20F56A4000672992 = { >+ CreatedOnToolsVersion = 10.0; >+ }; >+ E94C06D520F56A4200672992 = { >+ CreatedOnToolsVersion = 10.0; >+ TestTargetID = E94C06BF20F56A4000672992; >+ }; >+ }; >+ }; >+ buildConfigurationList = E94C06BB20F56A4000672992 /* Build configuration list for PBXProject "WHLSL Tests" */; >+ compatibilityVersion = "Xcode 9.3"; >+ developmentRegion = en; >+ hasScannedForEncodings = 0; >+ knownRegions = ( >+ en, >+ Base, >+ ); >+ mainGroup = E94C06B720F56A4000672992; >+ productRefGroup = E94C06C120F56A4000672992 /* Products */; >+ projectDirPath = ""; >+ projectRoot = ""; >+ targets = ( >+ E94C06BF20F56A4000672992 /* WHLSL Tests */, >+ E94C06D520F56A4200672992 /* WHLSL TestsTests */, >+ ); >+ }; >+/* End PBXProject section */ >+ >+/* Begin PBXResourcesBuildPhase section */ >+ E94C06BE20F56A4000672992 /* Resources */ = { >+ isa = PBXResourcesBuildPhase; >+ buildActionMask = 2147483647; >+ files = ( >+ E92EE00C211554980042F960 /* _SharedMetal.txt in Resources */, >+ E92D111620F7060E00D776B2 /* AddressSpace.js in Resources */, >+ E92D111720F7060E00D776B2 /* All.js in Resources */, >+ E92D111820F7060E00D776B2 /* AnonymousVariable.js in Resources */, >+ E92D111920F7060E00D776B2 /* ArrayRefType.js in Resources */, >+ E92D111A20F7060E00D776B2 /* ArrayType.js in Resources */, >+ E94C06CA20F56A4200672992 /* Assets.xcassets in Resources */, >+ E92D111B20F7060E00D776B2 /* Assignment.js in Resources */, >+ E92D111C20F7060E00D776B2 /* AutoWrapper.js in Resources */, >+ E92D111D20F7060E00D776B2 /* Block.js in Resources */, >+ E92D111E20F7060E00D776B2 /* BoolLiteral.js in Resources */, >+ E92D111F20F7060E00D776B2 /* Break.js in Resources */, >+ E921D6382138C02600775099 /* BuiltinMatrixGetter.js in Resources */, >+ E921D6392138C02600775099 /* BuiltinMatrixSetter.js in Resources */, >+ E941ACCA2134A5BC00392BA9 /* BuiltinVectorGetter.js in Resources */, >+ E941ACCD2134A5BC00392BA9 /* BuiltinVectorSetter.js in Resources */, >+ E92D112020F7060E00D776B2 /* CallExpression.js in Resources */, >+ E92D112120F7060E00D776B2 /* CallFunction.js in Resources */, >+ E9D7CBA2214B82B800F1C918 /* Casts.js in Resources */, >+ E92D112220F7060E00D776B2 /* Check.js in Resources */, >+ E92D112320F7060E00D776B2 /* Checker.js in Resources */, >+ E92D112420F7060E00D776B2 /* CheckLiteralTypes.js in Resources */, >+ E92D112520F7060E00D776B2 /* CheckLoops.js in Resources */, >+ E92D112620F7060E00D776B2 /* CheckRecursion.js in Resources */, >+ E92D112720F7060E00D776B2 /* CheckRecursiveTypes.js in Resources */, >+ E92D112820F7060E00D776B2 /* CheckReturns.js in Resources */, >+ E941ACBF2134A5BC00392BA9 /* CheckTypesWithArguments.js in Resources */, >+ E92D112920F7060E00D776B2 /* CheckUnreachableCode.js in Resources */, >+ E92D112A20F7060E00D776B2 /* CheckWrapped.js in Resources */, >+ E92D112B20F7060E00D776B2 /* CloneProgram.js in Resources */, >+ E92D112C20F7060E00D776B2 /* CommaExpression.js in Resources */, >+ E92D112E20F7060E00D776B2 /* ConstexprFolder.js in Resources */, >+ E92D113020F7060E00D776B2 /* Continue.js in Resources */, >+ E92D113120F7060E00D776B2 /* ConvertPtrToArrayRefExpression.js in Resources */, >+ E92D113220F7060E00D776B2 /* CreateLiteral.js in Resources */, >+ E92D113320F7060E00D776B2 /* CreateLiteralType.js in Resources */, >+ E92D109320F5734900D776B2 /* Default.whlsl in Resources */, >+ E92D113420F7060E00D776B2 /* DereferenceExpression.js in Resources */, >+ E92D113520F7060E00D776B2 /* DotExpression.js in Resources */, >+ E92D113820F7060E00D776B2 /* DoWhileLoop.js in Resources */, >+ E92D113920F7060E00D776B2 /* EArrayRef.js in Resources */, >+ E92D113A20F7060E00D776B2 /* EBuffer.js in Resources */, >+ E92D113B20F7060E00D776B2 /* EBufferBuilder.js in Resources */, >+ E92D113C20F7060E00D776B2 /* EnumLiteral.js in Resources */, >+ E92D113D20F7060E00D776B2 /* EnumMember.js in Resources */, >+ E92D113E20F7060E00D776B2 /* EnumType.js in Resources */, >+ E92D113F20F7060E00D776B2 /* EPtr.js in Resources */, >+ E92D114020F7060E00D776B2 /* EvaluationCommon.js in Resources */, >+ E92D114120F7060E00D776B2 /* Evaluator.js in Resources */, >+ E92D114220F7060E00D776B2 /* Expression.js in Resources */, >+ E92D114320F7060E00D776B2 /* ExpressionFinder.js in Resources */, >+ E92D114420F7060E00D776B2 /* ExternalOrigin.js in Resources */, >+ E92D114520F7060E00D776B2 /* Field.js in Resources */, >+ E92D114620F7060E00D776B2 /* FindHighZombies.js in Resources */, >+ E92D114720F7060E00D776B2 /* FlattenedStructOffsetGatherer.js in Resources */, >+ E92D114920F7060E00D776B2 /* FloatLiteral.js in Resources */, >+ E92D114A20F7060E00D776B2 /* FloatLiteralType.js in Resources */, >+ E92D114B20F7060E00D776B2 /* FoldConstexprs.js in Resources */, >+ E92D114C20F7060E00D776B2 /* ForLoop.js in Resources */, >+ E92D114D20F7060E00D776B2 /* Func.js in Resources */, >+ E92D114E20F7060E00D776B2 /* FuncDef.js in Resources */, >+ E92D115020F7060E00D776B2 /* FuncParameter.js in Resources */, >+ E92D115120F7060E00D776B2 /* FunctionLikeBlock.js in Resources */, >+ E92D115220F7060E00D776B2 /* HighZombieFinder.js in Resources */, >+ E92D115320F7060E00D776B2 /* IdentityExpression.js in Resources */, >+ E92D115420F7060E00D776B2 /* IfStatement.js in Resources */, >+ E92D115520F7060E00D776B2 /* IndexExpression.js in Resources */, >+ E92D115620F7060E00D776B2 /* InferTypesForCall.js in Resources */, >+ E92D115720F7060E00D776B2 /* Inline.js in Resources */, >+ E92D115820F7060E00D776B2 /* Inliner.js in Resources */, >+ E92D115A20F7060E00D776B2 /* IntLiteral.js in Resources */, >+ E92D115B20F7060E00D776B2 /* IntLiteralType.js in Resources */, >+ E92D115C20F7060E00D776B2 /* Intrinsics.js in Resources */, >+ E906B04621139B7700AD1C5E /* Julia.whlsl in Resources */, >+ E9D7CBA1214B82B800F1C918 /* LateCheckAndLayoutBuffers.js in Resources */, >+ E92D115D20F7060E00D776B2 /* LateChecker.js in Resources */, >+ E92D115E20F7060E00D776B2 /* Lexer.js in Resources */, >+ E92D115F20F7060E00D776B2 /* LexerToken.js in Resources */, >+ E92D116020F7060E00D776B2 /* LiteralTypeChecker.js in Resources */, >+ E92D116120F7060E00D776B2 /* LogicalExpression.js in Resources */, >+ E92D116220F7060E00D776B2 /* LogicalNot.js in Resources */, >+ E92D116320F7060E00D776B2 /* LoopChecker.js in Resources */, >+ E92EE000211546AB0042F960 /* Main.storyboard in Resources */, >+ E92D116420F7060E00D776B2 /* MakeArrayRefExpression.js in Resources */, >+ E92D116520F7060E00D776B2 /* MakePtrExpression.js in Resources */, >+ E94D124F2114BD7600B0F967 /* Mandelbrot.whlsl in Resources */, >+ E921D6372138C02600775099 /* MatrixType.js in Resources */, >+ E9D7CB98214B824200F1C918 /* MSLBackend.js in Resources */, >+ E9D7CBA6214B9E5F00F1C918 /* MSLCodegenAll.js in Resources */, >+ E9D7CBA7214B9E5F00F1C918 /* MSLCompileResult.js in Resources */, >+ E9D7CB99214B824200F1C918 /* MSLConstexprEmitter.js in Resources */, >+ E973E5DE213F341D005D79FC /* MSLFunctionDeclaration.js in Resources */, >+ E973E5DF213F341D005D79FC /* MSLFunctionDefinition.js in Resources */, >+ E973E5CE213F3385005D79FC /* MSLFunctionForwardDeclaration.js in Resources */, >+ E9D7CBA8214B9E5F00F1C918 /* MSLNameMangler.js in Resources */, >+ E9D7CBA9214B9E5F00F1C918 /* MSLNativeFunctionCall.js in Resources */, >+ E973E5CF213F3385005D79FC /* MSLStatementEmitter.js in Resources */, >+ E9D7CBAA214B9E5F00F1C918 /* MSLTypeAttributes.js in Resources */, >+ E9D7CBAB214B9E5F00F1C918 /* MSLTypeAttributesMap.js in Resources */, >+ E973E5CB213F3385005D79FC /* MSLTypeNamer.js in Resources */, >+ E9D7CBAC214B9E5F00F1C918 /* MSLTypeUnifier.js in Resources */, >+ E9D7CBAD214B9E5F00F1C918 /* MSLVarDeclaration.js in Resources */, >+ E92D116620F7060E00D776B2 /* NameContext.js in Resources */, >+ E92D116720F7060E00D776B2 /* NameFinder.js in Resources */, >+ E92D116820F7060E00D776B2 /* NameResolver.js in Resources */, >+ E92D116920F7060E00D776B2 /* NativeFunc.js in Resources */, >+ E92D116B20F7060E00D776B2 /* NativeType.js in Resources */, >+ E92D116D20F7060E00D776B2 /* Node.js in Resources */, >+ E92D116E20F7060E00D776B2 /* NormalUsePropertyResolver.js in Resources */, >+ E92D116F20F7060E00D776B2 /* NullLiteral.js in Resources */, >+ E92D117020F7060E00D776B2 /* NullType.js in Resources */, >+ E921D6362138C02600775099 /* OperatorAnderIndexer.js in Resources */, >+ E941ACC72134A5BC00392BA9 /* OperatorArrayRefLength.js in Resources */, >+ E92D117120F7060E00D776B2 /* OriginKind.js in Resources */, >+ E92D117220F7060E00D776B2 /* OverloadResolutionFailure.js in Resources */, >+ E92D117320F7060E00D776B2 /* Parse.js in Resources */, >+ E92D117420F7060E00D776B2 /* Prepare.js in Resources */, >+ E92D117520F7060E00D776B2 /* Program.js in Resources */, >+ E92D117620F7060E00D776B2 /* ProgramWithUnnecessaryThingsRemoved.js in Resources */, >+ E92D117720F7060E00D776B2 /* PropertyAccessExpression.js in Resources */, >+ E92D117820F7060E00D776B2 /* PropertyResolver.js in Resources */, >+ E92D117D20F7060E00D776B2 /* PtrType.js in Resources */, >+ E92D117E20F7060E00D776B2 /* ReadModifyWriteExpression.js in Resources */, >+ E92D117F20F7060E00D776B2 /* RecursionChecker.js in Resources */, >+ E92D118020F7060E00D776B2 /* RecursiveTypeChecker.js in Resources */, >+ E92D118120F7060E00D776B2 /* ReferenceType.js in Resources */, >+ E92D118220F7060E00D776B2 /* ResolveNames.js in Resources */, >+ E92D118320F7060E00D776B2 /* ResolveOverloadImpl.js in Resources */, >+ E92D118420F7060E00D776B2 /* ResolveProperties.js in Resources */, >+ E92D118520F7060E00D776B2 /* ResolveTypeDefs.js in Resources */, >+ E92D118620F7060E00D776B2 /* Return.js in Resources */, >+ E92D118720F7060E00D776B2 /* ReturnChecker.js in Resources */, >+ E92D118820F7060E00D776B2 /* ReturnException.js in Resources */, >+ E92D118920F7060E00D776B2 /* Rewriter.js in Resources */, >+ E9D7CBA3214B82B800F1C918 /* Sampler.js in Resources */, >+ E92D118A20F7060E00D776B2 /* StandardLibrary.js in Resources */, >+ E92D118B20F7060E00D776B2 /* StatementCloner.js in Resources */, >+ E92D118C20F7060E00D776B2 /* StructLayoutBuilder.js in Resources */, >+ E92D118D20F7060E00D776B2 /* StructType.js in Resources */, >+ E92D118F20F7060E00D776B2 /* SwitchCase.js in Resources */, >+ E92D119020F7060E00D776B2 /* SwitchStatement.js in Resources */, >+ E941ACC82134A5BC00392BA9 /* SynthesizeArrayOperatorLength.js in Resources */, >+ E941ACC02134A5BC00392BA9 /* SynthesizeCopyConstructorOperator.js in Resources */, >+ E941ACC42134A5BC00392BA9 /* SynthesizeDefaultConstructorOperator.js in Resources */, >+ E92D119120F7060E00D776B2 /* SynthesizeEnumFunctions.js in Resources */, >+ E92D119220F7060E00D776B2 /* SynthesizeStructAccessors.js in Resources */, >+ E941ACC62134A5BC00392BA9 /* TernaryExpression.js in Resources */, >+ E94D127F2114C6FF00B0F967 /* Test.js in Resources */, >+ E9D7CBA0214B82B800F1C918 /* Texture.js in Resources */, >+ E9D7CBA4214B82B800F1C918 /* TextureOperations.js in Resources */, >+ E92D119320F7060E00D776B2 /* TrapStatement.js in Resources */, >+ E92D119420F7060E00D776B2 /* Type.js in Resources */, >+ E92D119520F7060E00D776B2 /* TypeDef.js in Resources */, >+ E92D119620F7060E00D776B2 /* TypeDefResolver.js in Resources */, >+ E92D119720F7060E00D776B2 /* TypedValue.js in Resources */, >+ E973E5E3213F341D005D79FC /* TypeOf.js in Resources */, >+ E941ACCB2134A5BC00392BA9 /* TypeOverloadResolutionFailure.js in Resources */, >+ E92D119A20F7060E00D776B2 /* TypeRef.js in Resources */, >+ E92D119D20F7060E00D776B2 /* UintLiteral.js in Resources */, >+ E92D119E20F7060E00D776B2 /* UintLiteralType.js in Resources */, >+ E92D119F20F7060E00D776B2 /* UnificationContext.js in Resources */, >+ E92D11A020F7060E00D776B2 /* UnreachableCodeChecker.js in Resources */, >+ E92D11A120F7060E00D776B2 /* Value.js in Resources */, >+ E92D11A220F7060E00D776B2 /* VariableDecl.js in Resources */, >+ E92D11A320F7060E00D776B2 /* VariableRef.js in Resources */, >+ E941ACCC2134A5BC00392BA9 /* VectorType.js in Resources */, >+ E92D11A420F7060E00D776B2 /* VisitingSet.js in Resources */, >+ E92D11A520F7060E00D776B2 /* Visitor.js in Resources */, >+ E92D11A620F7060E00D776B2 /* WhileLoop.js in Resources */, >+ E9D7CB97214B824200F1C918 /* WhlslToMsl.js in Resources */, >+ E9D7CBA5214B82B800F1C918 /* WLexicalError.js in Resources */, >+ E92D11A720F7060E00D776B2 /* WrapChecker.js in Resources */, >+ E92D11A820F7060E00D776B2 /* WSyntaxError.js in Resources */, >+ E92D11A920F7060E00D776B2 /* WTrapError.js in Resources */, >+ E92D11AA20F7060E00D776B2 /* WTypeError.js in Resources */, >+ ); >+ runOnlyForDeploymentPostprocessing = 0; >+ }; >+ E94C06D420F56A4200672992 /* Resources */ = { >+ isa = PBXResourcesBuildPhase; >+ buildActionMask = 2147483647; >+ files = ( >+ ); >+ runOnlyForDeploymentPostprocessing = 0; >+ }; >+/* End PBXResourcesBuildPhase section */ >+ >+/* Begin PBXShellScriptBuildPhase section */ >+ E925653C21234AA1001A89D9 /* ShellScript */ = { >+ isa = PBXShellScriptBuildPhase; >+ buildActionMask = 2147483647; >+ files = ( >+ ); >+ inputFileListPaths = ( >+ ); >+ inputPaths = ( >+ ); >+ outputFileListPaths = ( >+ ); >+ outputPaths = ( >+ ); >+ runOnlyForDeploymentPostprocessing = 0; >+ shellPath = /bin/sh; >+ shellScript = "# Type a script or drag a script file from your workspace to insert its path.\ncd \"$SRCROOT/..\"\ntsc\n"; >+ }; >+/* End PBXShellScriptBuildPhase section */ >+ >+/* Begin PBXSourcesBuildPhase section */ >+ E94C06BC20F56A4000672992 /* Sources */ = { >+ isa = PBXSourcesBuildPhase; >+ buildActionMask = 2147483647; >+ files = ( >+ E92EDFFC211546A40042F960 /* AppDelegate.m in Sources */, >+ E92D108A20F56F0600D776B2 /* Compiler.m in Sources */, >+ E92D11BB20F7F67300D776B2 /* CompileResult.m in Sources */, >+ E92EDFFB211546A40042F960 /* CustomMetalView.m in Sources */, >+ E94C06D020F56A4200672992 /* main.m in Sources */, >+ E92D11AD20F7081500D776B2 /* OffscreenRenderer.m in Sources */, >+ E92D10AF20F57C9F00D776B2 /* OnscreenRenderer.m in Sources */, >+ E92D111520F6FFB600D776B2 /* Renderer.m in Sources */, >+ E9E11933211E61640014D553 /* Shaders.metal in Sources */, >+ E92EE004211549C50042F960 /* TestCallArgument.m in Sources */, >+ E92EE00A21154B5A0042F960 /* TestDescription.m in Sources */, >+ E92EE00721154AC40042F960 /* TestFamily.m in Sources */, >+ E92EE00F211563300042F960 /* TestFamilyRunner.m in Sources */, >+ E92EDFFD211546A40042F960 /* ViewController.m in Sources */, >+ ); >+ runOnlyForDeploymentPostprocessing = 0; >+ }; >+ E94C06D220F56A4200672992 /* Sources */ = { >+ isa = PBXSourcesBuildPhase; >+ buildActionMask = 2147483647; >+ files = ( >+ E94C06DB20F56A4200672992 /* WHLSL_ToyTests.m in Sources */, >+ ); >+ runOnlyForDeploymentPostprocessing = 0; >+ }; >+/* End PBXSourcesBuildPhase section */ >+ >+/* Begin PBXTargetDependency section */ >+ E94C06D820F56A4200672992 /* PBXTargetDependency */ = { >+ isa = PBXTargetDependency; >+ target = E94C06BF20F56A4000672992 /* WHLSL Tests */; >+ targetProxy = E94C06D720F56A4200672992 /* PBXContainerItemProxy */; >+ }; >+/* End PBXTargetDependency section */ >+ >+/* Begin PBXVariantGroup section */ >+ E92EDFFE211546AB0042F960 /* Main.storyboard */ = { >+ isa = PBXVariantGroup; >+ children = ( >+ E92EDFFF211546AB0042F960 /* Base */, >+ ); >+ name = Main.storyboard; >+ sourceTree = "<group>"; >+ }; >+/* End PBXVariantGroup section */ >+ >+/* Begin XCBuildConfiguration section */ >+ E94C06E820F56A4200672992 /* Debug */ = { >+ isa = XCBuildConfiguration; >+ buildSettings = { >+ ALWAYS_SEARCH_USER_PATHS = NO; >+ CLANG_ANALYZER_NONNULL = YES; >+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; >+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; >+ CLANG_CXX_LIBRARY = "libc++"; >+ CLANG_ENABLE_MODULES = YES; >+ CLANG_ENABLE_OBJC_ARC = YES; >+ CLANG_ENABLE_OBJC_WEAK = YES; >+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; >+ CLANG_WARN_BOOL_CONVERSION = YES; >+ CLANG_WARN_COMMA = YES; >+ CLANG_WARN_CONSTANT_CONVERSION = YES; >+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; >+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; >+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES; >+ CLANG_WARN_EMPTY_BODY = YES; >+ CLANG_WARN_ENUM_CONVERSION = YES; >+ CLANG_WARN_INFINITE_RECURSION = YES; >+ CLANG_WARN_INT_CONVERSION = YES; >+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; >+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; >+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; >+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; >+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; >+ CLANG_WARN_STRICT_PROTOTYPES = YES; >+ CLANG_WARN_SUSPICIOUS_MOVE = YES; >+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; >+ CLANG_WARN_UNREACHABLE_CODE = YES; >+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; >+ CODE_SIGN_IDENTITY = "Mac Developer"; >+ COPY_PHASE_STRIP = NO; >+ DEBUG_INFORMATION_FORMAT = dwarf; >+ ENABLE_STRICT_OBJC_MSGSEND = YES; >+ ENABLE_TESTABILITY = YES; >+ GCC_C_LANGUAGE_STANDARD = gnu11; >+ GCC_DYNAMIC_NO_PIC = NO; >+ GCC_NO_COMMON_BLOCKS = YES; >+ GCC_OPTIMIZATION_LEVEL = 0; >+ GCC_PREPROCESSOR_DEFINITIONS = ( >+ "DEBUG=1", >+ "$(inherited)", >+ ); >+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES; >+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; >+ GCC_WARN_UNDECLARED_SELECTOR = YES; >+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; >+ GCC_WARN_UNUSED_FUNCTION = YES; >+ GCC_WARN_UNUSED_VARIABLE = YES; >+ MACOSX_DEPLOYMENT_TARGET = 10.14; >+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; >+ ONLY_ACTIVE_ARCH = YES; >+ SDKROOT = macosx; >+ }; >+ name = Debug; >+ }; >+ E94C06E920F56A4200672992 /* Release */ = { >+ isa = XCBuildConfiguration; >+ buildSettings = { >+ ALWAYS_SEARCH_USER_PATHS = NO; >+ CLANG_ANALYZER_NONNULL = YES; >+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; >+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; >+ CLANG_CXX_LIBRARY = "libc++"; >+ CLANG_ENABLE_MODULES = YES; >+ CLANG_ENABLE_OBJC_ARC = YES; >+ CLANG_ENABLE_OBJC_WEAK = YES; >+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; >+ CLANG_WARN_BOOL_CONVERSION = YES; >+ CLANG_WARN_COMMA = YES; >+ CLANG_WARN_CONSTANT_CONVERSION = YES; >+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; >+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; >+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES; >+ CLANG_WARN_EMPTY_BODY = YES; >+ CLANG_WARN_ENUM_CONVERSION = YES; >+ CLANG_WARN_INFINITE_RECURSION = YES; >+ CLANG_WARN_INT_CONVERSION = YES; >+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; >+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; >+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; >+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; >+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; >+ CLANG_WARN_STRICT_PROTOTYPES = YES; >+ CLANG_WARN_SUSPICIOUS_MOVE = YES; >+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; >+ CLANG_WARN_UNREACHABLE_CODE = YES; >+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; >+ CODE_SIGN_IDENTITY = "Mac Developer"; >+ COPY_PHASE_STRIP = NO; >+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; >+ ENABLE_NS_ASSERTIONS = NO; >+ ENABLE_STRICT_OBJC_MSGSEND = YES; >+ GCC_C_LANGUAGE_STANDARD = gnu11; >+ GCC_NO_COMMON_BLOCKS = YES; >+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES; >+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; >+ GCC_WARN_UNDECLARED_SELECTOR = YES; >+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; >+ GCC_WARN_UNUSED_FUNCTION = YES; >+ GCC_WARN_UNUSED_VARIABLE = YES; >+ MACOSX_DEPLOYMENT_TARGET = 10.14; >+ MTL_ENABLE_DEBUG_INFO = NO; >+ SDKROOT = macosx; >+ }; >+ name = Release; >+ }; >+ E94C06EB20F56A4200672992 /* Debug */ = { >+ isa = XCBuildConfiguration; >+ buildSettings = { >+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; >+ CODE_SIGN_ENTITLEMENTS = Core/WHLSL.entitlements; >+ CODE_SIGN_IDENTITY = "-"; >+ CODE_SIGN_STYLE = Automatic; >+ COMBINE_HIDPI_IMAGES = YES; >+ DEVELOPMENT_TEAM = ""; >+ INFOPLIST_FILE = Core/Info.plist; >+ LD_RUNPATH_SEARCH_PATHS = ( >+ "$(inherited)", >+ "@executable_path/../Frameworks", >+ ); >+ PRODUCT_BUNDLE_IDENTIFIER = "com.apple.WHLSL-Toy"; >+ PRODUCT_NAME = "$(TARGET_NAME)"; >+ }; >+ name = Debug; >+ }; >+ E94C06EC20F56A4200672992 /* Release */ = { >+ isa = XCBuildConfiguration; >+ buildSettings = { >+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; >+ CODE_SIGN_ENTITLEMENTS = Core/WHLSL.entitlements; >+ CODE_SIGN_IDENTITY = "-"; >+ CODE_SIGN_STYLE = Automatic; >+ COMBINE_HIDPI_IMAGES = YES; >+ DEVELOPMENT_TEAM = ""; >+ INFOPLIST_FILE = Core/Info.plist; >+ LD_RUNPATH_SEARCH_PATHS = ( >+ "$(inherited)", >+ "@executable_path/../Frameworks", >+ ); >+ PRODUCT_BUNDLE_IDENTIFIER = "com.apple.WHLSL-Toy"; >+ PRODUCT_NAME = "$(TARGET_NAME)"; >+ }; >+ name = Release; >+ }; >+ E94C06EE20F56A4200672992 /* Debug */ = { >+ isa = XCBuildConfiguration; >+ buildSettings = { >+ BUNDLE_LOADER = "$(TEST_HOST)"; >+ CODE_SIGN_IDENTITY = "-"; >+ CODE_SIGN_STYLE = Automatic; >+ COMBINE_HIDPI_IMAGES = YES; >+ DEVELOPMENT_TEAM = ""; >+ INFOPLIST_FILE = "WHLSL ToyTests/Info.plist"; >+ LD_RUNPATH_SEARCH_PATHS = ( >+ "$(inherited)", >+ "@executable_path/../Frameworks", >+ "@loader_path/../Frameworks", >+ ); >+ PRODUCT_BUNDLE_IDENTIFIER = "com.apple.WHLSL-ToyTests"; >+ PRODUCT_NAME = "$(TARGET_NAME)"; >+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/WHLSL Tests.app/Contents/MacOS/WHLSL Tests"; >+ }; >+ name = Debug; >+ }; >+ E94C06EF20F56A4200672992 /* Release */ = { >+ isa = XCBuildConfiguration; >+ buildSettings = { >+ BUNDLE_LOADER = "$(TEST_HOST)"; >+ CODE_SIGN_IDENTITY = "-"; >+ CODE_SIGN_STYLE = Automatic; >+ COMBINE_HIDPI_IMAGES = YES; >+ DEVELOPMENT_TEAM = ""; >+ INFOPLIST_FILE = "WHLSL ToyTests/Info.plist"; >+ LD_RUNPATH_SEARCH_PATHS = ( >+ "$(inherited)", >+ "@executable_path/../Frameworks", >+ "@loader_path/../Frameworks", >+ ); >+ PRODUCT_BUNDLE_IDENTIFIER = "com.apple.WHLSL-ToyTests"; >+ PRODUCT_NAME = "$(TARGET_NAME)"; >+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/WHLSL Tests.app/Contents/MacOS/WHLSL Tests"; >+ }; >+ name = Release; >+ }; >+/* End XCBuildConfiguration section */ >+ >+/* Begin XCConfigurationList section */ >+ E94C06BB20F56A4000672992 /* Build configuration list for PBXProject "WHLSL Tests" */ = { >+ isa = XCConfigurationList; >+ buildConfigurations = ( >+ E94C06E820F56A4200672992 /* Debug */, >+ E94C06E920F56A4200672992 /* Release */, >+ ); >+ defaultConfigurationIsVisible = 0; >+ defaultConfigurationName = Release; >+ }; >+ E94C06EA20F56A4200672992 /* Build configuration list for PBXNativeTarget "WHLSL Tests" */ = { >+ isa = XCConfigurationList; >+ buildConfigurations = ( >+ E94C06EB20F56A4200672992 /* Debug */, >+ E94C06EC20F56A4200672992 /* Release */, >+ ); >+ defaultConfigurationIsVisible = 0; >+ defaultConfigurationName = Release; >+ }; >+ E94C06ED20F56A4200672992 /* Build configuration list for PBXNativeTarget "WHLSL TestsTests" */ = { >+ isa = XCConfigurationList; >+ buildConfigurations = ( >+ E94C06EE20F56A4200672992 /* Debug */, >+ E94C06EF20F56A4200672992 /* Release */, >+ ); >+ defaultConfigurationIsVisible = 0; >+ defaultConfigurationName = Release; >+ }; >+/* End XCConfigurationList section */ >+ }; >+ rootObject = E94C06B820F56A4000672992 /* Project object */; >+} >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/WHLSL ToyTests/Info.plist b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/WHLSL ToyTests/Info.plist >new file mode 100644 >index 0000000000000000000000000000000000000000..6c40a6cd0c4af2f0d93b697fbfb066793681b045 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/WHLSL ToyTests/Info.plist >@@ -0,0 +1,22 @@ >+<?xml version="1.0" encoding="UTF-8"?> >+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> >+<plist version="1.0"> >+<dict> >+ <key>CFBundleDevelopmentRegion</key> >+ <string>$(DEVELOPMENT_LANGUAGE)</string> >+ <key>CFBundleExecutable</key> >+ <string>$(EXECUTABLE_NAME)</string> >+ <key>CFBundleIdentifier</key> >+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> >+ <key>CFBundleInfoDictionaryVersion</key> >+ <string>6.0</string> >+ <key>CFBundleName</key> >+ <string>$(PRODUCT_NAME)</string> >+ <key>CFBundlePackageType</key> >+ <string>BNDL</string> >+ <key>CFBundleShortVersionString</key> >+ <string>1.0</string> >+ <key>CFBundleVersion</key> >+ <string>1</string> >+</dict> >+</plist> >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/WHLSL ToyTests/WHLSL_ToyTests.m b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/WHLSL ToyTests/WHLSL_ToyTests.m >new file mode 100644 >index 0000000000000000000000000000000000000000..555305078c63b7512c4f6e5757f29eb81d689a44 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/WHLSL ToyTests/WHLSL_ToyTests.m >@@ -0,0 +1,65 @@ >+// >+// WHLSL_ToyTests.m >+// WHLSL ToyTests >+// >+// Created by Thomas Denney on 7/10/18. >+// Copyright © 2018 Apple, Inc. All rights reserved. >+// >+ >+#import <XCTest/XCTest.h> >+ >+#import "TestFamily.h" >+#import "TestFamilyRunner.h" >+ >+/// The actual implementation of tests is in Test.h/m >+@interface WHLSLShaderTest : XCTestCase >+ >+@end >+ >+@implementation WHLSLShaderTest >+ >++ (WHLSLShaderTest*)testCaseInstanceFromImplementation:(TestFamily*)test >+{ >+ NSMethodSignature *testSignature = [WHLSLShaderTest instanceMethodSignatureForSelector:@selector(testShaderCompilationAndExecution:)]; >+ NSInvocation *testInvocation = [NSInvocation invocationWithMethodSignature:testSignature]; >+ testInvocation.selector = @selector(testShaderCompilationAndExecution:); >+ [testInvocation setArgument:&test atIndex:2]; >+ [testInvocation retainArguments]; >+ >+ WHLSLShaderTest *testCase = [[WHLSLShaderTest alloc] initWithInvocation:testInvocation]; >+ return testCase; >+} >+ >+- (void)testShaderCompilationAndExecution:(TestFamily*)test { >+ TestFamilyRunner* runner = [[TestFamilyRunner alloc] initWithTestFamily:test]; >+ BOOL result = [runner executeAllTests]; >+ if (result) >+ NSLog(@"\u2705 %@", test.name); >+ XCTAssert(result, @"%@", test.name); >+ NSLog(@"Total test case count: %lu", [TestFamilyRunner executionCount]); >+} >+ >+@end >+ >+@interface WHLSL_ToyTests : XCTestCase >+ >+@end >+ >+@implementation WHLSL_ToyTests >+ >++ (XCTestSuite*)defaultTestSuite >+{ >+ XCTestSuite* suite = [XCTestSuite testSuiteWithName:@"WHLSL tests"]; >+ NSArray<TestFamily*>* testDescriptions = [TestFamily allTests]; >+ NSRegularExpression* testFilter = [NSRegularExpression regularExpressionWithPattern:@".*" options:0 error:nil]; >+ for (TestFamily* test in testDescriptions) { >+ if ([testFilter firstMatchInString:test.name options:0 range:NSMakeRange(0, test.name.length)]) >+ [suite addTest:[WHLSLShaderTest testCaseInstanceFromImplementation:test]]; >+ } >+ >+ NSLog(@"Will execute %ld tests", suite.tests.count); >+ >+ return suite; >+} >+ >+@end >diff --git a/Tools/WebGPUShadingLanguageRI/Metal/WhlslToMsl.js b/Tools/WebGPUShadingLanguageRI/Metal/WhlslToMsl.js >new file mode 100644 >index 0000000000000000000000000000000000000000..5c85f2b49b2e3920a281f4e7278f21fc1ff4103f >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/Metal/WhlslToMsl.js >@@ -0,0 +1,41 @@ >+/* >+ * Copyright (C) 2018 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. ``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 >+ * 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. >+ */ >+ >+// Main wrapper for the compiler. Clients should use this function to compile WHLSL. >+function whlslToMsl(src) >+{ >+ let parsedProgram; >+ try { >+ parsedProgram = prepare("/internal/test", 0, src); >+ } catch (e) { >+ return new MSLCompileResult(null, e, null, null); >+ } >+ >+ if (!(parsedProgram instanceof Program)) >+ return new MSLCompileResult(null, new Error("Compilation failed"), null, null); >+ >+ const compiler = new MSLBackend(parsedProgram); >+ return compiler.compile(); >+} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/PropertyResolver.js b/Tools/WebGPUShadingLanguageRI/PropertyResolver.js >index b5c454ac2dc3d534ca5213ef13c3736cd1700344..23184ca5ad2f3aab46416a56adfcbe084ef39b5c 100644 >--- a/Tools/WebGPUShadingLanguageRI/PropertyResolver.js >+++ b/Tools/WebGPUShadingLanguageRI/PropertyResolver.js >@@ -168,6 +168,8 @@ class PropertyResolver extends Visitor { > super.visitMakePtrExpression(node); > if (!node.lValue.isLValue) > throw new WTypeError(node.origin.originString, "Not an lvalue: " + node.lValue); >+ if (node.lValue.unifyNode instanceof DereferenceExpression) >+ node.become(new IdentityExpression(node.lValue.unifyNode.ptr)); > } > > visitMakeArrayRefExpression(node) >diff --git a/Tools/WebGPUShadingLanguageRI/SynthesizeStructAccessors.js b/Tools/WebGPUShadingLanguageRI/SynthesizeStructAccessors.js >index a0181468a25ed4c09050d7bf1d61f44ed3a0aa66..24a209433bde0c1bbc2085654a0612c8c65fe9cd 100644 >--- a/Tools/WebGPUShadingLanguageRI/SynthesizeStructAccessors.js >+++ b/Tools/WebGPUShadingLanguageRI/SynthesizeStructAccessors.js >@@ -42,6 +42,13 @@ function synthesizeStructAccessors(program) > nativeFunc.implementation = (argumentList, node) => { > return implementation(argumentList, field.offset, type.size, field.type.size); > }; >+ >+ nativeFunc.implementationData = { >+ name: field.name, >+ type: type, >+ offset: field.offset, >+ size: field.type.size >+ }; > } > > function createFieldType() >diff --git a/Tools/WebGPUShadingLanguageRI/Test.js b/Tools/WebGPUShadingLanguageRI/Test.js >index 2bcea7d7da3cb382f1aabe2167ef3a7891392333..1166c58f83dcbb61e94b0811a50a96b1776863fa 100644 >--- a/Tools/WebGPUShadingLanguageRI/Test.js >+++ b/Tools/WebGPUShadingLanguageRI/Test.js >@@ -55,32 +55,37 @@ function doLex(code) > > function makeInt(program, value) > { >- return TypedValue.box(program.intrinsics.int, value); >+ return TypedValue.box(program.intrinsics.int, castAndCheckValue(castToInt, value)); > } > > function makeUint(program, value) > { >- return TypedValue.box(program.intrinsics.uint, value); >+ return TypedValue.box(program.intrinsics.uint, castAndCheckValue(castToUint, value)); > } > > function makeUchar(program, value) > { >- return TypedValue.box(program.intrinsics.uchar, value); >+ return TypedValue.box(program.intrinsics.uchar, castAndCheckValue(castToUchar, value)); > } > > function makeBool(program, value) > { >- return TypedValue.box(program.intrinsics.bool, value); >+ return TypedValue.box(program.intrinsics.bool, castAndCheckValue(castToBool, value)); > } > > function makeFloat(program, value) > { >- return TypedValue.box(program.intrinsics.float, value); >+ return TypedValue.box(program.intrinsics.float, castAndCheckValue(castToFloat, value)); >+} >+ >+function makeCastedFloat(program, value) >+{ >+ return TypedValue.box(program.intrinsics.float, castToFloat(value)); > } > > function makeHalf(program, value) > { >- return TypedValue.box(program.intrinsics.half, value); >+ return TypedValue.box(program.intrinsics.half, castAndCheckValue(castToHalf, value)); > } > > function makeEnum(program, enumName, value) >@@ -221,19 +226,12 @@ function makeRW2DDepthTextureArray(program, array, elementType) > return TypedValue.box(program.intrinsics[`RWTextureDepth2DArray<${elementType}>`], new TextureDepth2DArrayRW(elementType, array)); > } > >-function checkNumber(program, result, expected) >-{ >- if (!result.type.unifyNode.isNumber) >- throw new Error("Wrong result type; result: " + result); >- if (result.value != expected) >- throw new Error("Wrong result: " + result.value + " (expected " + expected + ")"); >-} >- > function checkInt(program, result, expected) > { > if (!result.type.equals(program.intrinsics.int)) > throw new Error("Wrong result type; result: " + result); >- checkNumber(program, result, expected); >+ if (result.value != expected) >+ throw new Error(`Wrong result: ${result.value} (expected ${expected})`); > } > > function checkEnum(program, result, expected) >@@ -439,6 +437,27 @@ tests.intSimpleMath = function() { > checkInt(program, callFunction(program, "foo", [makeInt(program, 7), makeInt(program, -2)]), -3); > } > >+tests.incrementAndDecrement = function() { >+ let program = doPrep(` >+ test int foo1() { int x = 0; return x++; } >+ test int foo2() { int x = 0; x++; return x; } >+ test int foo3() { int x = 0; return ++x; } >+ test int foo4() { int x = 0; ++x; return x; } >+ test int foo5() { int x = 0; return x--; } >+ test int foo6() { int x = 0; x--; return x; } >+ test int foo7() { int x = 0; return --x; } >+ test int foo8() { int x = 0; --x; return x; } >+ `); >+ checkInt(program, callFunction(program, "foo1", []), 0); >+ checkInt(program, callFunction(program, "foo2", []), 1); >+ checkInt(program, callFunction(program, "foo3", []), 1); >+ checkInt(program, callFunction(program, "foo4", []), 1); >+ checkInt(program, callFunction(program, "foo5", []), 0); >+ checkInt(program, callFunction(program, "foo6", []), -1); >+ checkInt(program, callFunction(program, "foo7", []), -1); >+ checkInt(program, callFunction(program, "foo8", []), -1); >+} >+ > tests.uintSimpleMath = function() { > let program = doPrep("test uint foo(uint x, uint y) { return x + y; }"); > checkUint(program, callFunction(program, "foo", [makeUint(program, 7), makeUint(program, 5)]), 12); >@@ -1039,13 +1058,13 @@ tests.passNullToPtrMonomorphicArrayRef = function() > tests.returnIntLiteralUint = function() > { > let program = doPrep("test uint foo() { return 42; }"); >- checkNumber(program, callFunction(program, "foo", []), 42); >+ checkUint(program, callFunction(program, "foo", []), 42); > } > > tests.returnIntLiteralFloat = function() > { > let program = doPrep("test float foo() { return 42; }"); >- checkNumber(program, callFunction(program, "foo", []), 42); >+ checkFloat(program, callFunction(program, "foo", []), 42); > } > > tests.badIntLiteralForInt = function() >@@ -2355,6 +2374,149 @@ tests.nestedSubscriptLValueEmulationSimple = function() > checkInt(program, callFunction(program, "testSetValuesMutateValuesAndSum", []), 5565); > } > >+tests.nestedSubscriptWithArraysInStructs = function() >+{ >+ let program = doPrep(` >+ struct Foo { >+ int[7] array; >+ } >+ int sum(Foo foo) >+ { >+ int result = 0; >+ for (uint i = 0; i < foo.array.length; i++) >+ result += foo.array[i]; >+ return result; >+ } >+ struct Bar { >+ Foo[6] array; >+ } >+ int sum(Bar bar) >+ { >+ int result = 0; >+ for (uint i = 0; i < bar.array.length; i++) >+ result += sum(bar.array[i]); >+ return result; >+ } >+ struct Baz { >+ Bar[5] array; >+ } >+ int sum(Baz baz) >+ { >+ int result = 0; >+ for (uint i = 0; i < baz.array.length; i++) >+ result += sum(baz.array[i]); >+ return result; >+ } >+ void setValues(thread Baz* baz) >+ { >+ for (uint i = 0; i < baz->array.length; i++) { >+ for (uint j = 0; j < baz->array[i].array.length; j++) { >+ for (uint k = 0; k < baz->array[i].array[j].array.length; k++) >+ baz->array[i].array[j].array[k] = int(i + j + k); >+ } >+ } >+ } >+ test int testSetValuesAndSum() >+ { >+ Baz baz; >+ setValues(&baz); >+ return sum(baz); >+ } >+ test int testSetValuesMutateValuesAndSum() >+ { >+ Baz baz; >+ setValues(&baz); >+ for (uint i = baz.array.length; i--;) { >+ for (uint j = baz.array[i].array.length; j--;) { >+ for (uint k = baz.array[i].array[j].array.length; k--;) >+ baz.array[i].array[j].array[k] = baz.array[i].array[j].array[k] * int(k); >+ } >+ } >+ return sum(baz); >+ } >+ `); >+ checkInt(program, callFunction(program, "testSetValuesAndSum", []), 1575); >+ checkInt(program, callFunction(program, "testSetValuesMutateValuesAndSum", []), 5565); >+} >+ >+tests.nestedSubscript = function() >+{ >+ let program = doPrep(` >+ int sum(int[7] array) >+ { >+ int result = 0; >+ for (uint i = array.length; i--;) >+ result += array[i]; >+ return result; >+ } >+ int sum(int[6][7] array) >+ { >+ int result = 0; >+ for (uint i = array.length; i--;) >+ result += sum(array[i]); >+ return result; >+ } >+ int sum(int[5][6][7] array) >+ { >+ int result = 0; >+ for (uint i = array.length; i--;) >+ result += sum(array[i]); >+ return result; >+ } >+ void setValues(thread int[][6][7] array) >+ { >+ for (uint i = array.length; i--;) { >+ for (uint j = array[i].length; j--;) { >+ for (uint k = array[i][j].length; k--;) >+ array[i][j][k] = int(i + j + k); >+ } >+ } >+ } >+ test int testSetValuesAndSum() >+ { >+ int[5][6][7] array; >+ setValues(@array); >+ return sum(array); >+ } >+ test int testSetValuesMutateValuesAndSum() >+ { >+ int[5][6][7] array; >+ setValues(@array); >+ for (uint i = array.length; i--;) { >+ for (uint j = array[i].length; j--;) { >+ for (uint k = array[i][j].length; k--;) >+ array[i][j][k] = array[i][j][k] * int(k); >+ } >+ } >+ return sum(array); >+ } >+ `); >+ checkInt(program, callFunction(program, "testSetValuesAndSum", []), 1575); >+ checkInt(program, callFunction(program, "testSetValuesMutateValuesAndSum", []), 5565); >+} >+ >+tests.lotsOfLocalVariables = function() >+{ >+ let src = "test int sum() {\n"; >+ src += " int i = 0;\n"; >+ let target = 0; >+ const numVars = 1024; >+ for (let i = 0; i < numVars; i++) { >+ const value = i * 3; >+ src += ` i = ${i};\n`; >+ src += ` int V${i} = (i + 3) * (i + 3);\n`; >+ target += (i + 3) * (i + 3); >+ } >+ src += " int result = 0;\n"; >+ for (let i = 0; i < numVars; i++) { >+ src += ` result += V${i};\n`; >+ } >+ src += " return result;\n"; >+ src += "}"; >+ let program = doPrep(src); >+ checkInt(program, callFunction(program, "sum", []), target); >+} >+ > tests.operatorBool = function() > { > let program = doPrep(` >@@ -2552,7 +2714,6 @@ tests.uintBitAnd = function() > `); > checkUint(program, callFunction(program, "foo", [makeUint(program, 1), makeUint(program, 7)]), 1); > checkUint(program, callFunction(program, "foo", [makeUint(program, 65535), makeUint(program, 42)]), 42); >- checkUint(program, callFunction(program, "foo", [makeUint(program, -1), makeUint(program, -7)]), 4294967289); > checkUint(program, callFunction(program, "foo", [makeUint(program, 0), makeUint(program, 85732)]), 0); > } > >@@ -2566,7 +2727,6 @@ tests.uintBitOr = function() > `); > checkUint(program, callFunction(program, "foo", [makeUint(program, 1), makeUint(program, 7)]), 7); > checkUint(program, callFunction(program, "foo", [makeUint(program, 65535), makeUint(program, 42)]), 65535); >- checkUint(program, callFunction(program, "foo", [makeUint(program, -1), makeUint(program, -7)]), 4294967295); > checkUint(program, callFunction(program, "foo", [makeUint(program, 0), makeUint(program, 85732)]), 85732); > } > >@@ -2580,7 +2740,6 @@ tests.uintBitXor = function() > `); > checkUint(program, callFunction(program, "foo", [makeUint(program, 1), makeUint(program, 7)]), 6); > checkUint(program, callFunction(program, "foo", [makeUint(program, 65535), makeUint(program, 42)]), 65493); >- checkUint(program, callFunction(program, "foo", [makeUint(program, -1), makeUint(program, -7)]), 6); > checkUint(program, callFunction(program, "foo", [makeUint(program, 0), makeUint(program, 85732)]), 85732); > } > >@@ -2594,7 +2753,6 @@ tests.uintBitNot = function() > `); > checkUint(program, callFunction(program, "foo", [makeUint(program, 1)]), 4294967294); > checkUint(program, callFunction(program, "foo", [makeUint(program, 65535)]), 4294901760); >- checkUint(program, callFunction(program, "foo", [makeUint(program, -1)]), 0); > checkUint(program, callFunction(program, "foo", [makeUint(program, 0)]), 4294967295); > } > >@@ -2608,7 +2766,6 @@ tests.uintLShift = function() > `); > checkUint(program, callFunction(program, "foo", [makeUint(program, 1), makeUint(program, 7)]), 128); > checkUint(program, callFunction(program, "foo", [makeUint(program, 65535), makeUint(program, 2)]), 262140); >- checkUint(program, callFunction(program, "foo", [makeUint(program, -1), makeUint(program, 5)]), 4294967264); > checkUint(program, callFunction(program, "foo", [makeUint(program, 0), makeUint(program, 3)]), 0); > } > >@@ -2622,7 +2779,6 @@ tests.uintRShift = function() > `); > checkUint(program, callFunction(program, "foo", [makeUint(program, 1), makeUint(program, 7)]), 0); > checkUint(program, callFunction(program, "foo", [makeUint(program, 65535), makeUint(program, 2)]), 16383); >- checkUint(program, callFunction(program, "foo", [makeUint(program, -1), makeUint(program, 5)]), 134217727); > checkUint(program, callFunction(program, "foo", [makeUint(program, 0), makeUint(program, 3)]), 0); > } > >@@ -2635,9 +2791,8 @@ tests.ucharBitAnd = function() > } > `); > checkUchar(program, callFunction(program, "foo", [makeUchar(program, 1), makeUchar(program, 7)]), 1); >- checkUchar(program, callFunction(program, "foo", [makeUchar(program, 65535), makeUchar(program, 42)]), 42); >- checkUchar(program, callFunction(program, "foo", [makeUchar(program, -1), makeUchar(program, -7)]), 249); >- checkUchar(program, callFunction(program, "foo", [makeUchar(program, 0), makeUchar(program, 85732)]), 0); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, 255), makeUchar(program, 42)]), 42); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, 0), makeUchar(program, 255)]), 0); > } > > tests.ucharBitOr = function() >@@ -2649,9 +2804,8 @@ tests.ucharBitOr = function() > } > `); > checkUchar(program, callFunction(program, "foo", [makeUchar(program, 1), makeUchar(program, 7)]), 7); >- checkUchar(program, callFunction(program, "foo", [makeUchar(program, 65535), makeUchar(program, 42)]), 255); >- checkUchar(program, callFunction(program, "foo", [makeUchar(program, -1), makeUchar(program, -7)]), 255); >- checkUchar(program, callFunction(program, "foo", [makeUchar(program, 0), makeUchar(program, 85732)]), 228); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, 255), makeUchar(program, 42)]), 255); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, 0), makeUchar(program, 228)]), 228); > } > > tests.ucharBitXor = function() >@@ -2663,9 +2817,8 @@ tests.ucharBitXor = function() > } > `); > checkUchar(program, callFunction(program, "foo", [makeUchar(program, 1), makeUchar(program, 7)]), 6); >- checkUchar(program, callFunction(program, "foo", [makeUchar(program, 65535), makeUchar(program, 42)]), 213); >- checkUchar(program, callFunction(program, "foo", [makeUchar(program, -1), makeUchar(program, -7)]), 6); >- checkUchar(program, callFunction(program, "foo", [makeUchar(program, 0), makeUchar(program, 85732)]), 228); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, 255), makeUchar(program, 42)]), 213); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, 0), makeUchar(program, 255)]), 255); > } > > tests.ucharBitNot = function() >@@ -2677,8 +2830,7 @@ tests.ucharBitNot = function() > } > `); > checkUchar(program, callFunction(program, "foo", [makeUchar(program, 1)]), 254); >- checkUchar(program, callFunction(program, "foo", [makeUchar(program, 65535)]), 0); >- checkUchar(program, callFunction(program, "foo", [makeUchar(program, -1)]), 0); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, 255)]), 0); > checkUchar(program, callFunction(program, "foo", [makeUchar(program, 0)]), 255); > } > >@@ -2691,8 +2843,7 @@ tests.ucharLShift = function() > } > `); > checkUchar(program, callFunction(program, "foo", [makeUchar(program, 1), makeUint(program, 7)]), 128); >- checkUchar(program, callFunction(program, "foo", [makeUchar(program, 65535), makeUint(program, 2)]), 252); >- checkUchar(program, callFunction(program, "foo", [makeUchar(program, -1), makeUint(program, 5)]), 224); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, 255), makeUint(program, 2)]), 252); > checkUchar(program, callFunction(program, "foo", [makeUchar(program, 0), makeUint(program, 3)]), 0); > } > >@@ -2705,8 +2856,8 @@ tests.ucharRShift = function() > } > `); > checkUchar(program, callFunction(program, "foo", [makeUchar(program, 1), makeUint(program, 7)]), 0); >- checkUchar(program, callFunction(program, "foo", [makeUchar(program, 65535), makeUint(program, 2)]), 255); >- checkUchar(program, callFunction(program, "foo", [makeUchar(program, -1), makeUint(program, 5)]), 255); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, 255), makeUint(program, 2)]), 63); >+ checkUchar(program, callFunction(program, "foo", [makeUchar(program, 255), makeUint(program, 5)]), 7); > checkUchar(program, callFunction(program, "foo", [makeUchar(program, 0), makeUint(program, 3)]), 0); > } > >@@ -7293,14 +7444,14 @@ tests.textureSample = function() { > checkFloat(program, callFunction(program, "foo14", [texture2D, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0)]), (12 + 13 + 20 + 21) / 4); > checkFloat(program, callFunction(program, "foo14", [texture2D, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1 / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 1 / texture2D.ePtr.loadValue().height)]), (12 + 13 + 20 + 21) / 4); > checkFloat(program, callFunction(program, "foo14", [texture2D, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 2 / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 2 / texture2D.ePtr.loadValue().height)]), (34 + 35 + 38 + 39) / 4); >- checkFloat(program, callFunction(program, "foo14", [texture2D, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().height)]), (12 + 13 + 20 + 21) / 4); >- checkFloat(program, callFunction(program, "foo14", [texture2D, makeSampler(program, {minFilter: "linear", mipmapFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().height)]), (((12 + 13 + 20 + 21) / 4) + ((34 + 35 + 38 + 39) / 4)) / 2); >+ checkFloat(program, callFunction(program, "foo14", [texture2D, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeCastedFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeCastedFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().height)]), (12 + 13 + 20 + 21) / 4); >+ checkFloat(program, callFunction(program, "foo14", [texture2D, makeSampler(program, {minFilter: "linear", mipmapFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeCastedFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeCastedFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().height)]), (((12 + 13 + 20 + 21) / 4) + ((34 + 35 + 38 + 39) / 4)) / 2); > checkFloat(program, callFunction(program, "foo15", [texture2D, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeInt(program, 0), makeInt(program, 0)]), (12 + 13 + 20 + 21) / 4); > checkFloat(program, callFunction(program, "foo15", [texture2D, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeInt(program, 1), makeInt(program, 0)]), (13 + 14 + 21 + 22) / 4); > checkFloat(program, callFunction(program, "foo15", [texture2D, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1 / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 1 / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (13 + 14 + 21 + 22) / 4); > checkFloat(program, callFunction(program, "foo15", [texture2D, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 2 / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 2 / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (35 + 36 + 39 + 40) / 4); >- checkFloat(program, callFunction(program, "foo15", [texture2D, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (13 + 14 + 21 + 22) / 4); >- checkFloat(program, callFunction(program, "foo15", [texture2D, makeSampler(program, {minFilter: "linear", mipmapFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (((13 + 14 + 21 + 22) / 4) + ((35 + 36 + 39 + 40) / 4)) / 2); >+ checkFloat(program, callFunction(program, "foo15", [texture2D, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeCastedFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeCastedFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (13 + 14 + 21 + 22) / 4); >+ checkFloat(program, callFunction(program, "foo15", [texture2D, makeSampler(program, {minFilter: "linear", mipmapFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeCastedFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeCastedFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (((13 + 14 + 21 + 22) / 4) + ((35 + 36 + 39 + 40) / 4)) / 2); > checkFloat(program, callFunction(program, "foo16", [texture2D, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0)]), (12 + 13 + 20 + 21) / 4); > checkFloat(program, callFunction(program, "foo16", [texture2D, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1)]), (34 + 35 + 38 + 39) / 4); > checkFloat(program, callFunction(program, "foo16", [texture2D, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0.5)]), (12 + 13 + 20 + 21) / 4); >@@ -7326,25 +7477,25 @@ tests.textureSample = function() { > checkFloat(program, callFunction(program, "foo20", [texture2DArray, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0)]), (12 + 13 + 20 + 21) / 4); > checkFloat(program, callFunction(program, "foo20", [texture2DArray, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, 1 / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 1 / texture2D.ePtr.loadValue().height)]), (12 + 13 + 20 + 21) / 4); > checkFloat(program, callFunction(program, "foo20", [texture2DArray, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, 2 / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 2 / texture2D.ePtr.loadValue().height)]), (34 + 35 + 38 + 39) / 4); >- checkFloat(program, callFunction(program, "foo20", [texture2DArray, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().height)]), (12 + 13 + 20 + 21) / 4); >- checkFloat(program, callFunction(program, "foo20", [texture2DArray, makeSampler(program, {minFilter: "linear", mipmapFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().height)]), (((12 + 13 + 20 + 21) / 4) + ((34 + 35 + 38 + 39) / 4)) / 2); >+ checkFloat(program, callFunction(program, "foo20", [texture2DArray, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeCastedFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeCastedFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().height)]), (12 + 13 + 20 + 21) / 4); >+ checkFloat(program, callFunction(program, "foo20", [texture2DArray, makeSampler(program, {minFilter: "linear", mipmapFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeCastedFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeCastedFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().height)]), (((12 + 13 + 20 + 21) / 4) + ((34 + 35 + 38 + 39) / 4)) / 2); > checkFloat(program, callFunction(program, "foo20", [texture2DArray, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0)]), (54 + 55 + 62 + 63) / 4); > checkFloat(program, callFunction(program, "foo20", [texture2DArray, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1), makeFloat(program, 1 / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 1 / texture2D.ePtr.loadValue().height)]), (54 + 55 + 62 + 63) / 4); > checkFloat(program, callFunction(program, "foo20", [texture2DArray, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1), makeFloat(program, 2 / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 2 / texture2D.ePtr.loadValue().height)]), (76 + 77 + 80 + 81) / 4); >- checkFloat(program, callFunction(program, "foo20", [texture2DArray, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1), makeFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().height)]), (54 + 55 + 62 + 63) / 4); >- checkFloat(program, callFunction(program, "foo20", [texture2DArray, makeSampler(program, {minFilter: "linear", mipmapFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1), makeFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().height)]), (((54 + 55 + 62 + 63) / 4) + ((76 + 77 + 80 + 81) / 4)) / 2); >+ checkFloat(program, callFunction(program, "foo20", [texture2DArray, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1), makeCastedFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeCastedFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().height)]), (54 + 55 + 62 + 63) / 4); >+ checkFloat(program, callFunction(program, "foo20", [texture2DArray, makeSampler(program, {minFilter: "linear", mipmapFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1), makeCastedFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeCastedFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().height)]), (((54 + 55 + 62 + 63) / 4) + ((76 + 77 + 80 + 81) / 4)) / 2); > checkFloat(program, callFunction(program, "foo21", [texture2DArray, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeInt(program, 0), makeInt(program, 0)]), (12 + 13 + 20 + 21) / 4); > checkFloat(program, callFunction(program, "foo21", [texture2DArray, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeInt(program, 1), makeInt(program, 0)]), (13 + 14 + 21 + 22) / 4); > checkFloat(program, callFunction(program, "foo21", [texture2DArray, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, 1 / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 1 / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (13 + 14 + 21 + 22) / 4); > checkFloat(program, callFunction(program, "foo21", [texture2DArray, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, 2 / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 2 / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (35 + 36 + 39 + 40) / 4); >- checkFloat(program, callFunction(program, "foo21", [texture2DArray, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (13 + 14 + 21 + 22) / 4); >- checkFloat(program, callFunction(program, "foo21", [texture2DArray, makeSampler(program, {minFilter: "linear", mipmapFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (((13 + 14 + 21 + 22) / 4) + ((35 + 36 + 39 + 40) / 4)) / 2); >+ checkFloat(program, callFunction(program, "foo21", [texture2DArray, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeCastedFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeCastedFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (13 + 14 + 21 + 22) / 4); >+ checkFloat(program, callFunction(program, "foo21", [texture2DArray, makeSampler(program, {minFilter: "linear", mipmapFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeCastedFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeCastedFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (((13 + 14 + 21 + 22) / 4) + ((35 + 36 + 39 + 40) / 4)) / 2); > checkFloat(program, callFunction(program, "foo21", [texture2DArray, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeInt(program, 0), makeInt(program, 0)]), (54 + 55 + 62 + 63) / 4); > checkFloat(program, callFunction(program, "foo21", [texture2DArray, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeInt(program, 1), makeInt(program, 0)]), (55 + 56 + 63 + 64) / 4); > checkFloat(program, callFunction(program, "foo21", [texture2DArray, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1), makeFloat(program, 1 / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 1 / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (55 + 56 + 63 + 64) / 4); > checkFloat(program, callFunction(program, "foo21", [texture2DArray, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1), makeFloat(program, 2 / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 2 / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (77 + 78 + 81 + 82) / 4); >- checkFloat(program, callFunction(program, "foo21", [texture2DArray, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1), makeFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (55 + 56 + 63 + 64) / 4); >- checkFloat(program, callFunction(program, "foo21", [texture2DArray, makeSampler(program, {minFilter: "linear", mipmapFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1), makeFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (((55 + 56 + 63 + 64) / 4) + ((77 + 78 + 81 + 82) / 4)) / 2); >+ checkFloat(program, callFunction(program, "foo21", [texture2DArray, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1), makeCastedFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeCastedFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (55 + 56 + 63 + 64) / 4); >+ checkFloat(program, callFunction(program, "foo21", [texture2DArray, makeSampler(program, {minFilter: "linear", mipmapFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1), makeCastedFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeCastedFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (((55 + 56 + 63 + 64) / 4) + ((77 + 78 + 81 + 82) / 4)) / 2); > checkFloat(program, callFunction(program, "foo22", [texture2DArray, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, 0)]), (12 + 13 + 20 + 21) / 4); > checkFloat(program, callFunction(program, "foo22", [texture2DArray, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, 1)]), (34 + 35 + 38 + 39) / 4); > checkFloat(program, callFunction(program, "foo22", [texture2DArray, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, 0.5)]), (12 + 13 + 20 + 21) / 4); >@@ -7372,7 +7523,7 @@ tests.textureSample = function() { > checkFloat(program, callFunction(program, "foo16", [texture2D, makeSampler(program, {minFilter: "linear", lodMinClamp: 1, lodMaxClamp: 1}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 2)]), (34 + 35 + 38 + 39) / 4); > checkFloat(program, callFunction(program, "foo16", [texture2D, makeSampler(program, {minFilter: "linear", lodMinClamp: 1, lodMaxClamp: 1}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0)]), (34 + 35 + 38 + 39) / 4); > checkFloat(program, callFunction(program, "foo14", [texture2D, makeSampler(program, {minFilter: "linear", mipmapFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 2 / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 1 / texture2D.ePtr.loadValue().height)]), (34 + 35 + 38 + 39) / 4); >- checkFloat(program, callFunction(program, "foo14", [texture2D, makeSampler(program, {minFilter: "linear", mipmapFilter: "linear", maxAnisotropy: 2}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 4 / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, (4/3) / texture2D.ePtr.loadValue().height)]), (34 + 35 + 38 + 39) / 4); >+ checkFloat(program, callFunction(program, "foo14", [texture2D, makeSampler(program, {minFilter: "linear", mipmapFilter: "linear", maxAnisotropy: 2}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 4 / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeCastedFloat(program, (4/3) / texture2D.ePtr.loadValue().height)]), (34 + 35 + 38 + 39) / 4); > let texture1DInt4 = make1DTexture(program, [[[1, 2, 3, 4], [100, 200, 300, 400], [101, 202, 301, 401], [13, 14, 15, 16]], [[17, 18, 19, 20], [21, 22, 23, 24]], [[25, 26, 27, 28]]], "int4"); > checkInt(program, callFunction(program, "foo24", [texture1DInt4, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5)]), 100); > checkInt(program, callFunction(program, "foo25", [texture1DInt4, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5)]), 201); >@@ -7414,14 +7565,14 @@ tests.textureSample = function() { > checkFloat(program, callFunction(program, "foo35", [textureDepth2D, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0)]), (12 + 13 + 20 + 21) / 4); > checkFloat(program, callFunction(program, "foo35", [textureDepth2D, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1 / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 1 / texture2D.ePtr.loadValue().height)]), (12 + 13 + 20 + 21) / 4); > checkFloat(program, callFunction(program, "foo35", [textureDepth2D, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 2 / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 2 / texture2D.ePtr.loadValue().height)]), (34 + 35 + 38 + 39) / 4); >- checkFloat(program, callFunction(program, "foo35", [textureDepth2D, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().height)]), (12 + 13 + 20 + 21) / 4); >- checkFloat(program, callFunction(program, "foo35", [textureDepth2D, makeSampler(program, {minFilter: "linear", mipmapFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().height)]), (((12 + 13 + 20 + 21) / 4) + ((34 + 35 + 38 + 39) / 4)) / 2); >+ checkFloat(program, callFunction(program, "foo35", [textureDepth2D, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeCastedFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeCastedFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().height)]), (12 + 13 + 20 + 21) / 4); >+ checkFloat(program, callFunction(program, "foo35", [textureDepth2D, makeSampler(program, {minFilter: "linear", mipmapFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeCastedFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeCastedFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().height)]), (((12 + 13 + 20 + 21) / 4) + ((34 + 35 + 38 + 39) / 4)) / 2); > checkFloat(program, callFunction(program, "foo36", [textureDepth2D, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeInt(program, 0), makeInt(program, 0)]), (12 + 13 + 20 + 21) / 4); > checkFloat(program, callFunction(program, "foo36", [textureDepth2D, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeInt(program, 1), makeInt(program, 0)]), (13 + 14 + 21 + 22) / 4); > checkFloat(program, callFunction(program, "foo36", [textureDepth2D, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1 / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 1 / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (13 + 14 + 21 + 22) / 4); > checkFloat(program, callFunction(program, "foo36", [textureDepth2D, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 2 / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 2 / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (35 + 36 + 39 + 40) / 4); >- checkFloat(program, callFunction(program, "foo36", [textureDepth2D, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (13 + 14 + 21 + 22) / 4); >- checkFloat(program, callFunction(program, "foo36", [textureDepth2D, makeSampler(program, {minFilter: "linear", mipmapFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (((13 + 14 + 21 + 22) / 4) + ((35 + 36 + 39 + 40) / 4)) / 2); >+ checkFloat(program, callFunction(program, "foo36", [textureDepth2D, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeCastedFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeCastedFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (13 + 14 + 21 + 22) / 4); >+ checkFloat(program, callFunction(program, "foo36", [textureDepth2D, makeSampler(program, {minFilter: "linear", mipmapFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeCastedFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeCastedFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (((13 + 14 + 21 + 22) / 4) + ((35 + 36 + 39 + 40) / 4)) / 2); > checkFloat(program, callFunction(program, "foo37", [textureDepth2D, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0)]), (12 + 13 + 20 + 21) / 4); > checkFloat(program, callFunction(program, "foo37", [textureDepth2D, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1)]), (34 + 35 + 38 + 39) / 4); > checkFloat(program, callFunction(program, "foo37", [textureDepth2D, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0.5)]), (12 + 13 + 20 + 21) / 4); >@@ -7447,25 +7598,25 @@ tests.textureSample = function() { > checkFloat(program, callFunction(program, "foo41", [textureDepth2DArray, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0)]), (12 + 13 + 20 + 21) / 4); > checkFloat(program, callFunction(program, "foo41", [textureDepth2DArray, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, 1 / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 1 / texture2D.ePtr.loadValue().height)]), (12 + 13 + 20 + 21) / 4); > checkFloat(program, callFunction(program, "foo41", [textureDepth2DArray, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, 2 / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 2 / texture2D.ePtr.loadValue().height)]), (34 + 35 + 38 + 39) / 4); >- checkFloat(program, callFunction(program, "foo41", [textureDepth2DArray, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().height)]), (12 + 13 + 20 + 21) / 4); >- checkFloat(program, callFunction(program, "foo41", [textureDepth2DArray, makeSampler(program, {minFilter: "linear", mipmapFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().height)]), (((12 + 13 + 20 + 21) / 4) + ((34 + 35 + 38 + 39) / 4)) / 2); >+ checkFloat(program, callFunction(program, "foo41", [textureDepth2DArray, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeCastedFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeCastedFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().height)]), (12 + 13 + 20 + 21) / 4); >+ checkFloat(program, callFunction(program, "foo41", [textureDepth2DArray, makeSampler(program, {minFilter: "linear", mipmapFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeCastedFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeCastedFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().height)]), (((12 + 13 + 20 + 21) / 4) + ((34 + 35 + 38 + 39) / 4)) / 2); > checkFloat(program, callFunction(program, "foo41", [textureDepth2DArray, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0)]), (54 + 55 + 62 + 63) / 4); > checkFloat(program, callFunction(program, "foo41", [textureDepth2DArray, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1), makeFloat(program, 1 / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 1 / texture2D.ePtr.loadValue().height)]), (54 + 55 + 62 + 63) / 4); > checkFloat(program, callFunction(program, "foo41", [textureDepth2DArray, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1), makeFloat(program, 2 / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 2 / texture2D.ePtr.loadValue().height)]), (76 + 77 + 80 + 81) / 4); >- checkFloat(program, callFunction(program, "foo41", [textureDepth2DArray, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1), makeFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().height)]), (54 + 55 + 62 + 63) / 4); >- checkFloat(program, callFunction(program, "foo41", [textureDepth2DArray, makeSampler(program, {minFilter: "linear", mipmapFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1), makeFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().height)]), (((54 + 55 + 62 + 63) / 4) + ((76 + 77 + 80 + 81) / 4)) / 2); >+ checkFloat(program, callFunction(program, "foo41", [textureDepth2DArray, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1), makeCastedFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeCastedFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().height)]), (54 + 55 + 62 + 63) / 4); >+ checkFloat(program, callFunction(program, "foo41", [textureDepth2DArray, makeSampler(program, {minFilter: "linear", mipmapFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1), makeCastedFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeCastedFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().height)]), (((54 + 55 + 62 + 63) / 4) + ((76 + 77 + 80 + 81) / 4)) / 2); > checkFloat(program, callFunction(program, "foo42", [textureDepth2DArray, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeInt(program, 0), makeInt(program, 0)]), (12 + 13 + 20 + 21) / 4); > checkFloat(program, callFunction(program, "foo42", [textureDepth2DArray, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeInt(program, 1), makeInt(program, 0)]), (13 + 14 + 21 + 22) / 4); > checkFloat(program, callFunction(program, "foo42", [textureDepth2DArray, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, 1 / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 1 / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (13 + 14 + 21 + 22) / 4); > checkFloat(program, callFunction(program, "foo42", [textureDepth2DArray, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, 2 / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 2 / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (35 + 36 + 39 + 40) / 4); >- checkFloat(program, callFunction(program, "foo42", [textureDepth2DArray, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (13 + 14 + 21 + 22) / 4); >- checkFloat(program, callFunction(program, "foo42", [textureDepth2DArray, makeSampler(program, {minFilter: "linear", mipmapFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (((13 + 14 + 21 + 22) / 4) + ((35 + 36 + 39 + 40) / 4)) / 2); >+ checkFloat(program, callFunction(program, "foo42", [textureDepth2DArray, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeCastedFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeCastedFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (13 + 14 + 21 + 22) / 4); >+ checkFloat(program, callFunction(program, "foo42", [textureDepth2DArray, makeSampler(program, {minFilter: "linear", mipmapFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeCastedFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeCastedFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (((13 + 14 + 21 + 22) / 4) + ((35 + 36 + 39 + 40) / 4)) / 2); > checkFloat(program, callFunction(program, "foo42", [textureDepth2DArray, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeInt(program, 0), makeInt(program, 0)]), (54 + 55 + 62 + 63) / 4); > checkFloat(program, callFunction(program, "foo42", [textureDepth2DArray, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 0), makeInt(program, 1), makeInt(program, 0)]), (55 + 56 + 63 + 64) / 4); > checkFloat(program, callFunction(program, "foo42", [textureDepth2DArray, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1), makeFloat(program, 1 / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 1 / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (55 + 56 + 63 + 64) / 4); > checkFloat(program, callFunction(program, "foo42", [textureDepth2DArray, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1), makeFloat(program, 2 / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, 2 / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (77 + 78 + 81 + 82) / 4); >- checkFloat(program, callFunction(program, "foo42", [textureDepth2DArray, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1), makeFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (55 + 56 + 63 + 64) / 4); >- checkFloat(program, callFunction(program, "foo42", [textureDepth2DArray, makeSampler(program, {minFilter: "linear", mipmapFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1), makeFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (((55 + 56 + 63 + 64) / 4) + ((77 + 78 + 81 + 82) / 4)) / 2); >+ checkFloat(program, callFunction(program, "foo42", [textureDepth2DArray, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1), makeCastedFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeCastedFloat(program, Math.pow(2, 0.25) / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (55 + 56 + 63 + 64) / 4); >+ checkFloat(program, callFunction(program, "foo42", [textureDepth2DArray, makeSampler(program, {minFilter: "linear", mipmapFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 1), makeCastedFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().width), makeFloat(program, 0), makeFloat(program, 0), makeCastedFloat(program, Math.pow(2, 0.5) / texture2D.ePtr.loadValue().height), makeInt(program, 1), makeInt(program, 0)]), (((55 + 56 + 63 + 64) / 4) + ((77 + 78 + 81 + 82) / 4)) / 2); > checkFloat(program, callFunction(program, "foo43", [textureDepth2DArray, makeSampler(program, {magFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, 0)]), (12 + 13 + 20 + 21) / 4); > checkFloat(program, callFunction(program, "foo43", [textureDepth2DArray, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, 1)]), (34 + 35 + 38 + 39) / 4); > checkFloat(program, callFunction(program, "foo43", [textureDepth2DArray, makeSampler(program, {minFilter: "linear"}), makeFloat(program, 0.5), makeFloat(program, 0.5), makeFloat(program, 0), makeFloat(program, 0.5)]), (12 + 13 + 20 + 21) / 4); >@@ -7946,13 +8097,6 @@ function* doTest(testFilter) > throw new Error("Test setup is incomplete."); > let before = preciseTime(); > >- print("Compiling standard library..."); >- const compileBefore = preciseTime(); >- yield; >- prepare(); >- const compileAfter = preciseTime(); >- print(` OK, took ${Math.round((compileAfter - compileBefore) * 1000)} ms`); >- > let names = []; > for (let s in tests) > names.push(s); >@@ -7978,7 +8122,7 @@ function* doTest(testFilter) > print("That took " + (after - before) * 1000 + " ms."); > } > >-if (!this.window) { >+if (!this.window && !this.runningInCocoaHost) { > Error.stackTraceLimit = Infinity; > for (let _ of doTest(testFilter)) { } > } >diff --git a/Tools/WebGPUShadingLanguageRI/Type.js b/Tools/WebGPUShadingLanguageRI/Type.js >index 2db158d099b326a93e7335e4e696138c5edbefdb..9a5e56e501d8e81e0a85a5f5c2960eb462eccbb3 100644 >--- a/Tools/WebGPUShadingLanguageRI/Type.js >+++ b/Tools/WebGPUShadingLanguageRI/Type.js >@@ -36,6 +36,11 @@ class Type extends Node { > get isEnum() { return false; } > get isPrimitive() { return false; } > >+ get arrayRefType() >+ { >+ return new ArrayRefType(this.origin, "thread", this); >+ } >+ > // Have to call these on the unifyNode. > argumentForAndOverload(origin, value) > {
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 187738
:
345192
|
345267
|
346955
|
347094
|
347104
|
347142
|
348258
|
348410
|
348702
|
349746
|
349818
|
350453
|
350779