WebKit Bugzilla
Attachment 348415 Details for
Bug 188873
: [WHLSL] Add more functions to the standard library
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch for committing
bug-188873-20180829110430.patch (text/plain), 222.97 KB, created by
Myles C. Maxfield
on 2018-08-29 11:04:31 PDT
(
hide
)
Description:
Patch for committing
Filename:
MIME Type:
Creator:
Myles C. Maxfield
Created:
2018-08-29 11:04:31 PDT
Size:
222.97 KB
patch
obsolete
>Subversion Revision: 235465 >diff --git a/Tools/ChangeLog b/Tools/ChangeLog >index 6c746cfa1caeaf05b4aa96c3d5566a71f8be6383..944f5001f0a13851af9092f8f2d2fefd4992e6f7 100644 >--- a/Tools/ChangeLog >+++ b/Tools/ChangeLog >@@ -1,3 +1,194 @@ >+2018-08-29 Myles C. Maxfield <mmaxfield@apple.com> >+ >+ [WHLSL] Add more functions to the standard library >+ https://bugs.webkit.org/show_bug.cgi?id=188873 >+ >+ Reviewed by Filip Pizlo. >+ >+ This patch adds the rest of the standard library to StandardLibrary.js, and updates the compiler to be able to compile it. >+ >+ There are a few major pieces: >+ 1. Swizzle operators are now implemented in the language, instead of as native functions >+ 2. Vector constructors are now implemented in the language, instead of as native functions >+ 3. The matrix type is implemented >+ 4. Vector operator&[] is illegal, and is removed from the compiler >+ 5. Vector index setters & index getters are now implemented in the language, instead of as native functions >+ 6. Vector and matrix equality operators are implemented in the language, instead of as native functions >+ 7. Casting a scalar to a boolean is implemented in the language, instead of as native functions >+ 8. Casting a vector to a boolean is not part of the language, and is removed from the compiler >+ 9. Half-precision floating point types are implemented >+ >+ * WebGPUShadingLanguageRI/All.js: >+ * WebGPUShadingLanguageRI/BuiltinMatrixGetter.js: Copied from Tools/WebGPUShadingLanguageRI/BuiltinVectorIndexSetter.js. >+ (BuiltinMatrixGetter): >+ (BuiltinMatrixGetter.prototype.get height): >+ (BuiltinMatrixGetter.prototype.get width): >+ (BuiltinMatrixGetter.prototype.toString): >+ (BuiltinMatrixGetter.functions): >+ (BuiltinMatrixGetter.prototype.instantiateImplementation): >+ * WebGPUShadingLanguageRI/BuiltinMatrixSetter.js: Renamed from Tools/WebGPUShadingLanguageRI/BuiltinVectorIndexSetter.js. >+ (BuiltinMatrixSetter): >+ (BuiltinMatrixSetter.prototype.get height): >+ (BuiltinMatrixSetter.prototype.get width): >+ (BuiltinMatrixSetter.prototype.toString): >+ (BuiltinMatrixSetter.functions): >+ (BuiltinMatrixSetter.prototype.instantiateImplementation): >+ * WebGPUShadingLanguageRI/BuiltinVectorConstructors.js: Removed. >+ * WebGPUShadingLanguageRI/BuiltinVectorEqualityOperator.js: Removed. >+ * WebGPUShadingLanguageRI/BuiltinVectorGetter.js: >+ (BuiltinVectorGetter.prototype.instantiateImplementation): >+ (BuiltinVectorGetter): >+ * WebGPUShadingLanguageRI/BuiltinVectorSetter.js: >+ (BuiltinVectorSetter.functions): >+ (BuiltinVectorSetter.prototype.instantiateImplementation): >+ (BuiltinVectorSetter): >+ * WebGPUShadingLanguageRI/CallExpression.js: >+ (CallExpression.prototype.resolve): >+ * WebGPUShadingLanguageRI/CheckTypesWithArguments.js: >+ (checkTypesWithArguments.TypeWithArgumentsChecker.prototype.visitTypeRef): >+ (checkTypesWithArguments.TypeWithArgumentsChecker): >+ (checkTypesWithArguments): >+ * WebGPUShadingLanguageRI/Checker.js: >+ (Checker.prototype.visitVectorType): >+ (Checker.prototype.visitMatrixType): >+ * WebGPUShadingLanguageRI/ConstexprFolder.js: >+ (ConstexprFolder.prototype.visitCallExpression): >+ (ConstexprFolder): >+ * WebGPUShadingLanguageRI/Evaluator.js: >+ (Evaluator.prototype.visitTernaryExpression): >+ * WebGPUShadingLanguageRI/FlattenedStructOffsetGatherer.js: >+ (FlattenedStructOffsetGatherer.prototype.visitMatrixType): >+ (FlattenedStructOffsetGatherer): >+ * WebGPUShadingLanguageRI/Intrinsics.js: >+ (Intrinsics.): >+ (Intrinsics): >+ * WebGPUShadingLanguageRI/MatrixType.js: Renamed from Tools/WebGPUShadingLanguageRI/BuiltinVectorIndexGetter.js. >+ (MatrixType): >+ (MatrixType.prototype.get elementType): >+ (MatrixType.prototype.get numRows): >+ (MatrixType.prototype.get numColumns): >+ (MatrixType.prototype.get numRowsValue): >+ (MatrixType.prototype.get numColumnsValue): >+ (MatrixType.prototype.get size): >+ (MatrixType.prototype.unifyImpl): >+ (MatrixType.prototype.populateDefaultValue): >+ (MatrixType.prototype.toString): >+ * WebGPUShadingLanguageRI/NameContext.js: >+ (NameContext.prototype.add): >+ * WebGPUShadingLanguageRI/NativeType.js: >+ (NativeType.create): >+ (NativeType): >+ * WebGPUShadingLanguageRI/OperatorAnderIndexer.js: Renamed from Tools/WebGPUShadingLanguageRI/OperatorAnderIndex.js. >+ (OperatorAnderIndexer): >+ * WebGPUShadingLanguageRI/OperatorBool.js: Removed. >+ * WebGPUShadingLanguageRI/Prepare.js: >+ (let.prepare): >+ * WebGPUShadingLanguageRI/Program.js: >+ (Program.prototype.add): >+ * WebGPUShadingLanguageRI/Rewriter.js: >+ (Rewriter.prototype.visitMatrixType): >+ (Rewriter): >+ * WebGPUShadingLanguageRI/SPIRV.html: >+ * WebGPUShadingLanguageRI/StandardLibrary.js: >+ (operator.bool): >+ (bool.operator): >+ (uchar.operator): >+ (ushort.operator): >+ (char.operator): >+ (short.operator): >+ (uint.operator): >+ (int.operator): >+ (half.operator): >+ (float.operator): >+ (uchar2.operator): >+ (uchar3.operator): >+ (uchar4.operator): >+ (ushort2.operator): >+ (ushort3.operator): >+ (ushort4.operator): >+ (uint2.operator): >+ (uint3.operator): >+ (uint4.operator): >+ (char2.operator): >+ (char3.operator): >+ (char4.operator): >+ (short2.operator): >+ (short3.operator): >+ (short4.operator): >+ (int2.operator): >+ (int3.operator): >+ (int4.operator): >+ (half2.operator): >+ (half3.operator): >+ (half4.operator): >+ (float2.operator): >+ (float3.operator): >+ (float4.operator): >+ (half2x2.operator): >+ (half2x3.operator): >+ (half2x4.operator): >+ (half3x2.operator): >+ (half3x3.operator): >+ (half3x4.operator): >+ (half4x2.operator): >+ (half4x3.operator): >+ (half4x4.operator): >+ (float2x2.operator): >+ (float2x3.operator): >+ (float2x4.operator): >+ (float3x2.operator): >+ (float3x3.operator): >+ (float3x4.operator): >+ (float4x2.operator): >+ (float4x3.operator): >+ (float4x4.operator): >+ (operator.bool2): >+ (operator.bool3): >+ (operator.bool4): >+ (uint.operator.length): >+ (operator.uchar2): >+ (operator.uchar3): >+ (operator.uchar4): >+ (operator.ushort2): >+ (operator.ushort3): >+ (operator.ushort4): >+ (operator.uint2): >+ (operator.uint3): >+ (operator.uint4): >+ (operator.char2): >+ (operator.char3): >+ (operator.char4): >+ (operator.short2): >+ (operator.short3): >+ (operator.short4): >+ (operator.int2): >+ (operator.int3): >+ (operator.int4): >+ (operator.half2): >+ (operator.half3): >+ (operator.half4): >+ (operator.float2): >+ (operator.float3): >+ (operator.float4): >+ (bool2.operator): >+ (bool3.operator): >+ (bool4.operator): >+ (allVectorTypeNames): >+ * WebGPUShadingLanguageRI/SwizzleOp.js: Removed. >+ * WebGPUShadingLanguageRI/SynthesizeDefaultConstructorOperator.js: >+ (synthesizeDefaultConstructorOperator.FindAllTypes.prototype.visitMatrixType): >+ (synthesizeDefaultConstructorOperator.FindAllTypes): >+ (synthesizeDefaultConstructorOperator): >+ * WebGPUShadingLanguageRI/SynthesizeOperatorBool.js: Removed. >+ * WebGPUShadingLanguageRI/Test.html: >+ * WebGPUShadingLanguageRI/Test.js: >+ (makeHalf): >+ (checkHalf): >+ * WebGPUShadingLanguageRI/Visitor.js: >+ (Visitor.prototype.visitMatrixType): >+ (Visitor): >+ * WebGPUShadingLanguageRI/index.html: >+ > 2018-08-29 David Kilzer <ddkilzer@apple.com> > > Remove empty directories from from svn.webkit.org repository >diff --git a/Tools/WebGPUShadingLanguageRI/All.js b/Tools/WebGPUShadingLanguageRI/All.js >index 315bec2e688627c3cd80ba46fba24001e28f9f4c..9c2a37150c1e976b926cfbee23437520a8de4a47 100644 >--- a/Tools/WebGPUShadingLanguageRI/All.js >+++ b/Tools/WebGPUShadingLanguageRI/All.js >@@ -34,7 +34,6 @@ load("Visitor.js"); > load("CreateLiteral.js"); > load("CreateLiteralType.js"); > load("PropertyAccessExpression.js"); >-load("SwizzleOp.js"); > load("NativeType.js"); > > load("AddressSpace.js"); >@@ -46,12 +45,10 @@ load("AutoWrapper.js"); > load("Block.js"); > load("BoolLiteral.js"); > load("Break.js"); >-load("BuiltinVectorConstructors.js"); >+load("BuiltinMatrixGetter.js"); >+load("BuiltinMatrixSetter.js"); > load("BuiltinVectorGetter.js"); > load("BuiltinVectorSetter.js"); >-load("BuiltinVectorIndexGetter.js"); >-load("BuiltinVectorIndexSetter.js"); >-load("BuiltinVectorEqualityOperator.js"); > load("CallExpression.js"); > load("CallFunction.js"); > load("Check.js"); >@@ -113,6 +110,7 @@ load("LogicalNot.js"); > load("LoopChecker.js"); > load("MakeArrayRefExpression.js"); > load("MakePtrExpression.js"); >+load("MatrixType.js"); > load("NameContext.js"); > load("NameFinder.js"); > load("NameResolver.js"); >@@ -120,9 +118,8 @@ load("NativeFunc.js"); > load("NormalUsePropertyResolver.js"); > load("NullLiteral.js"); > load("NullType.js"); >-load("OperatorAnderIndex.js"); >+load("OperatorAnderIndexer.js"); > load("OperatorArrayRefLength.js"); >-load("OperatorBool.js"); > load("OriginKind.js"); > load("OverloadResolutionFailure.js"); > load("Parse.js"); >@@ -150,7 +147,6 @@ load("SwitchStatement.js"); > load("SynthesizeArrayOperatorLength.js"); > load("SynthesizeEnumFunctions.js"); > load("SynthesizeStructAccessors.js"); >-load("SynthesizeOperatorBool.js"); > load("SynthesizeCopyConstructorOperator.js"); > load("SynthesizeDefaultConstructorOperator.js"); > load("TernaryExpression.js"); >diff --git a/Tools/WebGPUShadingLanguageRI/BuiltinMatrixGetter.js b/Tools/WebGPUShadingLanguageRI/BuiltinMatrixGetter.js >new file mode 100644 >index 0000000000000000000000000000000000000000..b339cf9163a9cfeeed7f0b2dadb4edb267c07b6d >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/BuiltinMatrixGetter.js >@@ -0,0 +1,73 @@ >+/* >+ * 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"; >+ >+class BuiltinMatrixGetter { >+ constructor(baseTypeName, height, width) >+ { >+ this._baseTypeName = baseTypeName; >+ this._height = height; >+ this._width = width; >+ } >+ >+ get baseTypeName() { return this._baseTypeName; } >+ get height() { return this._height; } >+ get width() { return this._width; } >+ >+ toString() >+ { >+ return `native ${this.baseTypeName}${this.width} operator[](${this.baseTypeName}${this.height}x${this.width},uint)`; >+ } >+ >+ static functions() >+ { >+ if (!this._functions) { >+ this._functions = []; >+ >+ for (let typeName of ["half", "float"]) { >+ for (let height of [2, 3, 4]) { >+ for (let width of [2, 3, 4]) >+ this._functions.push(new BuiltinMatrixGetter(typeName, height, width)); >+ } >+ } >+ } >+ return this._functions; >+ } >+ >+ instantiateImplementation(func) >+ { >+ func.implementation = ([mat, index]) => { >+ const indexValue = index.loadValue(); >+ if (indexValue >= 0 && indexValue < this.height) { >+ const result = new EPtr(new EBuffer(this.width), 0); >+ for (let i = 0; i < this.width; i++) >+ result.set(i, mat.get(indexValue * this.width + i)); >+ return result; >+ } else >+ throw new WTrapError("[Builtin matrix getter]", "Out-of-bounds index when indexing into a matrix"); >+ }; >+ func.implementationData = this; >+ } >+} >diff --git a/Tools/WebGPUShadingLanguageRI/BuiltinMatrixSetter.js b/Tools/WebGPUShadingLanguageRI/BuiltinMatrixSetter.js >new file mode 100644 >index 0000000000000000000000000000000000000000..f7b85749ce1f2d7d1af26b1cde8f78f3f84b5538 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/BuiltinMatrixSetter.js >@@ -0,0 +1,73 @@ >+/* >+ * 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"; >+ >+class BuiltinMatrixSetter { >+ constructor(baseTypeName, height, width) >+ { >+ this._baseTypeName = baseTypeName; >+ this._height = height; >+ this._width = width; >+ } >+ >+ get baseTypeName() { return this._baseTypeName; } >+ get height() { return this._height; } >+ get width() { return this._width; } >+ >+ toString() >+ { >+ return `native ${this.baseTypeName}${this.height}x${this.width} operator[]=(${this.baseTypeName}${this.height}x${this.width},uint,${this.baseTypeName}${this.width})`; >+ } >+ >+ static functions() >+ { >+ if (!this._functions) { >+ this._functions = []; >+ >+ for (let typeName of ["half", "float"]) { >+ for (let height of [2, 3, 4]) { >+ for (let width of [2, 3, 4]) >+ this._functions.push(new BuiltinMatrixSetter(typeName, height, width)); >+ } >+ } >+ } >+ return this._functions; >+ } >+ >+ instantiateImplementation(func) >+ { >+ func.implementation = ([base, index, value]) => { >+ const indexValue = index.loadValue(); >+ if (indexValue >= 0 && indexValue < this.height) { >+ let result = new EPtr(new EBuffer(this.width * this.height), 0); >+ result.copyFrom(base, this.width * this.height); >+ result.plus(indexValue * this.width).copyFrom(value, this.width); >+ return result; >+ } else >+ throw new WTrapError("[Builtin matrix setter]", "Out-of-bounds index when indexing into a matrix"); >+ }; >+ func.implementationData = this; >+ } >+} >diff --git a/Tools/WebGPUShadingLanguageRI/BuiltinVectorConstructors.js b/Tools/WebGPUShadingLanguageRI/BuiltinVectorConstructors.js >deleted file mode 100644 >index 2704b43a06c2faed9dfa73dead33bb0c5c955985..0000000000000000000000000000000000000000 >--- a/Tools/WebGPUShadingLanguageRI/BuiltinVectorConstructors.js >+++ /dev/null >@@ -1,84 +0,0 @@ >-/* >- * 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"; >- >-class BuiltinVectorConstructors { >- constructor(baseTypeName, parameterSizes) >- { >- this._baseTypeName = baseTypeName; >- this._parameterSizes = parameterSizes; >- } >- >- get baseTypeName() { return this._baseTypeName; } >- get parameterSizes() { return this._parameterSizes; } >- get outputSize() >- { >- return this.parameterSizes.reduce((a, b) => a + b, 0); >- } >- >- toString() >- { >- return `native operator ${this.baseTypeName}${this.outputSize}(${this.parameterSizes.map(x => x == 1 ? this.baseTypeName : this.baseTypeName + x).join(",")})`; >- } >- >- static functions() >- { >- if (!this._functions) { >- this._functions = []; >- >- for (let typeName of VectorElementTypes) { >- for (let size of VectorElementSizes) { >- for (let paramSizes of this._vectorParameterSizesForMaximumSize(size)) >- this._functions.push(new BuiltinVectorConstructors(typeName, paramSizes)); >- } >- } >- } >- return this._functions; >- } >- >- static _vectorParameterSizesForMaximumSize(maxSize) >- { >- let variants = [ [ maxSize ] ]; >- for (let splitPoint = 1; splitPoint < maxSize; splitPoint++) { >- for (let v of BuiltinVectorConstructors._vectorParameterSizesForMaximumSize(maxSize - splitPoint)) >- variants.push([ splitPoint ].concat(v)); >- } >- return variants; >- } >- >- instantiateImplementation(func) >- { >- func.implementation = (args) => { >- const result = new EPtr(new EBuffer(this.outputSize), 0); >- let offset = 0; >- for (let i = 0; i < args.length; i++) { >- for (let j = 0; j < this.parameterSizes[i]; j++) >- result.set(offset++, args[i].get(j)); >- } >- return result; >- }; >- func.implementationData = this; >- } >-} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/BuiltinVectorEqualityOperator.js b/Tools/WebGPUShadingLanguageRI/BuiltinVectorEqualityOperator.js >deleted file mode 100644 >index b183d356861941bc276e4d3c67c5e47ecafe4709..0000000000000000000000000000000000000000 >--- a/Tools/WebGPUShadingLanguageRI/BuiltinVectorEqualityOperator.js >+++ /dev/null >@@ -1,66 +0,0 @@ >-/* >- * 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"; >- >-class BuiltinVectorEqualityOperator { >- constructor(baseTypeName, size) >- { >- this._baseTypeName = baseTypeName; >- this._size = size; >- } >- >- get baseTypeName() { return this._baseTypeName; } >- get size() { return this._size; } >- >- toString() >- { >- return `native bool operator==(${this.baseTypeName}${this.size},${this.baseTypeName}${this.size})`; >- } >- >- static functions() >- { >- if (!this._functions) { >- this._functions = []; >- >- for (let typeName of VectorElementTypes) { >- for (let size of VectorElementSizes) >- this._functions.push(new BuiltinVectorEqualityOperator(typeName, size)); >- } >- } >- return this._functions; >- } >- >- instantiateImplementation(func) >- { >- func.implementation = ([ref1, ref2], node) => { >- for (let i = 0; i < this.size; i++) { >- if (ref1.get(i) != ref2.get(i)) >- return EPtr.box(false); >- } >- return EPtr.box(true); >- }; >- func.implementationData = this; >- } >-} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/BuiltinVectorGetter.js b/Tools/WebGPUShadingLanguageRI/BuiltinVectorGetter.js >index c253f7630ee9dc47cd1e1945bc87f42eaa3ccb28..40872b4f8e2bb3a8e4ffb26275d8d83fe72182f7 100644 >--- a/Tools/WebGPUShadingLanguageRI/BuiltinVectorGetter.js >+++ b/Tools/WebGPUShadingLanguageRI/BuiltinVectorGetter.js >@@ -62,9 +62,9 @@ class BuiltinVectorGetter { > > instantiateImplementation(func) > { >- func.implementation = ([vec], node) => { >+ func.implementation = ([vec]) => { > return EPtr.box(vec.get(this.index)); > }; > func.implementationData = this; > } >-} >\ No newline at end of file >+} >diff --git a/Tools/WebGPUShadingLanguageRI/BuiltinVectorIndexGetter.js b/Tools/WebGPUShadingLanguageRI/BuiltinVectorIndexGetter.js >deleted file mode 100644 >index f7262fc9ce2730f087d61455876b335fe024ac3a..0000000000000000000000000000000000000000 >--- a/Tools/WebGPUShadingLanguageRI/BuiltinVectorIndexGetter.js >+++ /dev/null >@@ -1,66 +0,0 @@ >-/* >- * 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"; >- >-class BuiltinVectorIndexGetter { >- constructor(baseTypeName, size) >- { >- this._baseTypeName = baseTypeName; >- this._size = size; >- } >- >- get baseTypeName() { return this._baseTypeName; } >- get size() { return this._size; } >- >- toString() >- { >- return `native ${this.baseTypeName} operator[](${this.baseTypeName}${this.size},uint)`; >- } >- >- static functions() >- { >- if (!this._allIndexGetters) { >- this._allIndexGetters = []; >- >- for (let typeName of VectorElementTypes) { >- for (let size of VectorElementSizes) >- this._allIndexGetters.push(new BuiltinVectorIndexGetter(typeName, size)); >- } >- } >- return this._allIndexGetters; >- } >- >- instantiateImplementation(func) >- { >- func.implementation = ([vec, index], node) => { >- const indexValue = index.loadValue(); >- if (indexValue >= 0 && indexValue < this.size) >- return EPtr.box(vec.get(index.loadValue())); >- else >- throw new Error(`${indexValue} out of bounds for vector of size ${this.size}`); >- }; >- func.implementationData = this; >- } >-} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/BuiltinVectorIndexSetter.js b/Tools/WebGPUShadingLanguageRI/BuiltinVectorIndexSetter.js >deleted file mode 100644 >index 2fe5d678ab705fe40b7d68e9693dd8afc4adee94..0000000000000000000000000000000000000000 >--- a/Tools/WebGPUShadingLanguageRI/BuiltinVectorIndexSetter.js >+++ /dev/null >@@ -1,71 +0,0 @@ >-/* >- * 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"; >- >-class BuiltinVectorIndexSetter { >- constructor(baseTypeName, size) >- { >- this._baseTypeName = baseTypeName; >- this._size = size; >- } >- >- get baseTypeName() { return this._baseTypeName; } >- get size() { return this._size; } >- get elementName() { return this._elementName; } >- get index() { return this._index; } >- >- toString() >- { >- return `native ${this.baseTypeName}${this.size} operator[]=(${this.baseTypeName}${this.size},uint,${this.baseTypeName})`; >- } >- >- static functions() >- { >- if (!this._functions) { >- this._functions = []; >- >- for (let typeName of VectorElementTypes) { >- for (let size of VectorElementSizes) >- this._functions.push(new BuiltinVectorIndexSetter(typeName, size)); >- } >- } >- return this._functions; >- } >- >- instantiateImplementation(func) >- { >- func.implementation = ([base, index, value], node) => { >- const indexValue = index.loadValue(); >- if (indexValue >= 0 && indexValue < this.size) { >- let result = new EPtr(new EBuffer(this.size), 0); >- result.copyFrom(base, this.size); >- result.plus(indexValue).copyFrom(value, 1); >- return result; >- } else >- throw new Error(`${indexValue} out of bounds for vector of size ${this.size}`); >- }; >- func.implementationData = this; >- } >-} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/BuiltinVectorSetter.js b/Tools/WebGPUShadingLanguageRI/BuiltinVectorSetter.js >index a2d763b7509997b2410c24b801314c34a3c487a0..d559591e968671ef9035996a3fb6157ef97b25ec 100644 >--- a/Tools/WebGPUShadingLanguageRI/BuiltinVectorSetter.js >+++ b/Tools/WebGPUShadingLanguageRI/BuiltinVectorSetter.js >@@ -47,7 +47,7 @@ class BuiltinVectorSetter { > { > if (!this._functions) { > this._functions = []; >- >+ > const elements = [ "x", "y", "z", "w" ]; > > for (let typeName of VectorElementTypes) { >@@ -62,7 +62,7 @@ class BuiltinVectorSetter { > > instantiateImplementation(func) > { >- func.implementation = ([base, value], node) => { >+ func.implementation = ([base, value]) => { > let result = new EPtr(new EBuffer(this.size), 0); > result.copyFrom(base, this.size); > result.plus(this.index).copyFrom(value, 1); >@@ -70,4 +70,4 @@ class BuiltinVectorSetter { > }; > func.implementationData = this; > } >-} >\ No newline at end of file >+} >diff --git a/Tools/WebGPUShadingLanguageRI/CallExpression.js b/Tools/WebGPUShadingLanguageRI/CallExpression.js >index 3b15455992e64e2677ba0b03ab6568ef43d5d865..5fbdd505f79d4b326e093e0fb76cd375d0a2c5ba 100644 >--- a/Tools/WebGPUShadingLanguageRI/CallExpression.js >+++ b/Tools/WebGPUShadingLanguageRI/CallExpression.js >@@ -52,19 +52,22 @@ class CallExpression extends Expression { > > resolve(possibleOverloads, program) > { >- if (!possibleOverloads) >- throw new WTypeError(this.origin.originString, "Did not find any functions named " + this.name); >- > let failures = []; >- let overload = resolveOverloadImpl(possibleOverloads, this.argumentTypes, this.returnType); >+ let overload; >+ if (possibleOverloads) >+ overload = resolveOverloadImpl(possibleOverloads, this.argumentTypes, this.returnType); > >- if (!overload.func) { >+ if (!overload || !overload.func) { >+ if (!overload) >+ overload = {}; > const func = this._resolveByInstantiation(program); > if (func) > overload.func = func; > } > > if (!overload.func) { >+ if (!overload.failures) >+ overload.failures = []; > failures.push(...overload.failures); > let message = "Did not find function named " + this.name + " for call with "; > message += "argument types (" + this.argumentTypes + ")"; >diff --git a/Tools/WebGPUShadingLanguageRI/CheckTypesWithArguments.js b/Tools/WebGPUShadingLanguageRI/CheckTypesWithArguments.js >index bb6b2bd498e77b149df4c68f4ef3ac1ff1cdaab2..2f69142a3517d294900530c0cf066c9bfd2277af 100644 >--- a/Tools/WebGPUShadingLanguageRI/CheckTypesWithArguments.js >+++ b/Tools/WebGPUShadingLanguageRI/CheckTypesWithArguments.js >@@ -29,8 +29,20 @@ function checkTypesWithArguments(program) > class TypeWithArgumentsChecker extends Visitor { > visitTypeRef(node) > { >- if (node.name == "vector" && node.typeArguments.length == 0) >- throw new Error("Builtin type ${node.name} should always have type arguments."); >+ if ((node.name == "vector" && node.typeArguments.length != 2) >+ || (node.name == "matrix" && node.typeArguments.length != 3) >+ || (node.name == "Texture1D" && node.typeArguments.length != 1) >+ || (node.name == "RWTexture1D" && node.typeArguments.length != 1) >+ || (node.name == "Texture1DArray" && node.typeArguments.length != 1) >+ || (node.name == "RWTexture1DArray" && node.typeArguments.length != 1) >+ || (node.name == "Texture2D" && node.typeArguments.length != 1) >+ || (node.name == "RWTexture2D" && node.typeArguments.length != 1) >+ || (node.name == "Texture2DArray" && node.typeArguments.length != 1) >+ || (node.name == "RWTexture2DArray" && node.typeArguments.length != 1) >+ || (node.name == "Texture3D" && node.typeArguments.length != 1) >+ || (node.name == "RWTexture3D" && node.typeArguments.length != 1) >+ || (node.name == "TextureCube" && node.typeArguments.length != 1)) >+ throw new Error(`Builtin type ${node.name} should always have type arguments.`); > } > } > program.visit(new TypeWithArgumentsChecker()); >diff --git a/Tools/WebGPUShadingLanguageRI/Checker.js b/Tools/WebGPUShadingLanguageRI/Checker.js >index c69d5549bad93dbd243fa6693c86f0b59978cc59..5f598b2ee7522bbc810545c948d773f2e4f9947d 100644 >--- a/Tools/WebGPUShadingLanguageRI/Checker.js >+++ b/Tools/WebGPUShadingLanguageRI/Checker.js >@@ -263,6 +263,7 @@ class Checker extends Visitor { > visitVectorType(node) > { > node.elementType.visit(this); >+ node.numElements.visit(this); > > let isKnownAllowedVectorElementType = false; > for (let vectorElementTypeName of VectorElementTypes) { >@@ -277,6 +278,33 @@ class Checker extends Visitor { > > if (!isKnownAllowedVectorElementType) > throw new WTypeError(`${node.elementType} is not a permitted vector element type.`); >+ if (node.numElementsValue != 2 && node.numElementsValue != 3 && node.numElementsValue != 4) >+ throw new WTypeError(`${node.toString()}: ${node.numElementsValue} is not 2, 3, or 4.`); >+ } >+ >+ visitMatrixType(node) >+ { >+ node.elementType.visit(this); >+ node.numRows.visit(this); >+ node.numColumns.visit(this); >+ >+ let isKnownAllowedVectorElementType = false; >+ for (let elementTypeName of ["half", "float"]) { >+ const elementType = this._program.globalNameContext.get(Type, elementTypeName); >+ if (!elementType) >+ throw new WTypeError(`${elementTypeName} is not a known native type in the standard library or intrinsics.`); >+ if (elementType.equals(node.elementType)) { >+ isKnownAllowedVectorElementType = true; >+ break; >+ } >+ } >+ >+ if (!isKnownAllowedVectorElementType) >+ throw new WTypeError(`${node.elementType} is not a permitted vector element type.`); >+ if (node.numRowsValue != 2 && node.numRowsValue != 3 && node.numRowsValue != 4) >+ throw new WTypeError(`${node.toString()}: ${node.numRowsValue} is not 2, 3, or 4.`); >+ if (node.numColumnsValue != 2 && node.numColumnsValue != 3 && node.numColumnsValue != 4) >+ throw new WTypeError(`${node.toString()}: ${node.numColumnsValue} is not 2, 3, or 4.`); > } > > visitArrayType(node) >diff --git a/Tools/WebGPUShadingLanguageRI/ConstexprFolder.js b/Tools/WebGPUShadingLanguageRI/ConstexprFolder.js >index 5451332d7f10c495cee94f6139645878abb071d2..36e5f6f35e579107339ab30b283808d3d7cf1e0c 100644 >--- a/Tools/WebGPUShadingLanguageRI/ConstexprFolder.js >+++ b/Tools/WebGPUShadingLanguageRI/ConstexprFolder.js >@@ -35,9 +35,9 @@ class ConstexprFolder extends Visitor { > > if (node.name == "operator-" > && node.argumentList.length == 1 >- && node.argumentList[0].unifyNode.isConstexpr >- && node.argumentList[0].unifyNode.negConstexpr) { >- node.become(node.argumentList[0].unifyNode.negConstexpr(node.origin)); >+ && node.argumentList[0].isLiteral >+ && node.argumentList[0].negConstexpr) { >+ node.become(node.argumentList[0].negConstexpr(node.origin)); > return; > } > } >diff --git a/Tools/WebGPUShadingLanguageRI/Evaluator.js b/Tools/WebGPUShadingLanguageRI/Evaluator.js >index 0290de23d441aa2f3a8c13290f21f1fcca6d2c7d..aee0a2312fed72c0c87e73f18ac348ea1ac3c7ba 100644 >--- a/Tools/WebGPUShadingLanguageRI/Evaluator.js >+++ b/Tools/WebGPUShadingLanguageRI/Evaluator.js >@@ -148,7 +148,6 @@ class Evaluator extends Visitor { > if (node.predicate.visit(this).loadValue()) > return node.bodyExpression.visit(this); > return node.elseExpression.visit(this); >- > } > > visitVariableRef(node) >diff --git a/Tools/WebGPUShadingLanguageRI/FlattenedStructOffsetGatherer.js b/Tools/WebGPUShadingLanguageRI/FlattenedStructOffsetGatherer.js >index 53c8716c45046f87fc4f6cd53fa9f7a42c53e165..2739d7bf7fa4962c775f28c79ce58458bfd4a8e8 100644 >--- a/Tools/WebGPUShadingLanguageRI/FlattenedStructOffsetGatherer.js >+++ b/Tools/WebGPUShadingLanguageRI/FlattenedStructOffsetGatherer.js >@@ -73,5 +73,17 @@ class FlattenedStructOffsetGatherer extends Visitor { > }); > } > } >+ >+ visitMatrixType(node) >+ { >+ const fieldNames = [ "row0", "row1", "row2", "row3" ]; >+ for (let i = 0; i < node.numRowsValue; i++) { >+ this._result.push({ >+ name: this._name.join(".") + "." + fieldNames[i], >+ offset: this._offset + i * node.elementType.size * node.numColumnsValue, >+ type: node.elementType.name + node.numColumnsValue.toString() >+ }); >+ } >+ } > } > >diff --git a/Tools/WebGPUShadingLanguageRI/Intrinsics.js b/Tools/WebGPUShadingLanguageRI/Intrinsics.js >index 72290632982ee108412e88b0882e41ce85a7301d..79f59070daffb55a3f3a70a3b1badb4ce68cd4ef 100644 >--- a/Tools/WebGPUShadingLanguageRI/Intrinsics.js >+++ b/Tools/WebGPUShadingLanguageRI/Intrinsics.js >@@ -273,7 +273,7 @@ class Intrinsics { > type.size = 1; > type.isFloating = true; > type.isNumber = true; >- type.canRepresent = value => isBitwiseEquivalent(castToHalf(value), value); >+ type.canRepresent = value => true; > type.populateDefaultValue = (buffer, offset) => buffer.set(offset, 0); > type.formatValueFromIntLiteral = value => value; > type.formatValueFromUintLiteral = value => value; >@@ -288,7 +288,7 @@ class Intrinsics { > type.size = 1; > type.isFloating = true; > type.isNumber = true; >- type.canRepresent = value => isBitwiseEquivalent(Math.fround(value), value); >+ type.canRepresent = value => true; > type.populateDefaultValue = (buffer, offset) => buffer.set(offset, 0); > type.formatValueFromIntLiteral = value => value; > type.formatValueFromUintLiteral = value => value; >@@ -316,90 +316,238 @@ class Intrinsics { > } > } > >+ for (let type of ["half", "float"]) { >+ for (let height = 2; height <= 4; ++height) { >+ for (let width = 2; width <= 4; ++width) { >+ this._map.set(`native typedef matrix<${type}, ${height}, ${width}>`, type => { >+ this[`matrix<${type}, ${height}, ${width}>`] = type; >+ }); >+ } >+ } >+ } >+ > this._map.set( >- "native operator int(uint)", >- func => { >- func.implementation = ([value]) => EPtr.box(value.loadValue() | 0); >- }); >+ "native typedef sampler", >+ type => { >+ this.sampler = type; >+ // FIXME: Figure out what to put here. >+ }); >+ >+ for (let textureType of ["Texture1D", "RWTexture1D", "Texture1DArray", "RWTexture1DArray", "Texture2D", "RWTexture2D", "Texture2DArray", "RWTexture2DArray", "Texture3D", "RWTexture3D", "TextureCube"]) { >+ for (let typeArgument of ["bool", "uchar", "ushort", "uint", "char", "short", "int", "half", "float"]) { >+ this._map.set( >+ `native typedef ${textureType}<${typeArgument}>`, >+ type => { >+ this[`${textureType}<${typeArgument}>`] = type; >+ }); >+ for (let i = 2; i <= 4; ++i) { >+ this._map.set( >+ `native typedef ${textureType}<${typeArgument}${i}>`, >+ type => { >+ this[`${textureType}<${typeArgument}${i}>`] = type; >+ }); >+ } >+ } >+ } >+ >+ for (let textureType of ["TextureDepth2D", "RWTextureDepth2D", "TextureDepth2DArray", "RWTextureDepth2DArray", "TextureDepthCube"]) { >+ for (let typeArgument of ["float", "half"]) { >+ this._map.set( >+ `native typedef ${textureType}<${typeArgument}>`, >+ type => { >+ this[`${textureType}<${typeArgument}>`] = type; >+ }); >+ } >+ } >+ >+ for (let primitiveType of ["ushort", "uint", "char", "short", "int", "half", "float"]) { >+ this._map.set( >+ `native operator uchar(${primitiveType})`, >+ func => { >+ func.implementation = ([value]) => EPtr.box(value.loadValue() & 0xff); >+ }); >+ } >+ >+ for (let primitiveType of ["uchar", "uint", "char", "short", "int", "half", "float"]) { >+ this._map.set( >+ `native operator ushort(${primitiveType})`, >+ func => { >+ func.implementation = ([value]) => EPtr.box(value.loadValue() & 0xffff); >+ }); >+ } >+ >+ for (let primitiveType of ["uchar", "ushort", "char", "short", "int", "half", "float"]) { >+ this._map.set( >+ `native operator uint(${primitiveType})`, >+ func => { >+ func.implementation = ([value]) => EPtr.box(value.loadValue() >>> 0); >+ }); >+ } >+ >+ for (let primitiveType of ["uchar", "ushort", "uint", "short", "int", "half", "float"]) { >+ this._map.set( >+ `native operator char(${primitiveType})`, >+ func => { >+ func.implementation = ([value]) => EPtr.box(cast(Int8Array, value.loadValue())); >+ }); >+ } >+ >+ for (let primitiveType of ["uchar", "ushort", "uint", "char", "int", "half", "float"]) { >+ this._map.set( >+ `native operator short(${primitiveType})`, >+ func => { >+ func.implementation = ([value]) => EPtr.box(cast(Int16Array, value.loadValue())); >+ }); >+ } >+ >+ for (let primitiveType of ["uchar", "ushort", "uint", "char", "short", "half", "float"]) { >+ this._map.set( >+ `native operator int(${primitiveType})`, >+ func => { >+ func.implementation = ([value]) => EPtr.box(cast(Int32Array, value.loadValue())); >+ }); >+ } >+ >+ for (let primitiveType of ["uchar", "ushort", "uint", "char", "short", "int", "float"]) { >+ this._map.set( >+ `native operator half(${primitiveType})`, >+ func => { >+ func.implementation = ([value]) => EPtr.box(castToHalf(value.loadValue())); >+ }); >+ } >+ >+ for (let primitiveType of ["uchar", "ushort", "uint", "char", "short", "int", "half"]) { >+ this._map.set( >+ `native operator float(${primitiveType})`, >+ func => { >+ func.implementation = ([value]) => EPtr.box(Math.fround(value.loadValue())); >+ }); >+ } > > this._map.set( >- "native operator int(uchar)", >+ `native operator int(atomic_int)`, > func => { >- func.implementation = ([value]) => EPtr.box(value.loadValue() | 0); >+ func.implementation = ([value]) => EPtr.box(value.loadValue()); > }); > > this._map.set( >- "native operator int(float)", >+ `native operator uint(atomic_uint)`, > func => { >- func.implementation = ([value]) => EPtr.box(value.loadValue() | 0); >+ func.implementation = ([value]) => EPtr.box(value.loadValue()); > }); > > this._map.set( >- "native operator uint(int)", >+ "native bool operator==(bool,bool)", > func => { >- func.implementation = ([value]) => EPtr.box(value.loadValue() >>> 0); >+ func.implementation = ([left, right]) => >+ EPtr.box(left.loadValue() == right.loadValue()); > }); > >+ for (let primitiveType of ["uint", "int", "float"]) { >+ this._map.set( >+ `native bool operator==(${primitiveType},${primitiveType})`, >+ func => { >+ func.implementation = ([left, right]) => >+ EPtr.box(left.loadValue() == right.loadValue()); >+ }); >+ >+ this._map.set( >+ `native bool operator<(${primitiveType},${primitiveType})`, >+ func => { >+ func.implementation = ([left, right]) => >+ EPtr.box(left.loadValue() < right.loadValue()); >+ }); >+ >+ this._map.set( >+ `native bool operator<=(${primitiveType},${primitiveType})`, >+ func => { >+ func.implementation = ([left, right]) => >+ EPtr.box(left.loadValue() <= right.loadValue()); >+ }); >+ >+ this._map.set( >+ `native bool operator>(${primitiveType},${primitiveType})`, >+ func => { >+ func.implementation = ([left, right]) => >+ EPtr.box(left.loadValue() > right.loadValue()); >+ }); >+ >+ this._map.set( >+ `native bool operator>=(${primitiveType},${primitiveType})`, >+ func => { >+ func.implementation = ([left, right]) => >+ EPtr.box(left.loadValue() >= right.loadValue()); >+ }); >+ } >+ > this._map.set( >- "native operator uint(uchar)", >+ "native int operator-(int)", > func => { >- func.implementation = ([value]) => EPtr.box(value.loadValue() >>> 0); >+ func.implementation = ([value]) => >+ EPtr.box((-value.loadValue()) | 0); > }); > > this._map.set( >- "native operator uint(float)", >+ "native float operator-(float)", > func => { >- func.implementation = ([value]) => EPtr.box(value.loadValue() >>> 0); >+ func.implementation = ([value]) => >+ EPtr.box(Math.fround(-value.loadValue())); > }); > > this._map.set( >- "native operator uchar(int)", >+ "native int operator+(int,int)", > func => { >- func.implementation = ([value]) => EPtr.box(value.loadValue() & 0xff); >+ func.implementation = ([left, right]) => >+ EPtr.box((left.loadValue() + right.loadValue()) | 0); > }); > > this._map.set( >- "native operator uchar(uint)", >+ "native int operator-(int,int)", > func => { >- func.implementation = ([value]) => EPtr.box(value.loadValue() & 0xff); >+ func.implementation = ([left, right]) => >+ EPtr.box((left.loadValue() - right.loadValue()) | 0); > }); > > this._map.set( >- "native operator uchar(float)", >+ "native int operator*(int,int)", > func => { >- func.implementation = ([value]) => EPtr.box(value.loadValue() & 0xff); >+ func.implementation = ([left, right]) => >+ EPtr.box((left.loadValue() * right.loadValue()) | 0); > }); > > this._map.set( >- "native operator float(int)", >+ "native int operator/(int,int)", > func => { >- func.implementation = ([value]) => EPtr.box(Math.fround(value.loadValue())); >+ func.implementation = ([left, right]) => >+ EPtr.box((left.loadValue() / right.loadValue()) | 0); > }); > > this._map.set( >- "native operator float(uint)", >+ "native uint operator+(uint,uint)", > func => { >- func.implementation = ([value]) => EPtr.box(Math.fround(value.loadValue())); >+ func.implementation = ([left, right]) => >+ EPtr.box((left.loadValue() + right.loadValue()) >>> 0); > }); > > this._map.set( >- "native operator float(uchar)", >+ "native uint operator-(uint,uint)", > func => { >- func.implementation = ([value]) => EPtr.box(Math.fround(value.loadValue())); >+ func.implementation = ([left, right]) => >+ EPtr.box((left.loadValue() - right.loadValue()) >>> 0); > }); > > this._map.set( >- "native int operator+(int,int)", >+ "native uint operator*(uint,uint)", > func => { > func.implementation = ([left, right]) => >- EPtr.box((left.loadValue() + right.loadValue()) | 0); >+ EPtr.box((left.loadValue() * right.loadValue()) >>> 0); > }); > > this._map.set( >- "native uint operator+(uint,uint)", >+ "native uint operator/(uint,uint)", > func => { > func.implementation = ([left, right]) => >- EPtr.box((left.loadValue() + right.loadValue()) >>> 0); >+ EPtr.box((left.loadValue() / right.loadValue()) >>> 0); > }); > > this._map.set( >@@ -410,67 +558,65 @@ class Intrinsics { > }); > > this._map.set( >- "native int operator-(int,int)", >+ "native float operator-(float,float)", > func => { > func.implementation = ([left, right]) => >- EPtr.box((left.loadValue() - right.loadValue()) | 0); >+ EPtr.box(Math.fround(left.loadValue() - right.loadValue())); > }); > > this._map.set( >- "native uint operator-(uint,uint)", >+ "native float operator*(float,float)", > func => { > func.implementation = ([left, right]) => >- EPtr.box((left.loadValue() - right.loadValue()) >>> 0); >+ EPtr.box(Math.fround(left.loadValue() * right.loadValue())); > }); > > this._map.set( >- "native float operator-(float,float)", >+ "native float operator/(float,float)", > func => { > func.implementation = ([left, right]) => >- EPtr.box(Math.fround(left.loadValue() - right.loadValue())); >+ EPtr.box(Math.fround(left.loadValue() / right.loadValue())); > }); > > this._map.set( >- "native int operator*(int,int)", >+ "native int operator&(int,int)", > func => { >- func.implementation = ([left, right]) => { >- return EPtr.box((left.loadValue() * right.loadValue()) | 0); >- }; >+ func.implementation = ([left, right]) => >+ EPtr.box((left.loadValue() & right.loadValue()) | 0); > }); > > this._map.set( >- "native uint operator*(uint,uint)", >+ "native int operator|(int,int)", > func => { > func.implementation = ([left, right]) => >- EPtr.box((left.loadValue() * right.loadValue()) >>> 0); >+ EPtr.box((left.loadValue() | right.loadValue()) | 0); > }); > > this._map.set( >- "native float operator*(float,float)", >+ "native int operator^(int,int)", > func => { > func.implementation = ([left, right]) => >- EPtr.box(Math.fround(left.loadValue() * right.loadValue())); >+ EPtr.box((left.loadValue() ^ right.loadValue()) | 0); > }); > > this._map.set( >- "native int operator/(int,int)", >+ "native int operator~(int)", > func => { >- func.implementation = ([left, right]) => >- EPtr.box((left.loadValue() / right.loadValue()) | 0); >+ func.implementation = ([value]) => EPtr.box((~value.loadValue()) | 0); > }); > > this._map.set( >- "native uint operator/(uint,uint)", >+ "native int operator<<(int,uint)", > func => { > func.implementation = ([left, right]) => >- EPtr.box((left.loadValue() / right.loadValue()) >>> 0); >+ EPtr.box((left.loadValue() << right.loadValue()) | 0); > }); > > this._map.set( >- "native int operator&(int,int)", >+ "native int operator>>(int,uint)", > func => { > func.implementation = ([left, right]) => >- EPtr.box(left.loadValue() & right.loadValue()); >+ EPtr.box((left.loadValue() >> right.loadValue()) | 0); > }); > > this._map.set( >@@ -481,223 +627,293 @@ class Intrinsics { > }); > > this._map.set( >- "native int operator|(int,int)", >+ "native uint operator|(uint,uint)", > func => { > func.implementation = ([left, right]) => >- EPtr.box(left.loadValue() | right.loadValue()); >+ EPtr.box((left.loadValue() | right.loadValue()) >>> 0); > }); > > this._map.set( >- "native uint operator|(uint,uint)", >+ "native uint operator^(uint,uint)", > func => { > func.implementation = ([left, right]) => >- EPtr.box((left.loadValue() | right.loadValue()) >>> 0); >+ EPtr.box((left.loadValue() ^ right.loadValue()) >>> 0); > }); > > this._map.set( >- "native int operator^(int,int)", >+ "native uint operator~(uint)", > func => { >- func.implementation = ([left, right]) => >- EPtr.box(left.loadValue() ^ right.loadValue()); >+ func.implementation = ([value]) => EPtr.box((~value.loadValue()) >>> 0); > }); > > this._map.set( >- "native uint operator^(uint,uint)", >+ "native uint operator<<(uint,uint)", > func => { > func.implementation = ([left, right]) => >- EPtr.box((left.loadValue() ^ right.loadValue()) >>> 0); >+ EPtr.box((left.loadValue() << right.loadValue()) >>> 0); > }); > > this._map.set( >- "native int operator<<(int,uint)", >+ "native uint operator>>(uint,uint)", > func => { > func.implementation = ([left, right]) => >- EPtr.box(left.loadValue() << right.loadValue()); >+ EPtr.box((left.loadValue() >>> right.loadValue()) >>> 0); > }); > > this._map.set( >- "native uint operator<<(uint,uint)", >+ "native float cos(float)", > func => { >- func.implementation = ([left, right]) => >- EPtr.box((left.loadValue() << right.loadValue()) >>> 0); >+ func.implementation = ([value]) => >+ EPtr.box(Math.fround(Math.cos(value.loadValue()))); > }); > > this._map.set( >- "native int operator>>(int,uint)", >+ "native float sin(float)", > func => { >- func.implementation = ([left, right]) => >- EPtr.box(left.loadValue() >> right.loadValue()); >+ func.implementation = ([value]) => >+ EPtr.box(Math.fround(Math.sin(value.loadValue()))); > }); > > this._map.set( >- "native uint operator>>(uint,uint)", >+ "native float tan(float)", > func => { >- func.implementation = ([left, right]) => >- EPtr.box(left.loadValue() >>> right.loadValue()); >+ func.implementation = ([value]) => >+ EPtr.box(Math.fround(Math.tan(value.loadValue()))); > }); > > this._map.set( >- "native int operator~(int)", >+ "native float acos(float)", > func => { >- func.implementation = ([value]) => EPtr.box(~value.loadValue()); >+ func.implementation = ([value]) => >+ EPtr.box(Math.fround(Math.acos(value.loadValue()))); > }); > > this._map.set( >- "native uint operator~(uint)", >+ "native float asin(float)", > func => { >- func.implementation = ([value]) => EPtr.box((~value.loadValue()) >>> 0); >+ func.implementation = ([value]) => >+ EPtr.box(Math.fround(Math.asin(value.loadValue()))); > }); > > this._map.set( >- "native float operator/(float,float)", >+ "native float atan(float)", > func => { >- func.implementation = ([left, right]) => >- EPtr.box(Math.fround(left.loadValue() / right.loadValue())); >+ func.implementation = ([value]) => >+ EPtr.box(Math.fround(Math.atan(value.loadValue()))); > }); > > this._map.set( >- "native bool operator==(int,int)", >+ "native float cosh(float)", > func => { >- func.implementation = ([left, right]) => >- EPtr.box(left.loadValue() == right.loadValue()); >+ func.implementation = ([value]) => >+ EPtr.box(Math.fround(Math.cosh(value.loadValue()))); > }); > > this._map.set( >- "native bool operator==(uint,uint)", >+ "native float sinh(float)", > func => { >- func.implementation = ([left, right]) => >- EPtr.box(left.loadValue() == right.loadValue()); >+ func.implementation = ([value]) => >+ EPtr.box(Math.fround(Math.sinh(value.loadValue()))); > }); > > this._map.set( >- "native bool operator==(bool,bool)", >+ "native float tanh(float)", > func => { >- func.implementation = ([left, right]) => >- EPtr.box(left.loadValue() == right.loadValue()); >+ func.implementation = ([value]) => >+ EPtr.box(Math.fround(Math.tanh(value.loadValue()))); > }); > > this._map.set( >- "native bool operator==(float,float)", >+ "native float ceil(float)", > func => { >- func.implementation = ([left, right]) => >- EPtr.box(left.loadValue() == right.loadValue()); >+ func.implementation = ([value]) => >+ EPtr.box(Math.fround(Math.ceil(value.loadValue()))); > }); > > this._map.set( >- "native bool operator<(int,int)", >+ "native float exp(float)", > func => { >- func.implementation = ([left, right]) => >- EPtr.box(left.loadValue() < right.loadValue()); >+ func.implementation = ([value]) => >+ EPtr.box(Math.fround(Math.exp(value.loadValue()))); > }); > > this._map.set( >- "native bool operator<(uint,uint)", >+ "native float floor(float)", > func => { >- func.implementation = ([left, right]) => >- EPtr.box(left.loadValue() < right.loadValue()); >+ func.implementation = ([value]) => >+ EPtr.box(Math.fround(Math.floor(value.loadValue()))); > }); > > this._map.set( >- "native bool operator<(float,float)", >+ "native float log(float)", > func => { >- func.implementation = ([left, right]) => >- EPtr.box(left.loadValue() < right.loadValue()); >+ func.implementation = ([value]) => >+ EPtr.box(Math.fround(Math.log(value.loadValue()))); > }); > > this._map.set( >- "native bool operator<=(int,int)", >+ "native float round(float)", > func => { >- func.implementation = ([left, right]) => >- EPtr.box(left.loadValue() <= right.loadValue()); >+ func.implementation = ([value]) => >+ EPtr.box(Math.fround(Math.round(value.loadValue()))); > }); > > this._map.set( >- "native bool operator<=(uint,uint)", >+ "native float sqrt(float)", > func => { >- func.implementation = ([left, right]) => >- EPtr.box(left.loadValue() <= right.loadValue()); >+ func.implementation = ([value]) => >+ EPtr.box(Math.fround(Math.sqrt(value.loadValue()))); > }); > > this._map.set( >- "native bool operator<=(float,float)", >+ "native float trunc(float)", > func => { >- func.implementation = ([left, right]) => >- EPtr.box(left.loadValue() <= right.loadValue()); >+ func.implementation = ([value]) => >+ EPtr.box(Math.fround(Math.trunc(value.loadValue()))); > }); > > this._map.set( >- "native bool operator>(int,int)", >+ "native float ddx(float)", > func => { >- func.implementation = ([left, right]) => >- EPtr.box(left.loadValue() > right.loadValue()); >+ func.implementation = ([value]) => EPtr.box(0); > }); > > this._map.set( >- "native bool operator>(uint,uint)", >+ "native float ddy(float)", > func => { >- func.implementation = ([left, right]) => >- EPtr.box(left.loadValue() > right.loadValue()); >+ func.implementation = ([value]) => EPtr.box(0); > }); > > this._map.set( >- "native bool operator>(float,float)", >+ "native float pow(float,float)", > func => { > func.implementation = ([left, right]) => >- EPtr.box(left.loadValue() > right.loadValue()); >+ EPtr.box(Math.fround(Math.pow(left.loadValue(), right.loadValue()))); > }); > > this._map.set( >- "native bool operator>=(int,int)", >+ "native bool isfinite(float)", > func => { >- func.implementation = ([left, right]) => >- EPtr.box(left.loadValue() >= right.loadValue()); >+ func.implementation = ([value]) => >+ EPtr.box(Number.isFinite(value.loadValue())); > }); > > this._map.set( >- "native bool operator>=(uint,uint)", >+ "native bool isinf(float)", > func => { >- func.implementation = ([left, right]) => >- EPtr.box(left.loadValue() >= right.loadValue()); >+ func.implementation = ([value]) => >+ EPtr.box((value.loadValue() == Number.POSITIVE_INFINITY) || (value.loadValue() == Number.NEGATIVE_INFINITY)); >+ }); >+ >+ this._map.set( >+ "native bool isnan(float)", >+ func => { >+ func.implementation = ([value]) => >+ EPtr.box(Number.isNaN(value.loadValue())); >+ }); >+ >+ // FIXME: Implement this. >+ this._map.set( >+ "native bool isnormal(half)", >+ func => { >+ func.implementation = ([value]) => >+ EPtr.box(isNaN(value.loadValue())); >+ }); >+ >+ // FIXME: Implement this. >+ this._map.set( >+ "native bool isnormal(float)", >+ func => { >+ func.implementation = ([value]) => >+ EPtr.box(isNaN(value.loadValue())); > }); > > this._map.set( >- "native bool operator>=(float,float)", >+ "native float atan2(float,float)", > func => { > func.implementation = ([left, right]) => >- EPtr.box(left.loadValue() >= right.loadValue()); >+ EPtr.box(Math.fround(Math.atan2(left.loadValue(), right.loadValue()))); > }); > >- for (let nativeVectorTypeName of allVectorTypeNames()) >- this._map.set(`native typedef ${nativeVectorTypeName}`, type => { >- type.isPrimitive = true; >+ this._map.set( >+ "native int asint(float)", >+ func => { >+ func.implementation = ([value]) => >+ EPtr.box(bitwiseCast(Float32Array, Int32Array, value.loadValue())); > }); > >- for (let swizzle of SwizzleOp.functions()) >- this._map.set(swizzle.toString(), func => swizzle.instantiateImplementation(func)); >+ this._map.set( >+ "native uint asuint(float)", >+ func => { >+ func.implementation = ([value]) => >+ EPtr.box(bitwiseCast(Float32Array, Uint32Array, value.loadValue())); >+ }); >+ >+ this._map.set( >+ "native float asfloat(int)", >+ func => { >+ func.implementation = ([value]) => >+ EPtr.box(bitwiseCast(Int32Array, Float32Array, value.loadValue())); >+ }); >+ >+ this._map.set( >+ "native float asfloat(uint)", >+ func => { >+ func.implementation = ([value]) => >+ EPtr.box(bitwiseCast(Uint32Array, Float32Array, value.loadValue())); >+ }); > >- for (let boolOp of OperatorBool.functions()) >- this._map.set(boolOp.toString(), func => boolOp.instantiateImplementation(func)); >+ // FIXME: Implement this. >+ this._map.set( >+ "native float f16tof32(uint)", >+ func => { >+ func.implementation = ([value]) => >+ EPtr.box(0); >+ }); > >- for (let anderIndex of OperatorAnderIndexer.functions()) >- this._map.set(anderIndex.toString(), func => anderIndex.instantiateImplementation(func)); >+ // FIXME: Implement this. >+ this._map.set( >+ "native uint f32tof16(float)", >+ func => { >+ func.implementation = ([value]) => >+ EPtr.box(0); >+ }); > >- for (let cast of BuiltinVectorConstructors.functions()) >- this._map.set(cast.toString(), func => cast.instantiateImplementation(func)); >+ this._map.set( >+ "native void AllMemoryBarrierWithGroupSync()", >+ func => { >+ func.implementation = function() {}; >+ }); > >- for (let getter of BuiltinVectorIndexGetter.functions()) >- this._map.set(getter.toString(), func => getter.instantiateImplementation(func)); >+ this._map.set( >+ "native void DeviceMemoryBarrierWithGroupSync()", >+ func => { >+ func.implementation = function() {}; >+ }); > >- for (let setter of BuiltinVectorIndexSetter.functions()) >- this._map.set(setter.toString(), func => setter.instantiateImplementation(func)); >+ this._map.set( >+ "native void GroupMemoryBarrierWithGroupSync()", >+ func => { >+ func.implementation = function() {}; >+ }); > >- for (let equalityOperator of BuiltinVectorEqualityOperator.functions()) >- this._map.set(equalityOperator.toString(), func => equalityOperator.instantiateImplementation(func)); >+ for (let nativeVectorTypeName of allVectorTypeNames()) { >+ this._map.set(`native typedef ${nativeVectorTypeName}`, type => { >+ type.isPrimitive = true; >+ }); >+ } > > for (let getter of BuiltinVectorGetter.functions()) > this._map.set(getter.toString(), func => getter.instantiateImplementation(func)); > > for (let setter of BuiltinVectorSetter.functions()) > this._map.set(setter.toString(), func => setter.instantiateImplementation(func)); >+ >+ for (let getter of BuiltinMatrixGetter.functions()) >+ this._map.set(getter.toString(), func => getter.instantiateImplementation(func)); >+ >+ for (let setter of BuiltinMatrixSetter.functions()) >+ this._map.set(setter.toString(), func => setter.instantiateImplementation(func)); > } > > add(thing) >diff --git a/Tools/WebGPUShadingLanguageRI/MatrixType.js b/Tools/WebGPUShadingLanguageRI/MatrixType.js >new file mode 100644 >index 0000000000000000000000000000000000000000..c39ceec715e7c996f9f1b9ef51795c8263a988f3 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/MatrixType.js >@@ -0,0 +1,61 @@ >+/* >+ * 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"; >+ >+class MatrixType extends NativeType { >+ constructor(origin, name, typeArguments) >+ { >+ super(origin, name, typeArguments); >+ } >+ >+ get elementType() { return this.typeArguments[0]; } >+ get numRows() { return this.typeArguments[1]; } >+ get numColumns() { return this.typeArguments[2]; } >+ get numRowsValue() { return this.numRows.value; } >+ get numColumnsValue() { return this.numColumns.value; } >+ get size() { return this.elementType.size * this.numRowsValue * this.numColumnsValue; } >+ >+ unifyImpl(unificationContext, other) >+ { >+ if (!(other instanceof MatrixType)) >+ return false; >+ >+ if (this.numRowsValue !== other.numRowsValue || this.numColumnsValue !== other.numColumnsValue) >+ return false; >+ >+ return this.elementType.unify(unificationContext, other.elementType); >+ } >+ >+ populateDefaultValue(buffer, offset) >+ { >+ for (let i = 0; i < this.numRowsValue * this.numColumnsValue; ++i) >+ this.elementType.populateDefaultValue(buffer, offset + i * this.elementType.size); >+ } >+ >+ toString() >+ { >+ return `native typedef matrix<${this.elementType}, ${this.numRowsValue}, ${this.numColumnsValue}>`; >+ } >+} >diff --git a/Tools/WebGPUShadingLanguageRI/NameContext.js b/Tools/WebGPUShadingLanguageRI/NameContext.js >index dc68578ff556b312b0927ef3c0dffa0068f1be63..c89968c779607b7cabcc6a5f969b4ab913e7263e 100644 >--- a/Tools/WebGPUShadingLanguageRI/NameContext.js >+++ b/Tools/WebGPUShadingLanguageRI/NameContext.js >@@ -71,7 +71,7 @@ class NameContext { > > if (thing.kind == Type) { > this._set.add(thing); >- if (thing.name == "vector") { >+ if (thing.typeArguments && thing.typeArguments.length != 0) { > let array = this._map.get(thing.name); > if (!array) { > array = []; >diff --git a/Tools/WebGPUShadingLanguageRI/NativeFunc.js b/Tools/WebGPUShadingLanguageRI/NativeFunc.js >index 997bd48974c9fe2c64026134163a302314b1a19a..f0865342f2edd7dec47bf52d1598610c324f0f2c 100644 >--- a/Tools/WebGPUShadingLanguageRI/NativeFunc.js >+++ b/Tools/WebGPUShadingLanguageRI/NativeFunc.js >@@ -31,7 +31,6 @@ class NativeFunc extends Func { > this.isRestricted = false; > this.implementation = null; > this._implementationData = null; >- this.instantiateImplementation = (substitution) => {}; > this.visitImplementationData = (implementationData, visitor) => null; > } > >diff --git a/Tools/WebGPUShadingLanguageRI/NativeType.js b/Tools/WebGPUShadingLanguageRI/NativeType.js >index 2381b5a6b0b010e0fdd4dc53550a8ea6b4f8347b..b368a2e8b24f548eab88a2824b495be23c87cb85 100644 >--- a/Tools/WebGPUShadingLanguageRI/NativeType.js >+++ b/Tools/WebGPUShadingLanguageRI/NativeType.js >@@ -66,6 +66,8 @@ class NativeType extends Type { > { > if (name == "vector") > return new VectorType(origin, name, typeArguments); >+ if (name == "matrix") >+ return new MatrixType(origin, name, typeArguments); > > return new NativeType(origin, name, typeArguments); > } >diff --git a/Tools/WebGPUShadingLanguageRI/OperatorAnderIndex.js b/Tools/WebGPUShadingLanguageRI/OperatorAnderIndex.js >deleted file mode 100644 >index 670371fb90f2a1fd15c2ddf6c4a396c0f239cebf..0000000000000000000000000000000000000000 >--- a/Tools/WebGPUShadingLanguageRI/OperatorAnderIndex.js >+++ /dev/null >@@ -1,71 +0,0 @@ >-/* >- * 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"; >- >-class OperatorAnderIndexer { >- constructor(baseTypeName, addressSpace) >- { >- this._baseTypeName = baseTypeName; >- this._addressSpace = addressSpace; >- } >- >- get addressSpace() { return this._addressSpace; } >- get baseTypeName() { return this._baseTypeName; } >- >- toString() >- { >- return `native ${this.baseTypeName}* ${this.addressSpace} operator&[](${this.baseTypeName}[] ${this.addressSpace},uint)`; >- } >- >- static functions() >- { >- if (!this._functions) { >- this._functions = []; >- >- const typeNames = [ "uint", "int", "float", "bool" ].concat(allVectorTypeNames()); >- const addressSpaces = [ "thread", "threadgroup", "device", "constant" ]; >- >- for (let addressSpace of addressSpaces) { >- for (let typeName of typeNames) >- this._functions.push(new OperatorAnderIndexer(typeName, addressSpace)); >- } >- } >- return this._functions; >- } >- >- instantiateImplementation(func) >- { >- func.implementation = ([ref, index], node) => { >- ref = ref.loadValue(); >- if (!ref) >- throw new WTrapError(node.origin.originString, "Null dereference"); >- index = index.loadValue(); >- if (index > ref.length) >- throw new WTrapError(node.origin.originString, "Array index " + index + " is out of bounds of " + ref); >- return EPtr.box(ref.ptr.plus(index * node.argumentTypes[0].elementType.size)); >- }; >- func.implementationData = this; >- } >-} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/OperatorAnderIndexer.js b/Tools/WebGPUShadingLanguageRI/OperatorAnderIndexer.js >new file mode 100644 >index 0000000000000000000000000000000000000000..012f06780f7ad9322d6c7be4790cd446181f89b4 >--- /dev/null >+++ b/Tools/WebGPUShadingLanguageRI/OperatorAnderIndexer.js >@@ -0,0 +1,55 @@ >+/* >+ * 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"; >+ >+class OperatorAnderIndexer { >+ constructor(baseTypeName, addressSpace) >+ { >+ this._baseTypeName = baseTypeName; >+ this._addressSpace = addressSpace; >+ } >+ >+ get addressSpace() { return this._addressSpace; } >+ get baseTypeName() { return this._baseTypeName; } >+ >+ toString() >+ { >+ return `native ${this.baseTypeName}* ${this.addressSpace} operator&[](${this.baseTypeName}[] ${this.addressSpace},uint)`; >+ } >+ >+ instantiateImplementation(func) >+ { >+ func.implementation = ([ref, index], node) => { >+ ref = ref.loadValue(); >+ if (!ref) >+ throw new WTrapError(node.origin.originString, "Null dereference"); >+ index = index.loadValue(); >+ if (index > ref.length) >+ throw new WTrapError(node.origin.originString, "Array index " + index + " is out of bounds of " + ref); >+ return EPtr.box(ref.ptr.plus(index * node.argumentTypes[0].elementType.size)); >+ }; >+ func.implementationData = this; >+ } >+} >diff --git a/Tools/WebGPUShadingLanguageRI/OperatorBool.js b/Tools/WebGPUShadingLanguageRI/OperatorBool.js >deleted file mode 100644 >index 58bb0e09b80bee107089b1c9d200cbc68a5cb9d3..0000000000000000000000000000000000000000 >--- a/Tools/WebGPUShadingLanguageRI/OperatorBool.js >+++ /dev/null >@@ -1,68 +0,0 @@ >-/* >- * 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"; >- >-class OperatorBool { >- constructor(baseTypeName) >- { >- this._baseTypeName = baseTypeName; >- } >- >- get baseTypeName() { return this._baseTypeName; } >- >- toString() >- { >- return `native operator bool(${this.baseTypeName})`; >- } >- >- static functions() >- { >- // FIXME: These operators should be in the standard library where possible. >- if (!OperatorBool._functions) { >- OperatorBool._functions = []; >- >- // bool is not included because this is generated by the copy constructor. >- // FIXME: Include all native types. >- const typeNames = [ "uchar", "uint", "int", "float" ].concat(allVectorTypeNames()); >- >- for (let typeName of typeNames) >- OperatorBool._functions.push(new OperatorBool(typeName)); >- } >- return OperatorBool._functions; >- } >- >- instantiateImplementation(func) >- { >- func.implementation = ([ref], node) => { >- const size = node.argumentTypes[0].size; >- for (let i = 0; i < size; ++i) { >- if (!!ref.get(i)) >- return EPtr.box(true); >- } >- return EPtr.box(false); >- } >- func.implementationData = this; >- } >-} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/Prepare.js b/Tools/WebGPUShadingLanguageRI/Prepare.js >index 9faca86e205755b2c6a66f412b5692e99e7b03af..834592d36f3457dfa86b5751bb7262472a3f0a2d 100644 >--- a/Tools/WebGPUShadingLanguageRI/Prepare.js >+++ b/Tools/WebGPUShadingLanguageRI/Prepare.js >@@ -46,7 +46,6 @@ let prepare = (() => { > resolveTypeDefsInTypes(program); > checkRecursiveTypes(program); > synthesizeStructAccessors(program); >- synthesizeOperatorBool(program); > synthesizeEnumFunctions(program); > synthesizeArrayOperatorLength(program); > synthesizeCopyConstructorOperator(program); >diff --git a/Tools/WebGPUShadingLanguageRI/Program.js b/Tools/WebGPUShadingLanguageRI/Program.js >index 1116c4f577562215fdd7428a317579a929165414..ac1defb4fbaaa6e8e13429734ccf4915339ba539 100644 >--- a/Tools/WebGPUShadingLanguageRI/Program.js >+++ b/Tools/WebGPUShadingLanguageRI/Program.js >@@ -51,7 +51,7 @@ class Program extends Node { > this.functions.set(statement.name, array = []); > array.push(statement); > } else if (statement instanceof Type) { >- if (statement.isNative && statement.name == "vector") { >+ if (statement.isNative && statement.typeArguments.length != 0) { > let array = this.types.get(statement.name); > if (!array) > this.types.set(statement.name, array = []); >diff --git a/Tools/WebGPUShadingLanguageRI/Rewriter.js b/Tools/WebGPUShadingLanguageRI/Rewriter.js >index 94d3a762e38fb921c584cbafff1f59478ebb791d..7c2dfba6955339884dbbf910478d43effdec65cf 100644 >--- a/Tools/WebGPUShadingLanguageRI/Rewriter.js >+++ b/Tools/WebGPUShadingLanguageRI/Rewriter.js >@@ -391,5 +391,11 @@ class Rewriter { > vecType._elementType = node.elementType.visit(this); > return vecType; > } >+ >+ visitMatrixType(node) >+ { >+ const matType = new MatrixType(node.origin, node.name, node.typeArguments.map(argument => argument.visit(this))); >+ return matType; >+ } > } > >diff --git a/Tools/WebGPUShadingLanguageRI/SPIRV.html b/Tools/WebGPUShadingLanguageRI/SPIRV.html >index ff2c02c7bafca4d1e2cf833c6c79fa1cec89013c..78d008f835f9e9c234ef2df6d6deea3f7426ce65 100644 >--- a/Tools/WebGPUShadingLanguageRI/SPIRV.html >+++ b/Tools/WebGPUShadingLanguageRI/SPIRV.html >@@ -17,7 +17,6 @@ td { > <script src="CreateLiteral.js"></script> > <script src="CreateLiteralType.js"></script> > <script src="PropertyAccessExpression.js"></script> >- <script src="SwizzleOp.js"></script> > <script src="NativeType.js"></script> > > <script src="AddressSpace.js"></script> >@@ -29,12 +28,10 @@ td { > <script src="Block.js"></script> > <script src="BoolLiteral.js"></script> > <script src="Break.js"></script> >- <script src="BuiltinVectorConstructors.js"></script> >+ <script src="BuiltinMatrixGetter.js"></script> >+ <script src="BuiltinMatrixSetter.js"></script> > <script src="BuiltinVectorGetter.js"></script> > <script src="BuiltinVectorSetter.js"></script> >- <script src="BuiltinVectorIndexGetter.js"></script> >- <script src="BuiltinVectorIndexSetter.js"></script> >- <script src="BuiltinVectorEqualityOperator.js"></script> > <script src="CallExpression.js"></script> > <script src="CallFunction.js"></script> > <script src="Check.js"></script> >@@ -96,6 +93,7 @@ td { > <script src="LoopChecker.js"></script> > <script src="MakeArrayRefExpression.js"></script> > <script src="MakePtrExpression.js"></script> >+ <script src="MatrixType.js"></script> > <script src="NameContext.js"></script> > <script src="NameFinder.js"></script> > <script src="NameResolver.js"></script> >@@ -103,9 +101,8 @@ td { > <script src="NormalUsePropertyResolver.js"></script> > <script src="NullLiteral.js"></script> > <script src="NullType.js"></script> >- <script src="OperatorAnderIndex.js"></script> >+ <script src="OperatorAnderIndexer.js"></script> > <script src="OperatorArrayRefLength.js"></script> >- <script src="OperatorBool.js"></script> > <script src="OriginKind.js"></script> > <script src="OverloadResolutionFailure.js"></script> > <script src="Parse.js"></script> >@@ -133,7 +130,6 @@ td { > <script src="SynthesizeArrayOperatorLength.js"></script> > <script src="SynthesizeEnumFunctions.js"></script> > <script src="SynthesizeStructAccessors.js"></script> >- <script src="SynthesizeOperatorBool.js"></script> > <script src="SynthesizeCopyConstructorOperator.js"></script> > <script src="SynthesizeDefaultConstructorOperator.js"></script> > <script src="TernaryExpression.js"></script> >diff --git a/Tools/WebGPUShadingLanguageRI/StandardLibrary.js b/Tools/WebGPUShadingLanguageRI/StandardLibrary.js >index 8190a4356923a61e5485bdd4f180d1383774898b..6a33236617a431bd8239baa469d3ed80c1a9a02f 100644 >--- a/Tools/WebGPUShadingLanguageRI/StandardLibrary.js >+++ b/Tools/WebGPUShadingLanguageRI/StandardLibrary.js >@@ -24,183 +24,2100 @@ > */ > "use strict"; > >-// NOTE: The next line is line 28, and we rely on this in Prepare.js. >-let standardLibrary = ` >-// This is the WSL standard library. Implementations of all of these things are in >-// Intrinsics.js. >- >-// Need to bootstrap void first. >-native typedef void; >-native typedef bool; >-native typedef uchar; >-native typedef ushort; >-native typedef uint; >-native typedef char; >-native typedef short; >-native typedef int; >-native typedef half; >-native typedef float; >-native typedef atomic_int; >-native typedef atomic_uint; >- >-native typedef vector<bool, 2>; >-typedef bool2 = vector<bool, 2>; >-native typedef vector<bool, 3>; >-typedef bool3 = vector<bool, 3>; >-native typedef vector<bool, 4>; >-typedef bool4 = vector<bool, 4>; >-native typedef vector<uchar, 2>; >-typedef uchar2 = vector<uchar, 2>; >-native typedef vector<uchar, 3>; >-typedef uchar3 = vector<uchar, 3>; >-native typedef vector<uchar, 4>; >-typedef uchar4 = vector<uchar, 4>; >-native typedef vector<ushort, 2>; >-typedef ushort2 = vector<ushort, 2>; >-native typedef vector<ushort, 3>; >-typedef ushort3 = vector<ushort, 3>; >-native typedef vector<ushort, 4>; >-typedef ushort4 = vector<ushort, 4>; >-native typedef vector<uint, 2>; >-typedef uint2 = vector<uint, 2>; >-native typedef vector<uint, 3>; >-typedef uint3 = vector<uint, 3>; >-native typedef vector<uint, 4>; >-typedef uint4 = vector<uint, 4>; >-native typedef vector<char, 2>; >-typedef char2 = vector<char, 2>; >-native typedef vector<char, 3>; >-typedef char3 = vector<char, 3>; >-native typedef vector<char, 4>; >-typedef char4 = vector<char, 4>; >-native typedef vector<short, 2>; >-typedef short2 = vector<short, 2>; >-native typedef vector<short, 3>; >-typedef short3 = vector<short, 3>; >-native typedef vector<short, 4>; >-typedef short4 = vector<short, 4>; >-native typedef vector<int, 2>; >-typedef int2 = vector<int, 2>; >-native typedef vector<int, 3>; >-typedef int3 = vector<int, 3>; >-native typedef vector<int, 4>; >-typedef int4 = vector<int, 4>; >-native typedef vector<half, 2>; >-typedef half2 = vector<half, 2>; >-native typedef vector<half, 3>; >-typedef half3 = vector<half, 3>; >-native typedef vector<half, 4>; >-typedef half4 = vector<half, 4>; >-native typedef vector<float, 2>; >-typedef float2 = vector<float, 2>; >-native typedef vector<float, 3>; >-typedef float3 = vector<float, 3>; >-native typedef vector<float, 4>; >-typedef float4 = vector<float, 4>; >- >-native operator int(uint); >-native operator int(uchar); >-native operator int(float); >-native operator uint(int); >-native operator uint(uchar); >-native operator uint(float); >-native operator uchar(int); >-native operator uchar(uint); >-native operator uchar(float); >-native operator float(int); >-native operator float(uint); >-native operator float(uchar); >- >-native int operator+(int, int); >-native uint operator+(uint, uint); >-uchar operator+(uchar a, uchar b) { return uchar(uint(a) + uint(b)); } >-native float operator+(float, float); >-int operator++(int value) { return value + 1; } >-uint operator++(uint value) { return value + 1; } >-uchar operator++(uchar value) { return value + 1; } >-native int operator-(int, int); >-native uint operator-(uint, uint); >-uchar operator-(uchar a, uchar b) { return uchar(uint(a) - uint(b)); } >-native float operator-(float, float); >-int operator--(int value) { return value - 1; } >-uint operator--(uint value) { return value - 1; } >-uchar operator--(uchar value) { return value - 1; } >-native int operator*(int, int); >-native uint operator*(uint, uint); >-uchar operator*(uchar a, uchar b) { return uchar(uint(a) * uint(b)); } >-native float operator*(float, float); >-native int operator/(int, int); >-native uint operator/(uint, uint); >-uchar operator/(uchar a, uchar b) { return uchar(uint(a) / uint(b)); } >-native int operator&(int, int); >-native int operator|(int, int); >-native int operator^(int, int); >-native int operator~(int); >-native int operator<<(int, uint); >-native int operator>>(int, uint); >-native uint operator&(uint, uint); >-native uint operator|(uint, uint); >-native uint operator^(uint, uint); >-native uint operator~(uint); >-native uint operator<<(uint, uint); >-native uint operator>>(uint, uint); >-uchar operator&(uchar a, uchar b) { return uchar(uint(a) & uint(b)); } >-uchar operator|(uchar a, uchar b) { return uchar(uint(a) | uint(b)); } >-uchar operator^(uchar a, uchar b) { return uchar(uint(a) ^ uint(b)); } >-uchar operator~(uchar value) { return uchar(~uint(value)); } >-uchar operator<<(uchar a, uint b) { return uchar(uint(a) << (b & 7)); } >-uchar operator>>(uchar a, uint b) { return uchar(uint(a) >> (b & 7)); } >-native float operator/(float, float); >-native bool operator==(int, int); >-native bool operator==(uint, uint); >-bool operator==(uchar a, uchar b) { return uint(a) == uint(b); } >-native bool operator==(bool, bool); >-native bool operator==(float, float); >-native bool operator<(int, int); >-native bool operator<(uint, uint); >-bool operator<(uchar a, uchar b) { return uint(a) < uint(b); } >-native bool operator<(float, float); >-native bool operator<=(int, int); >-native bool operator<=(uint, uint); >-bool operator<=(uchar a, uchar b) { return uint(a) <= uint(b); } >-native bool operator<=(float, float); >-native bool operator>(int, int); >-native bool operator>(uint, uint); >-bool operator>(uchar a, uchar b) { return uint(a) > uint(b); } >-native bool operator>(float, float); >-native bool operator>=(int, int); >-native bool operator>=(uint, uint); >-bool operator>=(uchar a, uchar b) { return uint(a) >= uint(b); } >-native bool operator>=(float, float); >- >-bool operator&(bool a, bool b) >-{ >- if (a) >- return b; >- return false; >-} >- >-bool operator|(bool a, bool b) >-{ >- if (a) >- return true; >- if (b) >- return true; >- return false; >-} >- >-bool operator^(bool a, bool b) >-{ >- if (a) >- return !b; >- return b; >-} >- >-bool operator~(bool value) >-{ >- return !value; >-} >-`; >+let standardLibrary = (function() { >+ let result = ""; >+ function print(s) >+ { >+ if (s) >+ result += s; >+ result += "\n"; >+ } >+ (function() { >+ print(`// This was autogenerated from Generate_Standard_Library.swift! Do not edit!!`); >+ print(); >+ >+ for (var type of [`void`, `bool`, `uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`, `atomic_int`, `atomic_uint`]) { >+ print(`native typedef ${type};`); >+ } >+ for (var type of [`bool`, `uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) { >+ for (var size of [2, 3, 4]) { >+ print(`native typedef vector<${type}, ${size}>;`); >+ print(`typedef ${type}${size} = vector<${type}, ${size}>;`); >+ } >+ } >+ print(); >+ >+ for (var type of [`half`, `float`]) { >+ for (var i of [2, 3, 4]) { >+ for (var j of [2, 3, 4]) { >+ print(`native typedef matrix<${type}, ${i}, ${j}>;`); >+ print(`typedef ${type}${i}x${j} = matrix<${type}, ${i}, ${j}>;`); >+ } >+ } >+ } >+ print(`native typedef sampler;`); >+ for (var type of [`Texture1D`, `RWTexture1D`, `Texture1DArray`, `RWTexture1DArray`, `Texture2D`, `RWTexture2D`, `Texture2DArray`, `RWTexture2DArray`, `Texture3D`, `RWTexture3D`, `TextureCube`]) { >+ for (var typeArgumentBase of [`bool`, `uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) { >+ for (var size of [``, `2`, `3`, `4`]) { >+ print(`native typedef ${type}<${typeArgumentBase}${size}>;`); >+ } >+ } >+ } >+ for (var type of [`TextureDepth2D`, `RWTextureDepth2D`, `TextureDepth2DArray`, `RWTextureDepth2DArray`, `TextureDepthCube`]) { >+ for (var typeArgument of [`float`, `half`]) { >+ print(`native typedef ${type}<${typeArgument}>;`); >+ } >+ } >+ print(); >+ >+ for (var type1 of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) { >+ for (var type2 of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) { >+ if (type1 != type2) { >+ print(`native operator ${type1}(${type2});`); >+ } >+ } >+ } >+ print(); >+ >+ for (var type of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) { >+ print(`operator bool(${type} x) {`); >+ print(` return x != 0;`); >+ print(`}`); >+ } >+ print(); >+ >+ print(`native operator int(atomic_int);`); >+ print(`native operator uint(atomic_uint);`); >+ print(); >+ >+ print(`native bool operator==(bool, bool);`); >+ >+ print(`bool operator&(bool a, bool b) {`); >+ print(` return a && b;`); >+ print(`}`); >+ >+ print(`bool operator|(bool a, bool b) {`); >+ print(` return a || b;`); >+ print(`}`); >+ >+ print(`bool operator^(bool a, bool b) {`); >+ print(` if (a)`); >+ print(` return !b;`); >+ print(` return b;`); >+ print(`}`); >+ >+ print(`bool operator~(bool value) {`); >+ print(` return !value;`); >+ print(`}`); >+ >+ for (var type of [`int`, `uint`, `float`]) { >+ print(`native ${type} operator+(${type}, ${type});`); >+ print(`native ${type} operator-(${type}, ${type});`); >+ print(`native ${type} operator*(${type}, ${type});`); >+ print(`native ${type} operator/(${type}, ${type});`); >+ print(`native bool operator==(${type}, ${type});`); >+ print(`native bool operator<(${type}, ${type});`); >+ print(`native bool operator<=(${type}, ${type});`); >+ print(`native bool operator>(${type}, ${type});`); >+ print(`native bool operator>=(${type}, ${type});`); >+ } >+ >+ for (var type of [`int`, `uint`]) { >+ print(`native ${type} operator&(${type}, ${type});`); >+ print(`native ${type} operator|(${type}, ${type});`); >+ print(`native ${type} operator^(${type}, ${type});`); >+ print(`native ${type} operator~(${type});`); >+ print(`native ${type} operator<<(${type}, uint);`); >+ print(`native ${type} operator>>(${type}, uint);`); >+ } >+ >+ for (var type of [`uchar`, `ushort`]) { >+ print(`${type} operator+(${type} a, ${type} b) {`); >+ print(` return ${type}(uint(a) + uint(b));`); >+ print(`}`); >+ print(`${type} operator-(${type} a, ${type} b) {`); >+ print(` return ${type}(uint(a) - uint(b));`); >+ print(`}`); >+ print(`${type} operator*(${type} a, ${type} b) {`); >+ print(` return ${type}(uint(a) * uint(b));`); >+ print(`}`); >+ print(`${type} operator/(${type} a, ${type} b) {`); >+ print(` return ${type}(uint(a) / uint(b));`); >+ print(`}`); >+ print(`${type} operator&(${type} a, ${type} b) {`); >+ print(` return ${type}(uint(a) & uint(b));`); >+ print(`}`); >+ print(`${type} operator|(${type} a, ${type} b) {`); >+ print(` return ${type}(uint(a) | uint(b));`); >+ print(`}`); >+ print(`${type} operator^(${type} a, ${type} b) {`); >+ print(` return ${type}(uint(a) ^ uint(b));`); >+ print(`}`); >+ print(`${type} operator~(${type} a) {`); >+ print(` return ${type}(~uint(a));`); >+ print(`}`); >+ print(`bool operator==(${type} a, ${type} b) {`); >+ print(` return uint(a) == uint(b);`); >+ print(`}`); >+ print(`bool operator<(${type} a, ${type} b) {`); >+ print(` return uint(a) < uint(b);`); >+ print(`}`); >+ print(`bool operator<=(${type} a, ${type} b) {`); >+ print(` return uint(a) <= uint(b);`); >+ print(`}`); >+ print(`bool operator>(${type} a, ${type} b) {`); >+ print(` return uint(a) > uint(b);`); >+ print(`}`); >+ print(`bool operator>=(${type} a, ${type} b) {`); >+ print(` return uint(a) >= uint(b);`); >+ print(`}`); >+ } >+ print(`uchar operator<<(uchar a, uint b) {`); >+ print(` return uchar(uint(a) << (b & 255));`); >+ print(`}`); >+ print(`ushort operator<<(ushort a, uint b) {`); >+ print(` return ushort(uint(a) << (b & 65535));`); >+ print(`}`); >+ print(`uchar operator>>(uchar a, uint b) {`); >+ print(` return uchar(uint(a) >> (b & 255));`); >+ print(`}`); >+ print(`ushort operator>>(ushort a, uint b) {`); >+ print(` return ushort(uint(a) >> (b & 65535));`); >+ print(`}`); >+ >+ for (var type of [`char`, `short`]) { >+ print(`${type} operator+(${type} a, ${type} b) {`); >+ print(` return ${type}(int(a) + int(b));`); >+ print(`}`); >+ print(`${type} operator-(${type} a, ${type} b) {`); >+ print(` return ${type}(int(a) - int(b));`); >+ print(`}`); >+ print(`${type} operator*(${type} a, ${type} b) {`); >+ print(` return ${type}(int(a) * int(b));`); >+ print(`}`); >+ print(`${type} operator/(${type} a, ${type} b) {`); >+ print(` return ${type}(int(a) / int(b));`); >+ print(`}`); >+ print(`${type} operator&(${type} a, ${type} b) {`); >+ print(` return ${type}(int(a) & int(b));`); >+ print(`}`); >+ print(`${type} operator|(${type} a, ${type} b) {`); >+ print(` return ${type}(int(a) | int(b));`); >+ print(`}`); >+ print(`${type} operator^(${type} a, ${type} b) {`); >+ print(` return ${type}(int(a) ^ int(b));`); >+ print(`}`); >+ print(`${type} operator~(${type} a) {`); >+ print(` return ${type}(~int(a));`); >+ print(`}`); >+ print(`bool operator==(${type} a, ${type} b) {`); >+ print(` return int(a) == int(b);`); >+ print(`}`); >+ print(`bool operator>(${type} a, ${type} b) {`); >+ print(` return int(a) > int(b);`); >+ print(`}`); >+ print(`bool operator>=(${type} a, ${type} b) {`); >+ print(` return int(a) >= int(b);`); >+ print(`}`); >+ print(`bool operator<(${type} a, ${type} b) {`); >+ print(` return int(a) < int(b);`); >+ print(`}`); >+ print(`bool operator<=(${type} a, ${type} b) {`); >+ print(` return int(a) <= int(b);`); >+ print(`}`); >+ } >+ print(`char operator<<(char a, uint b) {`); >+ print(` return char(int(a) << (b & 255));`); >+ print(`}`); >+ print(`short operator<<(short a, uint b) {`); >+ print(` return short(int(a) << (b & 65535));`); >+ print(`}`); >+ print(`char operator>>(char a, uint b) {`); >+ print(` return char(int(a) >> (b & 255));`); >+ print(`}`); >+ print(`short operator>>(short a, uint b) {`); >+ print(` return short(int(a) >> (b & 65535));`); >+ print(`}`); >+ >+ for (var type of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) { >+ print(`${type} operator++(${type} value) {`); >+ print(` return value + 1;`); >+ print(`}`); >+ print(`${type} operator--(${type} value) {`); >+ print(` return value - 1;`); >+ print(`}`); >+ } >+ >+ print(`half operator+(half a, half b) {`); >+ print(` return half(float(a) + float(b));`); >+ print(`}`); >+ print(`half operator-(half a, half b) {`); >+ print(` return half(float(a) - float(b));`); >+ print(`}`); >+ print(`half operator*(half a, half b) {`); >+ print(` return half(float(a) * float(b));`); >+ print(`}`); >+ print(`half operator/(half a, half b) {`); >+ print(` return half(float(a) / float(b));`); >+ print(`}`); >+ print(`bool operator==(half a, half b) {`); >+ print(` return float(a) == float(b);`); >+ print(`}`); >+ print(`bool operator<(half a, half b) {`); >+ print(` return float(a) < float(b);`); >+ print(`}`); >+ print(`bool operator<=(half a, half b) {`); >+ print(` return float(a) <= float(b);`); >+ print(`}`); >+ print(`bool operator>(half a, half b) {`); >+ print(` return float(a) < float(b);`); >+ print(`}`); >+ print(`bool operator>=(half a, half b) {`); >+ print(` return float(a) <= float(b);`); >+ print(`}`); >+ print(`char operator-(char x) {`); >+ print(` return char(-int(x));`); >+ print(`}`); >+ print(`short operator-(short x) {`); >+ print(` return short(-int(x));`); >+ print(`}`); >+ print(`half operator-(half x) {`); >+ print(` return half(-float(x));`); >+ print(`}`); >+ print(`native int operator-(int);`); >+ print(`native float operator-(float);`); >+ print(); >+ >+ for (var type of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) { >+ for (var size of [2, 3, 4]) { >+ print(`${type}${size} operator+(${type}${size} a, ${type}${size} b) {`); >+ print(` ${type}${size} result;`); >+ for (var m = 0; m < size; ++m) { >+ print(` result[${m}] = a[${m}] + b[${m}];`); >+ } >+ print(` return result;`); >+ print(`}`); >+ print(`${type}${size} operator-(${type}${size} a, ${type}${size} b) {`); >+ print(` ${type}${size} result;`); >+ for (var m = 0; m < size; ++m) { >+ print(` result[${m}] = a[${m}] - b[${m}];`); >+ } >+ print(` return result;`); >+ print(`}`); >+ print(`${type}${size} operator*(${type}${size} a, ${type}${size} b) {`); >+ print(` ${type}${size} result;`); >+ for (var m = 0; m < size; ++m) { >+ print(` result[${m}] = a[${m}] * b[${m}];`); >+ } >+ print(` return result;`); >+ print(`}`); >+ print(`${type}${size} operator*(${type}${size} a, ${type} b) {`); >+ print(` ${type}${size} result;`); >+ for (var m = 0; m < size; ++m) { >+ print(` result[${m}] = a[${m}] * b;`); >+ } >+ print(` return result;`); >+ print(`}`); >+ print(`${type}${size} operator*(${type} a, ${type}${size} b) {`); >+ print(` ${type}${size} result;`); >+ for (var m = 0; m < size; ++m) { >+ print(` result[${m}] = a * b[${m}];`); >+ } >+ print(` return result;`); >+ print(`}`); >+ print(`${type}${size} operator/(${type}${size} a, ${type}${size} b) {`); >+ print(` ${type}${size} result;`); >+ for (var m = 0; m < size; ++m) { >+ print(` result[${m}] = a[${m}] / b[${m}];`); >+ } >+ print(` return result;`); >+ print(`}`); >+ print(`${type}${size} operator/(${type}${size} a, ${type} b) {`); >+ print(` ${type}${size} result;`); >+ for (var m = 0; m < size; ++m) { >+ print(` result[${m}] = a[${m}] / b;`); >+ } >+ print(` return result;`); >+ print(`}`); >+ print(`${type}${size} operator/(${type} a, ${type}${size} b) {`); >+ print(` ${type}${size} result;`); >+ for (var m = 0; m < size; ++m) { >+ print(` result[${m}] = a / b[${m}];`); >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ } >+ for (var type of [`char`, `short`, `int`, `half`, `float`]) { >+ for (var size of [2, 3, 4]) { >+ print(`${type}${size} operator-(${type}${size} a) {`); >+ print(` ${type}${size} result;`); >+ for (var m = 0; m < size; ++m) { >+ print(` result[${m}] = -a[${m}];`); >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ } >+ for (var type of [`half`, `float`]) { >+ for (var i of [2, 3, 4]) { >+ for (var j of [2, 3, 4]) { >+ print(`${type}${i}x${j} operator+(${type}${i}x${j} a, ${type}${i}x${j} b) {`); >+ print(` ${type}${i}x${j} result;`); >+ for (var m = 0; m < i; ++m) { >+ for (var n = 0; n < j; ++n) { >+ print(` result[${m}][${n}] = a[${m}][${n}] + b[${m}][${n}];`); >+ } >+ } >+ print(` return result;`); >+ print(`}`); >+ print(`${type}${i}x${j} operator-(${type}${i}x${j} a, ${type}${i}x${j} b) {`); >+ print(` ${type}${i}x${j} result;`); >+ for (var m = 0; m < i; ++m) { >+ for (var n = 0; n < j; ++n) { >+ print(` result[${m}][${n}] = a[${m}][${n}] - b[${m}][${n}];`); >+ } >+ } >+ print(` return result;`); >+ print(`}`); >+ print(`${type}${i}x${j} operator-(${type}${i}x${j} a) {`); >+ print(` ${type}${i}x${j} result;`); >+ for (var m = 0; m < i; ++m) { >+ for (var n = 0; n < j; ++n) { >+ print(` result[${m}][${n}] = -a[${m}][${n}];`); >+ } >+ } >+ print(` return result;`); >+ print(`}`); >+ print(`${type}${i}x${j} operator*(${type}${i}x${j} a, ${type}${i}x${j} b) {`); >+ print(` ${type}${i}x${j} result;`); >+ for (var m = 0; m < i; ++m) { >+ for (var n = 0; n < j; ++n) { >+ print(` result[${m}][${n}] = a[${m}][${n}] * b[${m}][${n}];`); >+ } >+ } >+ print(` return result;`); >+ print(`}`); >+ print(`${type}${i}x${j} operator*(${type}${i}x${j} a, ${type} b) {`); >+ print(` ${type}${i}x${j} result;`); >+ for (var m = 0; m < i; ++m) { >+ for (var n = 0; n < j; ++n) { >+ print(` result[${m}][${n}] = a[${m}][${n}] * b;`); >+ } >+ } >+ print(` return result;`); >+ print(`}`); >+ print(`${type}${i}x${j} operator*(${type} a, ${type}${i}x${j} b) {`); >+ print(` ${type}${i}x${j} result;`); >+ for (var m = 0; m < i; ++m) { >+ for (var n = 0; n < j; ++n) { >+ print(` result[${m}][${n}] = a * b[${m}][${n}];`); >+ } >+ } >+ print(` return result;`); >+ print(`}`); >+ print(`${type}${i}x${j} operator/(${type}${i}x${j} a, ${type}${i}x${j} b) {`); >+ print(` ${type}${i}x${j} result;`); >+ for (var m = 0; m < i; ++m) { >+ for (var n = 0; n < j; ++n) { >+ print(` result[${m}][${n}] = a[${m}][${n}] / b[${m}][${n}];`); >+ } >+ } >+ print(` return result;`); >+ print(`}`); >+ print(`${type}${i}x${j} operator/(${type}${i}x${j} a, ${type} b) {`); >+ print(` ${type}${i}x${j} result;`); >+ for (var m = 0; m < i; ++m) { >+ for (var n = 0; n < j; ++n) { >+ print(` result[${m}][${n}] = a[${m}][${n}] / b;`); >+ } >+ } >+ print(` return result;`); >+ print(`}`); >+ print(`${type}${i}x${j} operator/(${type} a, ${type}${i}x${j} b) {`); >+ print(` ${type}${i}x${j} result;`); >+ for (var m = 0; m < i; ++m) { >+ for (var n = 0; n < j; ++n) { >+ print(` result[${m}][${n}] = a / b[${m}][${n}];`); >+ } >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ } >+ } >+ >+ for (var type of [`bool`, `uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) { >+ print(`operator ${type}2(${type} x, ${type} y) {`); >+ print(` ${type}2 result;`); >+ print(` result.x = x;`); >+ print(` result.y = y;`); >+ print(` return result;`); >+ print(`}`); >+ print(`operator ${type}3(${type} x, ${type} y, ${type} z) {`); >+ print(` ${type}3 result;`); >+ print(` result.x = x;`); >+ print(` result.y = y;`); >+ print(` result.z = z;`); >+ print(` return result;`); >+ print(`}`); >+ print(`operator ${type}3(${type}2 x, ${type} y) {`); >+ print(` ${type}3 result;`); >+ print(` result.x = x.x;`); >+ print(` result.y = x.y;`); >+ print(` result.z = y;`); >+ print(` return result;`); >+ print(`}`); >+ print(`operator ${type}3(${type} x, ${type}2 y) {`); >+ print(` ${type}3 result;`); >+ print(` result.x = x;`); >+ print(` result.y = y.x;`); >+ print(` result.z = y.y;`); >+ print(` return result;`); >+ print(`}`); >+ print(`operator ${type}4(${type} x, ${type} y, ${type} z, ${type} w) {`); >+ print(` ${type}4 result;`); >+ print(` result.x = x;`); >+ print(` result.y = y;`); >+ print(` result.z = z;`); >+ print(` result.w = w;`); >+ print(` return result;`); >+ print(`}`); >+ print(`operator ${type}4(${type}2 x, ${type} y, ${type} z) {`); >+ print(` ${type}4 result;`); >+ print(` result.x = x.x;`); >+ print(` result.y = x.y;`); >+ print(` result.z = y;`); >+ print(` result.w = z;`); >+ print(` return result;`); >+ print(`}`); >+ print(`operator ${type}4(${type} x, ${type}2 y, ${type} z) {`); >+ print(` ${type}4 result;`); >+ print(` result.x = x;`); >+ print(` result.y = y.x;`); >+ print(` result.z = y.y;`); >+ print(` result.w = z;`); >+ print(` return result;`); >+ print(`}`); >+ print(`operator ${type}4(${type} x, ${type} y, ${type}2 z) {`); >+ print(` ${type}4 result;`); >+ print(` result.x = x;`); >+ print(` result.y = y;`); >+ print(` result.z = z.x;`); >+ print(` result.w = z.y;`); >+ print(` return result;`); >+ print(`}`); >+ print(`operator ${type}4(${type}2 x, ${type}2 y) {`); >+ print(` ${type}4 result;`); >+ print(` result.x = x.x;`); >+ print(` result.y = x.y;`); >+ print(` result.z = y.x;`); >+ print(` result.w = y.y;`); >+ print(` return result;`); >+ print(`}`); >+ print(`operator ${type}4(${type}3 x, ${type} y) {`); >+ print(` ${type}4 result;`); >+ print(` result.x = x.x;`); >+ print(` result.y = x.y;`); >+ print(` result.z = x.z;`); >+ print(` result.w = y;`); >+ print(` return result;`); >+ print(`}`); >+ print(`operator ${type}4(${type} x, ${type}3 y) {`); >+ print(` ${type}4 result;`); >+ print(` result.x = x;`); >+ print(` result.y = y.x;`); >+ print(` result.z = y.y;`); >+ print(` result.w = y.z;`); >+ print(` return result;`); >+ print(`}`); >+ print(`uint operator.length(${type}2) {`); >+ print(` return 2;`); >+ print(`}`); >+ print(`uint operator.length(${type}3) {`); >+ print(` return 3;`); >+ print(`}`); >+ print(`uint operator.length(${type}4) {`); >+ print(` return 4;`); >+ print(`}`); >+ } >+ print(); >+ >+ for (var type of [`half`, `float`]) { >+ let variables = [`a`, `b`, `c`, `d`]; >+ for (var m of [2, 3, 4]) { >+ for (var n of [2, 3, 4]) { >+ let signature = `operator ${type}${m}x${n}(`; >+ for (var i = 0; i < m; ++i) { >+ if (i != 0) { >+ signature += `, `; >+ } >+ signature += `${type}${n} ${variables[i]}`; >+ } >+ signature += `) {`; >+ print(signature); >+ print(` ${type}${m}x${n} result;`); >+ for (var i = 0; i < m; ++i) { >+ print(` result[${i}] = ${variables[i]};`); >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ } >+ } >+ print(); >+ >+ for (var type of [`bool`, `uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) { >+ print(`bool operator==(${type}2 a, ${type}2 b) {`); >+ print(` return a.x == b.x && a.y == b.y;`); >+ print(`}`); >+ print(`bool operator==(${type}3 a, ${type}3 b) {`); >+ print(` return a.x == b.x && a.y == b.y && a.z == b.z;`); >+ print(`}`); >+ print(`bool operator==(${type}4 a, ${type}4 b) {`); >+ print(` return a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w;`); >+ print(`}`); >+ print(`native ${type} operator.x(${type}2);`); >+ print(`native ${type} operator.y(${type}2);`); >+ print(`native ${type} operator.x(${type}3);`); >+ print(`native ${type} operator.y(${type}3);`); >+ print(`native ${type} operator.z(${type}3);`); >+ print(`native ${type} operator.x(${type}4);`); >+ print(`native ${type} operator.y(${type}4);`); >+ print(`native ${type} operator.z(${type}4);`); >+ print(`native ${type} operator.w(${type}4);`); >+ print(`native ${type}2 operator.x=(${type}2, ${type});`); >+ print(`native ${type}2 operator.y=(${type}2, ${type});`); >+ print(`native ${type}3 operator.x=(${type}3, ${type});`); >+ print(`native ${type}3 operator.y=(${type}3, ${type});`); >+ print(`native ${type}3 operator.z=(${type}3, ${type});`); >+ print(`native ${type}4 operator.x=(${type}4, ${type});`); >+ print(`native ${type}4 operator.y=(${type}4, ${type});`); >+ print(`native ${type}4 operator.z=(${type}4, ${type});`); >+ print(`native ${type}4 operator.w=(${type}4, ${type});`); >+ print(`${type} operator[](${type}2 v, uint index) {`); >+ print(` switch (index) {`); >+ print(` case 0:`); >+ print(` return v.x;`); >+ print(` case 1:`); >+ print(` return v.y;`); >+ print(` default:`); >+ print(` trap;`); >+ print(` }`); >+ print(`}`); >+ print(`${type} operator[](${type}3 v, uint index) {`); >+ print(` switch (index) {`); >+ print(` case 0:`); >+ print(` return v.x;`); >+ print(` case 1:`); >+ print(` return v.y;`); >+ print(` case 2:`); >+ print(` return v.z;`); >+ print(` default:`); >+ print(` trap;`); >+ print(` }`); >+ print(`}`); >+ print(`${type} operator[](${type}4 v, uint index) {`); >+ print(` switch (index) {`); >+ print(` case 0:`); >+ print(` return v.x;`); >+ print(` case 1:`); >+ print(` return v.y;`); >+ print(` case 2:`); >+ print(` return v.z;`); >+ print(` case 3:`); >+ print(` return v.w;`); >+ print(` default:`); >+ print(` trap;`); >+ print(` }`); >+ print(`}`); >+ print(`${type}2 operator[]=(${type}2 v, uint index, ${type} a) {`); >+ print(` switch (index) {`); >+ print(` case 0:`); >+ print(` v.x = a;`); >+ print(` break;`); >+ print(` case 1:`); >+ print(` v.y = a;`); >+ print(` break;`); >+ print(` default:`); >+ print(` trap;`); >+ print(` }`); >+ print(` return v;`); >+ print(`}`); >+ print(`${type}3 operator[]=(${type}3 v, uint index, ${type} a) {`); >+ print(` switch (index) {`); >+ print(` case 0:`); >+ print(` v.x = a;`); >+ print(` break;`); >+ print(` case 1:`); >+ print(` v.y = a;`); >+ print(` break;`); >+ print(` case 2:`); >+ print(` v.z = a;`); >+ print(` break;`); >+ print(` default:`); >+ print(` trap;`); >+ print(` }`); >+ print(` return v;`); >+ print(`}`); >+ print(`${type}4 operator[]=(${type}4 v, uint index, ${type} a) {`); >+ print(` switch (index) {`); >+ print(` case 0:`); >+ print(` v.x = a;`); >+ print(` break;`); >+ print(` case 1:`); >+ print(` v.y = a;`); >+ print(` break;`); >+ print(` case 2:`); >+ print(` v.z = a;`); >+ print(` break;`); >+ print(` case 3:`); >+ print(` v.w = a;`); >+ print(` break;`); >+ print(` default:`); >+ print(` trap;`); >+ print(` }`); >+ print(` return v;`); >+ print(`}`); >+ } >+ print(); >+ >+ for (var type of [`half`, `float`]) { >+ for (var m of [2, 3, 4]) { >+ for (var n of [2, 3, 4]) { >+ print(`native ${type}${n} operator[](${type}${m}x${n}, uint);`); >+ print(`native ${type}${m}x${n} operator[]=(${type}${m}x${n}, uint, ${type}${n});`); >+ } >+ } >+ } >+ print(); >+ >+ for (var type of [`half`, `float`]) { >+ for (var i of [2, 3, 4]) { >+ for (var j of [2, 3, 4]) { >+ print(`bool operator==(${type}${i}x${j} a, ${type}${i}x${j} b) {`); >+ print(` return`); >+ for (var m = 0; m < i; ++m) { >+ for (var n = 0; n < j; ++n) { >+ print(` a[${m}][${n}] == b[${m}][${n}] &&`); >+ } >+ } >+ print(` true;`); >+ print(`}`); >+ } >+ } >+ } >+ >+ function computeSwizzle(components, maxValue, maxLength) { >+ if (components.length == maxLength) { >+ return [components]; >+ } else { >+ let result = []; >+ for (var i = 0; i < maxValue; ++i) { >+ result = result.concat(computeSwizzle(components.concat([i]), maxValue, maxLength)); >+ } >+ return result; >+ } >+ } >+ >+ function component(value) { >+ switch (value) { >+ case 0: >+ return `x`; >+ case 1: >+ return `y`; >+ case 2: >+ return `z`; >+ case 3: >+ return `w`; >+ default: >+ fatalError(); >+ } >+ } >+ >+ function uniqueLength([Int]) { >+ let has0 = false; >+ let has1 = false; >+ let has2 = false; >+ let has3 = false; >+ for (var v of swizzle) { >+ switch (v) { >+ case 0: >+ has0 = true; >+ break; >+ case 1: >+ has1 = true; >+ break; >+ case 2: >+ has2 = true; >+ break; >+ case 3: >+ has3 = true; >+ break; >+ default: >+ fatalError(); >+ } >+ } >+ let result = 0; >+ if (has0) { >+ result += 1; >+ } >+ if (has1) { >+ result += 1; >+ } >+ if (has2) { >+ result += 1; >+ } >+ if (has3) { >+ result += 1; >+ } >+ return result; >+ } >+ >+ /* >+ for (var type of [`bool`, `uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) { >+ for (var size of [2, 3, 4]) { >+ for (var maxValue of [2, 3, 4]) { >+ for (var swizzle of computeSwizzle([], maxValue, size)) { >+ let swizzleName = swizzle.map(component).join(""); >+ print(`${type}${size} operator.${swizzleName}(${type}${maxValue} v) {`); >+ print(` ${type}${size} result;`); >+ for (var i = 0; i < size; ++i) { >+ print(` result.${component(i)} = v.${component(swizzle[i])};`); >+ } >+ print(` return result;`); >+ print(`}`); >+ if (uniqueLength(swizzle) == size) { >+ print(`${type}${maxValue} operator.${swizzleName}=(${type}${maxValue} v, ${type}${size} c) {`); >+ print(` ${type}${maxValue} result = v;`); >+ for (var i = 0; i < size; ++i) { >+ print(` result.${component(swizzle[i])} = c.${component(i)};`); >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ } >+ } >+ } >+ } >+ >+ // These functions are unary floating-point scalar functions, >+ // which can also be applied to vectors and matrices component-wise. >+ (function() { >+ let nativeFunctions = [`cos`, `sin`, `tan`, `acos`, `asin`, `atan`, `cosh`, `sinh`, `tanh`, `ceil`, `exp`, `floor`, `log`, `round`, `trunc`, `ddx`, `ddy`]; >+ let nonNativeFunctions = [`sqrt`, `log2`, `log10`, `frac`, `exp2`, `degrees`, `radians`, `rcp`, `rsqrt`, `saturate`, `ddx_coarse`, `ddx_fine`, `ddy_coarse`, `ddy_fine`, `fwidth`]; >+ >+ for (var nativeFunction of nativeFunctions) { >+ print(`native float ${nativeFunction}(float);`); >+ print(`half ${nativeFunction}(half x) {`); >+ print(` return half(${nativeFunction}(float(x)));`); >+ print(`}`); >+ } >+ >+ for (var type of [`half`, `float`]) { >+ print(`${type} sqrt(${type} x) {`); >+ print(` return pow(x, 0.5);`); >+ print(`}`); >+ print(`${type} log2(${type} x) {`); >+ print(` return log(x) / log(${type}(2));`); >+ print(`}`); >+ print(`${type} log10(${type} x) {`); >+ print(` return log(x) / log(${type}(10));`); >+ print(`}`); >+ print(`${type} frac(${type} x) {`); >+ print(` return x - floor(x);`); >+ print(`}`); >+ print(`${type} exp2(${type} x) {`); >+ print(` return exp(x * log(${type}(2)));`); >+ print(`}`); >+ print(`${type} degrees(${type} x) {`); >+ print(` return x * 180 / 3.14159;`); >+ print(`}`); >+ print(`${type} radians(${type} x) {`); >+ print(` return x * 3.14159 / 180;`); >+ print(`}`); >+ print(`${type} rcp(${type} x) {`); >+ print(` return 1 / x;`); >+ print(`}`); >+ print(`${type} rsqrt(${type} x) {`); >+ print(` return 1 / sqrt(x);`); >+ print(`}`); >+ print(`${type} saturate(${type} x) {`); >+ print(` return clamp(x, 0, 1);`); >+ print(`}`); >+ print(`${type} ddx_coarse(${type} x) {`); >+ print(` return ddx(x);`); >+ print(`}`); >+ print(`${type} ddx_fine(${type} x) {`); >+ print(` return ddx(x);`); >+ print(`}`); >+ print(`${type} ddy_coarse(${type} x) {`); >+ print(` return ddy(x);`); >+ print(`}`); >+ print(`${type} ddy_fine(${type} x) {`); >+ print(` return ddy(x);`); >+ print(`}`); >+ print(`${type} fwidth(${type} x) {`); >+ print(` return abs(ddx(x)) + abs(ddy(x));`); >+ print(`}`); >+ >+ for (var outputFunction of nativeFunctions.concat(nonNativeFunctions)) { >+ for (var size of [2, 3, 4]) { >+ print(`${type}${size} ${outputFunction}(${type}${size} x) {`); >+ print(` ${type}${size} result;`); >+ for (var i = 0; i < size; ++i) { >+ print(` result[${i}] = ${outputFunction}(x[${i}]);`); >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ for (var i of [2, 3, 4]) { >+ for (var j of [2, 3, 4]) { >+ print(`${type}${i}x${j} ${outputFunction}(${type}${i}x${j} x) {`); >+ print(` ${type}${i}x${j} result;`); >+ for (var m = 0; m < i; ++m) { >+ for (var n = 0; n < j; ++n) { >+ print(` result[${m}][${n}] = ${outputFunction}(x[${m}][${n}]);`); >+ } >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ } >+ } >+ print(); >+ } >+ })(); >+ >+ // These functions are binary floating-point scalar functions, >+ // which can also be applied to vectors and matrices component-wise. >+ (function() { >+ let nativeFunctions = [`pow`]; >+ >+ for (var nativeFunction of nativeFunctions) { >+ print(`native float ${nativeFunction}(float, float);`); >+ print(`half ${nativeFunction}(half x, half y) {`); >+ print(` return half(${nativeFunction}(float(x), float(y)));`); >+ print(`}`); >+ } >+ >+ for (var type of [`half`, `float`]) { >+ let nonNativeFunctions = [`step`, `ldexp`, `fmod`]; >+ >+ print(`${type} step(${type} y, ${type} x) {`); >+ print(` return x >= y ? 1 : 0;`); >+ print(`}`); >+ print(`${type} ldexp(${type} x, ${type} e) {`); >+ print(` return x * pow(2, e);`); >+ print(`}`); >+ print(`${type} fmod(${type} x, ${type} y) {`); >+ print(` uint whole = uint(x / y);`); >+ print(` ${type} multiple = ${type}(whole) * y;`); >+ print(` return x - multiple;`); >+ print(`}`); >+ >+ for (var outputFunction of nativeFunctions.concat(nonNativeFunctions)) { >+ for (var size of [2, 3, 4]) { >+ print(`${type}${size} ${outputFunction}(${type}${size} x, ${type}${size} y) {`); >+ print(` ${type}${size} result;`); >+ for (var i = 0; i < size; ++i) { >+ print(` result[${i}] = ${outputFunction}(x[${i}], y[${i}]);`); >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ for (var i of [2, 3, 4]) { >+ for (var j of [2, 3, 4]) { >+ print(`${type}${i}x${j} ${outputFunction}(${type}${i}x${j} x, ${type}${i}x${j} y) {`); >+ print(` ${type}${i}x${j} result;`); >+ for (var m = 0; m < i; ++m) { >+ for (var n = 0; n < j; ++n) { >+ print(` result[${m}][${n}] = ${outputFunction}(x[${m}][${n}], y[${m}][${n}]);`); >+ } >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ } >+ } >+ print(); >+ } >+ })(); >+ >+ // These functions are ternary floating-point scalar functions, >+ // which can also be applied to vectors and matrices component-wise. >+ for (var type of [`half`, `float`]) { >+ let nonNativeFunctions = [`smoothstep`, `lerp`, `fma`, `mad`]; >+ >+ print(`${type} smoothstep(${type} edge0, ${type} edge1, ${type} x) {`); >+ print(` ${type} t = clamp((x - edge0) / (edge1 - edge0), 0, 1);`); >+ print(` return t * t * (3 - 2 * t);`); >+ print(`}`); >+ print(`${type} lerp(${type} x, ${type} y, ${type} s) {`); >+ print(` return x * (1 - s) + y * s;`); >+ print(`}`); >+ print(`${type} fma(${type} x, ${type} y, ${type} z) {`); >+ print(` return x * y + z;`); >+ print(`}`); >+ print(`${type} mad(${type} x, ${type} y, ${type} z) {`); >+ print(` return x * y + z;`); >+ print(`}`); >+ >+ for (var nonNativeFunction of nonNativeFunctions) { >+ for (var size of [2, 3, 4]) { >+ print(`${type}${size} ${nonNativeFunction}(${type}${size} x, ${type}${size} y, ${type}${size} z) {`); >+ print(` ${type}${size} result;`); >+ for (var i = 0; i < size; ++i) { >+ print(` result[${i}] = ${nonNativeFunction}(x[${i}], y[${i}], z[${i}]);`); >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ for (var i of [2, 3, 4]) { >+ for (var j of [2, 3, 4]) { >+ print(`${type}${i}x${j} ${nonNativeFunction}(${type}${i}x${j} x, ${type}${i}x${j} y, ${type}${i}x${j} z) {`); >+ print(` ${type}${i}x${j} result;`); >+ for (var m = 0; m < i; ++m) { >+ for (var n = 0; n < j; ++n) { >+ print(` result[${m}][${n}] = ${nonNativeFunction}(x[${m}][${n}], y[${m}][${n}], z[${m}][${n}]);`); >+ } >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ } >+ } >+ print(); >+ } >+ >+ print(`native bool isnormal(half);`); >+ print(`native bool isnormal(float);`); >+ for (var type of [`half`, `float`]) { >+ for (var size of [2, 3, 4]) { >+ print(`bool${size} isnormal(${type}${size} x) {`); >+ print(` bool${size} result;`); >+ for (var i = 0; i < size; ++i) { >+ print(` result[${i}] = isnormal(x[${i}]);`); >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ print(); >+ } >+ >+ (function() { >+ let nativeFunctions = [`isfinite`, `isinf`, `isnan`]; >+ >+ for (var nativeFunction of nativeFunctions) { >+ print(`native bool ${nativeFunction}(float);`); >+ print(`bool ${nativeFunction}(half x) {`); >+ print(` return ${nativeFunction}(float(x));`); >+ print(`}`); >+ } >+ >+ for (var type of [`half`, `float`]) { >+ for (var nativeFunction of nativeFunctions) { >+ for (var size of [2, 3, 4]) { >+ print(`bool${size} ${nativeFunction}(${type}${size} x) {`); >+ print(` bool${size} result;`); >+ for (var i = 0; i < size; ++i) { >+ print(` result[${i}] = ${nativeFunction}(x[${i}]);`); >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ } >+ print(); >+ } >+ })() >+ >+ for (var type of [`half`, `float`]) { >+ let nonNativeFunctions = [`isordered`, `isunordered`]; >+ >+ print(`bool isordered(${type} x, ${type} y) {`); >+ print(` return (x == x) && (y == y);`); >+ print(`}`); >+ print(`bool isunordered(${type} x, ${type} y) {`); >+ print(` return isnan(x) || isnan(y);`); >+ print(`}`); >+ >+ for (var nonNativeFunction of nonNativeFunctions) { >+ for (var size of [2, 3, 4]) { >+ print(`bool${size} ${nonNativeFunction}(${type}${size} x, ${type}${size} y) {`); >+ print(` bool${size} result;`); >+ for (var i = 0; i < size; ++i) { >+ print(` result[${i}] = ${nonNativeFunction}(x[${i}], y[${i}]);`); >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ } >+ print(); >+ } >+ >+ print(`native float atan2(float, float);`); >+ print(`half atan2(half x, half y) {`); >+ print(` return half(atan2(float(x), float(y)));`); >+ print(`}`); >+ for (var type of [`half`, `float`]) { >+ for (var size of [2, 3, 4]) { >+ print(`${type}${size} atan2(${type}${size} x, ${type}${size} y) {`); >+ print(` ${type}${size} result;`); >+ for (var i = 0; i < size; ++i) { >+ print(` result[${i}] = atan2(x[${i}], y[${i}]);`); >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ for (var i of [2, 3, 4]) { >+ for (var j of [2, 3, 4]) { >+ print(`${type}${i}x${j} atan2(${type}${i}x${j} x, ${type}${i}x${j} y) {`); >+ print(` ${type}${i}x${j} result;`); >+ for (var m = 0; m < i; ++m) { >+ for (var n = 0; n < j; ++n) { >+ print(` result[${m}][${n}] = atan2(x[${m}][${n}], y[${m}][${n}]);`); >+ } >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ } >+ } >+ print(); >+ >+ for (var type of [`half`, `float`]) { >+ print(`void sincos(${type} x, thread ${type}* y, thread ${type}* z) {`); >+ print(` *y = sin(x);`); >+ print(` *z = cos(x);`); >+ print(`}`); >+ for (var size of [2, 3, 4]) { >+ print(`void sincos(${type}${size} x, thread ${type}${size}* y, thread ${type}${size}* z) {`); >+ // Can't take a pointer to a member of a vector. >+ print(` ${type} sinResult;`); >+ print(` ${type} cosResult;`); >+ for (var i = 0; i < size; ++i) { >+ print(` sincos(x[${i}], &sinResult, &cosResult);`); >+ print(` (*y)[${i}] = sinResult;`); >+ print(` (*z)[${i}] = cosResult;`); >+ } >+ print(`}`); >+ } >+ for (var i of [2, 3, 4]) { >+ for (var j of [2, 3, 4]) { >+ print(`void sincos(${type}${i}x${j} x, thread ${type}${i}x${j}* y, thread ${type}${i}x${j}* z) {`); >+ // Can't take a pointer to a member of a matrix. >+ print(` ${type} sinResult;`); >+ print(` ${type} cosResult;`); >+ for (var m = 0; m < i; ++m) { >+ for (var n = 0; n < j; ++n) { >+ print(` sincos(x[${m}][${n}], &sinResult, &cosResult);`); >+ print(` (*y)[${m}][${n}] = sinResult;`); >+ print(` (*z)[${m}][${n}] = cosResult;`); >+ } >+ } >+ print(`}`); >+ } >+ } >+ } >+ print(); >+ >+ for (var binaryFunction of [[`all`, `true`, `&&`], [`any`, `false`, `||`]]) { >+ print(`bool ${binaryFunction[0]}(bool x) {`); >+ print(` return x;`); >+ print(`}`); >+ for (var size of [2, 3, 4]) { >+ print(`bool ${binaryFunction[0]}(bool${size} x) {`); >+ print(` bool result = ${binaryFunction[1]};`); >+ for (var i = 0; i < size; ++i) { >+ print(` result = result ${binaryFunction[2]} (x[${i}]);`); >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ for (var type of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) { >+ print(`bool ${binaryFunction[0]}(${type} x) {`); >+ print(` return x != 0;`); >+ print(`}`); >+ for (var size of [2, 3, 4]) { >+ print(`bool ${binaryFunction[0]}(${type}${size} x) {`); >+ print(` bool result = ${binaryFunction[1]};`); >+ for (var i = 0; i < size; ++i) { >+ print(` result = result ${binaryFunction[2]} (x[${i}] != 0);`); >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ if (type == `half` || type == `float`) { >+ for (var i of [2, 3, 4]) { >+ for (var j of [2, 3, 4]) { >+ print(`bool ${binaryFunction[0]}(${type}${i}x${j} x) {`); >+ print(` bool result = ${binaryFunction[1]};`); >+ for (var m = 0; m < i; ++m) { >+ for (var n = 0; n < j; ++n) { >+ print(` result = result ${binaryFunction[2]} (x[${m}][${n}] != 0);`); >+ } >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ } >+ } >+ } >+ print(); >+ } >+ >+ for (var type of [`uchar`, `ushort`, `uint`]) { >+ print(`${type} abs(${type} x) {`); >+ print(` return x;`); >+ print(`}`); >+ } >+ for (var type of [`char`, `short`, `int`, `half`, `float`]) { >+ print(`${type} abs(${type} x) {`); >+ print(` if (x < 0)`); >+ print(` return -x;`); >+ print(` return x;`); >+ print(`}`); >+ } >+ for (var type of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) { >+ for (var size of [2, 3, 4]) { >+ print(`${type}${size} abs(${type}${size} x) {`); >+ print(` ${type}${size} result;`); >+ for (var i = 0; i < size; ++i) { >+ print(` result[${i}] = abs(x[${i}]);`); >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ if (type == `half` || type == `float`) { >+ for (var i of [2, 3, 4]) { >+ for (var j of [2, 3, 4]) { >+ print(`${type}${i}x${j} abs(${type}${i}x${j} x) {`); >+ print(` ${type}${i}x${j} result;`); >+ for (var m = 0; m < i; ++m) { >+ for (var n = 0; n < j; ++n) { >+ print(` result[${m}][${n}] = abs(x[${m}][${n}]);`); >+ } >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ } >+ } >+ } >+ print(); >+ >+ for (var type of [`uchar`, `ushort`, `uint`]) { >+ print(`${type} sign(${type} x) {`); >+ print(` return x == 0 ? 0 : 1;`); >+ print(`}`); >+ } >+ for (var type of [`char`, `short`, `int`, `half`, `float`]) { >+ print(`${type} sign(${type} x) {`); >+ print(` if (x < 0)`); >+ print(` return -1;`); >+ print(` if (x == 0)`); >+ print(` return 0;`); >+ print(` return 1;`); >+ print(`}`); >+ } >+ for (var type of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) { >+ for (var size of [2, 3, 4]) { >+ print(`${type}${size} sign(${type}${size} x) {`); >+ print(` ${type}${size} result;`); >+ for (var i = 0; i < size; ++i) { >+ print(` result[${i}] = sign(x[${i}]);`); >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ if (type == `half` || type == `float`) { >+ for (var i of [2, 3, 4]) { >+ for (var j of [2, 3, 4]) { >+ print(`${type}${i}x${j} sign(${type}${i}x${j} x) {`); >+ print(` ${type}${i}x${j} result;`); >+ for (var m = 0; m < i; ++m) { >+ for (var n = 0; n < j; ++n) { >+ print(` result[${m}][${n}] = sign(x[${m}][${n}]);`); >+ } >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ } >+ } >+ } >+ print(); >+ >+ for (var type of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) { >+ let nonNativeFunctions = [`min`, `max`]; >+ >+ print(`${type} min(${type} x, ${type} y) {`); >+ print(` return x > y ? y : x;`); >+ print(`}`); >+ print(`${type} max(${type} x, ${type} y) {`); >+ print(` return x > y ? x : y;`); >+ print(`}`); >+ >+ for (var nonNativeFunction of nonNativeFunctions) { >+ for (var size of [2, 3, 4]) { >+ print(`${type}${size} ${nonNativeFunction}(${type}${size} x, ${type}${size} y) {`); >+ print(` ${type}${size} result;`); >+ for (var i = 0; i < size; ++i) { >+ print(` result[${i}] = ${nonNativeFunction}(x[${i}], y[${i}]);`); >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ if (type == `half` || type == `float`) { >+ for (var i of [2, 3, 4]) { >+ for (var j of [2, 3, 4]) { >+ print(`${type}${i}x${j} ${nonNativeFunction}(${type}${i}x${j} x, ${type}${i}x${j} y) {`); >+ print(` ${type}${i}x${j} result;`); >+ for (var m = 0; m < i; ++m) { >+ for (var n = 0; n < j; ++n) { >+ print(` result[${m}][${n}] = ${nonNativeFunction}(x[${m}][${n}], y[${m}][${n}]);`); >+ } >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ } >+ } >+ } >+ print(); >+ } >+ >+ for (var type of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) { >+ let nonNativeFunctions = [`clamp`]; >+ >+ print(`${type} clamp(${type} x, ${type} lower, ${type} upper) {`); >+ print(` return max(min(upper, x), lower);`); >+ print(`}`); >+ >+ for (var nonNativeFunction of nonNativeFunctions) { >+ for (var size of [2, 3, 4]) { >+ print(`${type}${size} ${nonNativeFunction}(${type}${size} x, ${type}${size} y, ${type}${size} z) {`); >+ print(` ${type}${size} result;`); >+ for (var i = 0; i < size; ++i) { >+ print(` result[${i}] = ${nonNativeFunction}(x[${i}], y[${i}], z[${i}]);`); >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ if (type == `half` || type == `float`) { >+ for (var i of [2, 3, 4]) { >+ for (var j of [2, 3, 4]) { >+ print(`${type}${i}x${j} ${nonNativeFunction}(${type}${i}x${j} x, ${type}${i}x${j} y, ${type}${i}x${j} z) {`); >+ print(` ${type}${i}x${j} result;`); >+ for (var m = 0; m < i; ++m) { >+ for (var n = 0; n < j; ++n) { >+ print(` result[${m}][${n}] = ${nonNativeFunction}(x[${m}][${n}], y[${m}][${n}], z[${m}][${n}]);`); >+ } >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ } >+ } >+ } >+ print(); >+ } >+ >+ for (var type of [`half`, `float`]) { >+ print(`${type} modf(${type} x, thread ${type}* ip) {`); >+ print(` uint result = uint(x);`); >+ print(` *ip = x - ${type}(result);`); >+ print(` return ${type}(result);`); >+ print(`}`); >+ >+ for (var size of [2, 3, 4]) { >+ print(`${type}${size} modf(${type}${size} x, thread ${type}${size}* y) {`); >+ print(` ${type}${size} result;`); >+ // Can't take a pointer to a member of a vector. >+ print(` ${type} buffer;`); >+ for (var i = 0; i < size; ++i) { >+ print(` result[${i}] = modf(x[${i}], &buffer);`); >+ print(` (*y)[${i}] = buffer;`); >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ for (var i of [2, 3, 4]) { >+ for (var j of [2, 3, 4]) { >+ print(`${type}${i}x${j} modf(${type}${i}x${j} x, thread ${type}${i}x${j}* y) {`); >+ print(` ${type}${i}x${j} result;`); >+ // Can't take a pointer to a member of a matrix. >+ print(` ${type} buffer;`); >+ for (var m = 0; m < i; ++m) { >+ for (var n = 0; n < j; ++n) { >+ print(` result[${m}][${n}] = modf(x[${m}][${n}], &buffer);`); >+ print(` (*y)[${m}][${n}] = buffer;`); >+ } >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ } >+ print(); >+ } >+ >+ print(`uchar count_bits(uchar x) {`); >+ print(` return uchar(((x | uchar(1 << 0)) == 0 ? 0 : 1) +`); >+ for (var i = 1; i < 7; ++i) { >+ print(` ((x | uchar(1 << ${i})) == 0 ? 0 : 1) +`); >+ } >+ print(` ((x | uchar(1 << 7)) == 0 ? 0 : 1));`); >+ print(`}`); >+ print(`uchar count_bits(ushort x) {`); >+ print(` return uchar(((x | ushort(1 << 0)) == 0 ? 0 : 1) +`); >+ for (var i = 1; i < 15; ++i) { >+ print(` ((x | ushort(1 << ${i})) == 0 ? 0 : 1) +`); >+ } >+ print(` ((x | ushort(1 << 15)) == 0 ? 0 : 1));`); >+ print(`}`); >+ print(`uchar count_bits(uint x) {`); >+ print(` return uchar(((x | uint(1 << 0)) == 0 ? 0 : 1) +`); >+ for (var i = 1; i < 31; ++i) { >+ print(` ((x | uint(1 << ${i})) == 0 ? 0 : 1) +`); >+ } >+ print(` ((x | uint(1 << 31)) == 0 ? 0 : 1));`); >+ print(`}`); >+ print(`uchar reversebits(uchar x) {`); >+ print(` return uchar(((x & uchar(1 << 0)) << 7) |`); >+ for (var i = 1; i < 7; ++i) { >+ let offset = 7 - 2 * i >+ print(` ((x & uchar(1 << ${i})) ${offset > 0 ? `<<` : `>>`} ${Math.abs(offset)}) |`); >+ } >+ print(` ((x & uchar(1 << 7)) >> 7));`); >+ print(`}`); >+ print(`ushort reversebits(ushort x) {`); >+ print(` return ushort(((x & ushort(1 << 0)) << 15) |`); >+ for (var i = 1; i < 15; ++i) { >+ let offset = 15 - 2 * i >+ print(` ((x & ushort(1 << ${i})) ${offset > 0 ? `<<` : `>>`} ${Math.abs(offset)}) |`); >+ } >+ print(` ((x & ushort(1 << 15)) >> 15));`); >+ print(`}`); >+ print(`uint reversebits(uint x) {`); >+ print(` return uint(((x & uint(1 << 0)) << 31) |`); >+ for (var i = 1; i < 31; ++i) { >+ let offset = 31 - 2 * i >+ print(` ((x & uint(1 << ${i})) ${offset > 0 ? `<<` : `>>`} ${Math.abs(offset)}) |`); >+ } >+ print(` ((x & uint(1 << 31)) >> 31));`); >+ print(`}`); >+ for (var type of [`uchar`, `ushort`, `uint`]) { >+ for (var size of [2, 3, 4]) { >+ print(`uchar${size} count_bits(${type}${size} x) {`); >+ print(` uchar${size} result;`); >+ for (var i = 0; i < size; ++i) { >+ print(` result[${i}] = count_bits(x[${i}]);`); >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ } >+ for (var type of [`uchar`, `ushort`, `uint`]) { >+ for (var size of [2, 3, 4]) { >+ print(`${type}${size} reversebits(${type}${size} x) {`); >+ print(` ${type}${size} result;`); >+ for (var i = 0; i < size; ++i) { >+ print(` result[${i}] = reversebits(x[${i}]);`); >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ } >+ print(); >+ >+ print(`uint firstbithigh(uchar x) {`); >+ for (var i = 0; i <= 7; ++i) { >+ print(` if ((x & uchar(1 << ${7 - i})) != 0)`); >+ print(` return ${i};`); >+ } >+ print(` return 8;`); >+ print(`}`); >+ print(`uint firstbithigh(ushort x) {`); >+ for (var i = 0; i <= 15; ++i) { >+ print(` if ((x & ushort(1 << ${15 - i})) != 0)`); >+ print(` return ${i};`); >+ } >+ print(` return 16;`); >+ print(`}`); >+ print(`uint firstbithigh(uint x) {`); >+ for (var i = 0; i <= 31; ++i) { >+ print(` if ((x & uint(1 << ${31 - i})) != 0)`); >+ print(` return ${i};`); >+ } >+ print(` return 32;`); >+ print(`}`); >+ print(`uint firstbithigh(char x) {`); >+ print(` return firstbithigh(uchar(x));`); >+ print(`}`); >+ print(`uint firstbithigh(short x) {`); >+ print(` return firstbithigh(ushort(x));`); >+ print(`}`); >+ print(`uint firstbithigh(int x) {`); >+ print(` return firstbithigh(uint(x));`); >+ print(`}`); >+ print(`uint firstbitlow(uchar x) {`); >+ for (var i = 0; i <= 7; ++i) { >+ print(` if ((x & uchar(1 << ${i})) != 0)`); >+ print(` return ${7 - i};`); >+ } >+ print(` return 8;`); >+ print(`}`); >+ print(`uint firstbitlow(ushort x) {`); >+ for (var i = 0; i <= 15; ++i) { >+ print(` if ((x & ushort(1 << ${i})) != 0)`); >+ print(` return ${15 - i};`); >+ } >+ print(` return 16;`); >+ print(`}`); >+ print(`uint firstbitlow(uint x) {`); >+ for (var i = 0; i <= 31; ++i) { >+ print(` if ((x & uint(1 << ${i})) != 0)`); >+ print(` return ${31 - i};`); >+ } >+ print(` return 32;`); >+ print(`}`); >+ print(`uint firstbitlow(char x) {`); >+ print(` return firstbitlow(uchar(x));`); >+ print(`}`); >+ print(`uint firstbitlow(short x) {`); >+ print(` return firstbitlow(ushort(x));`); >+ print(`}`); >+ print(`uint firstbitlow(int x) {`); >+ print(` return firstbitlow(uint(x));`); >+ print(`}`); >+ for (var functionName of [`firstbithigh`, `firstbitlow`]) { >+ for (var type of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`]) { >+ for (var size of [2, 3, 4]) { >+ print(`uint${size} ${functionName}(${type}${size} x) {`); >+ print(` uint${size} result;`); >+ for (var i = 0; i < size; ++i) { >+ print(` result[${i}] = ${functionName}(x[${i}]);`); >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ } >+ } >+ print(); >+ >+ // Row-major, so the first index selects which row, and the second index selects which column >+ for (var type of [`half`, `float`]) { >+ print(`${type} determinant(${type} x) {`); >+ print(` return x;`); >+ print(`}`); >+ print(`${type} determinant(${type}2x2 x) {`); >+ print(` return x[0][0] * x[1][1] - x[0][1] * x[1][0];`); >+ print(`}`); >+ print(`${type} determinant(${type}3x3 x) {`); >+ print(` return x[0][0] * x[1][1] * x[2][2] +`); >+ print(` x[0][1] * x[1][2] * x[2][0] +`); >+ print(` x[0][2] * x[1][0] * x[2][1] -`); >+ print(` x[2][0] * x[1][1] * x[0][2] -`); >+ print(` x[2][1] * x[1][2] * x[0][0] -`); >+ print(` x[2][2] * x[1][0] * x[0][1];`); >+ print(`}`); >+ print(`${type} determinant(${type}4x4 x) {`); >+ print(` ${type} result;`); >+ print(` ${type}3x3 minor;`); >+ print(` minor[0][0] = x[1][1];`); >+ print(` minor[0][1] = x[1][2];`); >+ print(` minor[0][2] = x[1][3];`); >+ print(` minor[1][0] = x[2][1];`); >+ print(` minor[1][1] = x[2][2];`); >+ print(` minor[1][2] = x[2][3];`); >+ print(` minor[2][0] = x[3][1];`); >+ print(` minor[2][1] = x[3][2];`); >+ print(` minor[2][2] = x[3][3];`); >+ print(` result = result + x[0][0] * determinant(minor);`); >+ print(` minor[0][0] = x[1][0];`); >+ print(` minor[0][1] = x[1][2];`); >+ print(` minor[0][2] = x[1][3];`); >+ print(` minor[1][0] = x[2][0];`); >+ print(` minor[1][1] = x[2][2];`); >+ print(` minor[1][2] = x[2][3];`); >+ print(` minor[2][0] = x[3][0];`); >+ print(` minor[2][1] = x[3][2];`); >+ print(` minor[2][2] = x[3][3];`); >+ print(` result = result - x[0][1] * determinant(minor);`); >+ print(` minor[0][0] = x[1][0];`); >+ print(` minor[0][1] = x[1][1];`); >+ print(` minor[0][2] = x[1][3];`); >+ print(` minor[1][0] = x[2][0];`); >+ print(` minor[1][1] = x[2][1];`); >+ print(` minor[1][2] = x[2][3];`); >+ print(` minor[2][0] = x[3][0];`); >+ print(` minor[2][1] = x[3][1];`); >+ print(` minor[2][2] = x[3][3];`); >+ print(` result = result + x[0][2] * determinant(minor);`); >+ print(` minor[0][0] = x[1][0];`); >+ print(` minor[0][1] = x[1][1];`); >+ print(` minor[0][2] = x[1][2];`); >+ print(` minor[1][0] = x[2][0];`); >+ print(` minor[1][1] = x[2][1];`); >+ print(` minor[1][2] = x[2][2];`); >+ print(` minor[2][0] = x[3][0];`); >+ print(` minor[2][1] = x[3][1];`); >+ print(` minor[2][2] = x[3][2];`); >+ print(` result = result - x[0][3] * determinant(minor);`); >+ print(` return result;`); >+ print(`}`); >+ } >+ print(); >+ >+ for (var type of [`uchar4`, `ushort4`, `uint4`, `char4`, `short4`, `int4`, `half4`, `float4`]) { >+ print(`${type} dst(${type} src0, ${type} src1) {`); >+ print(` ${type} result;`); >+ print(` result.x = 1;`); >+ print(` result.y = src0.y * src1.y;`); >+ print(` result.z = src0.z;`); >+ print(` result.w = src1.w;`); >+ print(` return result;`); >+ print(`}`); >+ } >+ print(); >+ >+ for (var type of [`half`, `float`]) { >+ print(`${type} distance(${type} x, ${type} y) {`); >+ print(` return length(x - y);`); >+ print(`}`); >+ for (var size of [2, 3, 4]) { >+ print(`${type} distance(${type}${size} x, ${type}${size} y) {`); >+ print(` return length(x - y);`); >+ print(`}`); >+ } >+ } >+ print(); >+ >+ for (var type of [`half3`, `float3`]) { >+ print(`${type} cross(${type} u, ${type} v) {`); >+ print(` ${type} result;`); >+ print(` result.x = u.y * v.z - u.z * v.y;`); >+ print(` result.y = u.z * v.x - u.x * v.z;`); >+ print(` result.z = u.x * v.y - u.y * v.x;`); >+ print(` return result;`); >+ print(`}`); >+ } >+ print(); >+ >+ for (var type of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) { >+ print(`${type} dot(${type} a, ${type} b) {`); >+ print(` return a * b;`); >+ print(`}`); >+ for (var size of [2, 3, 4]) { >+ print(`${type} dot(${type}${size} a, ${type}${size} b) {`); >+ print(` ${type} result = 0;`); >+ for (var i = 0; i < size; ++i) { >+ print(` result = result + a[${i}] * b[${i}];`); >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ } >+ print(); >+ >+ for (var type of [`half`, `float`]) { >+ for (var size of [``, `2`, `3`, `4`]) { >+ print(`${type}${size} faceforward(${type}${size} n, ${type}${size} i, ${type}${size} ng) {`); >+ print(` return -n * sign(dot(i, ng));`); >+ print(`}`); >+ } >+ } >+ print(); >+ >+ for (var type of [`half`, `float`]) { >+ for (var size of [``, `2`, `3`, `4`]) { >+ print(`${type} length(${type}${size} x) {`); >+ print(` return sqrt(dot(x, x));`); >+ print(`}`); >+ } >+ } >+ print(); >+ >+ for (var type of [`half`, `float`]) { >+ print(`${type}4 lit(${type} n_dot_l, ${type} n_dot_h, ${type} m) {`); >+ print(` ${type} ambient = 1;`); >+ print(` ${type} diffuse = max(0, n_dot_l);`); >+ print(` ${type} specular = n_dot_l < 0 || n_dot_h < 0 ? 0 : n_dot_h * m;`); >+ print(` ${type}4 result;`); >+ print(` result.x = ambient;`); >+ print(` result.y = diffuse;`); >+ print(` result.z = specular;`); >+ print(` result.w = 1;`); >+ print(` return result;`); >+ print(`}`); >+ } >+ print(); >+ >+ for (var type of [`half`, `float`]) { >+ for (var size of [``, `2`, `3`, `4`]) { >+ print(`${type}${size} normalize(${type}${size} x) {`); >+ print(` return x / length(x);`); >+ print(`}`); >+ } >+ } >+ print(); >+ >+ for (var type of [`half`, `float`]) { >+ for (var size of [``, `2`, `3`, `4`]) { >+ print(`${type}${size} reflect(${type}${size} i, ${type}${size} n) {`); >+ print(` return i - 2 * n * dot(i, n);`); >+ print(`}`); >+ } >+ } >+ print(); >+ >+ // OpenGL ES v3.30 section 8.4 >+ for (var type of [`half`, `float`]) { >+ for (var size of [``, `2`, `3`, `4`]) { >+ print(`${type}${size} refract(${type}${size} i, ${type}${size} n, ${type} eta) {`); >+ print(` ${type}${size} result;`); >+ print(` ${type} k = 1 - eta * eta * (1 - dot(n, i) * dot(n, i));`); >+ print(` if (k < 0)`); >+ print(` return result;`); >+ print(` return eta * i - (eta * dot(n, i) + sqrt(k)) * n;`); >+ print(`}`); >+ } >+ } >+ print(); >+ >+ for (var type of [`half`, `float`]) { >+ print(`${type} transpose(${type} x) {`); >+ print(` return x;`); >+ print(`}`); >+ for (var i of [2, 3, 4]) { >+ for (var j of [2, 3, 4]) { >+ print(`${type}${i}x${j} transpose(${type}${j}x${i} x) {`); >+ print(` ${type}${i}x${j} result;`); >+ for (var m = 0; m < i; ++m) { >+ for (var n = 0; n < j; ++n) { >+ print(` result[${m}][${n}] = x[${n}][${m}];`); >+ } >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ } >+ } >+ print(); >+ >+ for (var resultType of [`int`, `uint`, `float`]) { >+ for (var type of [`int`, `uint`, `float`]) { >+ if (type == resultType) { >+ print(`${resultType} as${resultType}(${type} x) {`); >+ print(` return x;`); >+ print(`}`); >+ } else if (resultType == `int` && type == `uint` || resultType == `uint` && type == `int`) { >+ print(`${resultType} as${resultType}(${type} x) {`); >+ print(` return ${resultType}(x);`); >+ print(`}`); >+ } else { >+ print(`native ${resultType} as${resultType}(${type});`); >+ } >+ for (var size of [2, 3, 4]) { >+ if (type == resultType) { >+ print(`${resultType}${size} as${resultType}(${type}${size} x) {`); >+ print(` return x;`); >+ print(`}`); >+ } else { >+ print(`${resultType}${size} as${resultType}(${type}${size} x) {`); >+ print(` ${resultType}${size} result;`); >+ for (var i = 0; i < size; ++i) { >+ print(` result[${i}] = as${resultType}(x[${i}]);`); >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ } >+ if (resultType == `float` && type == `float`) { >+ for (var i of [2, 3, 4]) { >+ for (var j of [2, 3, 4]) { >+ if (type == resultType) { >+ print(`${resultType}${i}x${j} as${resultType}(${type}${i}x${j} x) {`); >+ print(` return x;`); >+ print(`}`); >+ } else { >+ print(`${resultType}${i}x${j} as${resultType}(${type}${i}x${j} x) {`); >+ print(` ${resultType}${i}x${j} result;`); >+ for (var m = 0; m < i; ++m) { >+ for (var n = 0; n < j; ++n) { >+ print(` result[${m}][${n}] = as${resultType}(x[${m}][${n}]);`); >+ } >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ } >+ } >+ } >+ } >+ } >+ print(); >+ >+ print(`native float f16tof32(uint);`); >+ print(`native uint f32tof16(float);`); >+ for (var size of [2, 3, 4]) { >+ print(`float${size} f16tof32(uint${size} x) {`); >+ print(` float${size} result;`); >+ for (var i = 0; i < size; ++i) { >+ print(` result[${i}] = f16tof32(x[${i}]);`); >+ } >+ print(` return result;`); >+ print(`}`); >+ print(`uint${size} f32tof16(float${size} x) {`); >+ print(` uint${size} result;`); >+ for (var i = 0; i < size; ++i) { >+ print(` result[${i}] = f32tof16(x[${i}]);`); >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ print(); >+ >+ print(`native void AllMemoryBarrierWithGroupSync();`); >+ print(`native void DeviceMemoryBarrierWithGroupSync();`); >+ print(`native void GroupMemoryBarrierWithGroupSync();`); >+ print(); >+ >+ for (var type of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) { >+ print(`${type} mul(${type} x, ${type} y) {`); >+ print(` return x * y;`); >+ print(`}`); >+ } >+ >+ for (var type of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) { >+ for (var size of [2, 3, 4]) { >+ print(`${type}${size} mul(${type} x, ${type}${size} y) {`); >+ print(` ${type}${size} result;`); >+ for (var i = 0; i < size; ++i) { >+ print(` result[${i}] = x * y[${i}];`); >+ } >+ print(` return result;`); >+ print(`}`); >+ print(`${type}${size} mul(${type}${size} x, ${type} y) {`); >+ print(` ${type}${size} result;`); >+ for (var i = 0; i < size; ++i) { >+ print(` result[${i}] = x[${i}] * y;`); >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ } >+ >+ for (var type of [`half`, `float`]) { >+ for (var i of [2, 3, 4]) { >+ for (var j of [2, 3, 4]) { >+ print(`${type}${i}x${j} mul(${type} x, ${type}${i}x${j} y) {`); >+ print(` ${type}${i}x${j} result;`); >+ for (var m = 0; m < i; ++m) { >+ for (var n = 0; n < j; ++n) { >+ print(` result[${m}][${n}] = x * y[${m}][${n}];`); >+ } >+ } >+ print(` return result;`); >+ print(`}`); >+ print(`${type}${i}x${j} mul(${type}${i}x${j} x, ${type} y) {`); >+ print(` ${type}${i}x${j} result;`); >+ for (var m = 0; m < i; ++m) { >+ for (var n = 0; n < j; ++n) { >+ print(` result[${m}][${n}] = x[${m}][${n}] * y;`); >+ } >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ } >+ } >+ >+ for (var type of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) { >+ for (var size of [2, 3, 4]) { >+ print(`${type} mul(${type}${size} x, ${type}${size} y) {`); >+ print(` return dot(x, y);`); >+ print(`}`); >+ } >+ } >+ >+ for (var type of [`half`, `float`]) { >+ for (var i of [2, 3, 4]) { >+ for (var j of [2, 3, 4]) { >+ print(`${type}${j} mul(${type}${i} x, ${type}${i}x${j} y) {`); >+ print(` ${type}${j} result;`); >+ for (var m = 0; m < j; ++m) { >+ print(` result[${m}] = 0;`); >+ for (var n = 0; n < i; ++n) { >+ print(` result[${m}] += x[${n}] * y[${n}][${m}];`); >+ } >+ } >+ print(` return result;`); >+ print(`}`); >+ print(`${type}${i} mul(${type}${i}x${j} x, ${type}${j} y) {`); >+ print(` ${type}${i} result;`); >+ for (var m = 0; m < i; ++m) { >+ print(` result[${m}] = 0;`); >+ for (var n = 0; n < j; ++n) { >+ print(` result[${m}] += x[${m}][${n}] * y[${n}];`); >+ } >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ } >+ } >+ >+ for (var type of [`half`, `float`]) { >+ for (var i of [2, 3, 4]) { >+ for (var j of [2, 3, 4]) { >+ for (var k of [2, 3, 4]) { >+ print(`${type}${i}x${k} mul(${type}${i}x${j} x, ${type}${j}x${k} y) {`); >+ print(` ${type}${i}x${k} result;`); >+ for (var p = 0; p < i; ++p) { >+ for (var r = 0; r < k; ++r) { >+ print(` result[${p}][${k}] = 0;`); >+ for (var q = 0; q < j; ++q) { >+ print(` result[${p}][${k}] += x[${p}][${q}] * y[${q}][${r}];`); >+ } >+ } >+ } >+ print(` return result;`); >+ print(`}`); >+ } >+ } >+ } >+ } >+ print(); >+ >+ for (var type of [`uint`, `int`]) { >+ for (var functionName of [`Add`, `And`, `Exchange`, `Max`, `Min`, `Or`, `Xor`]) { >+ print(`native void Interlocked${functionName}(thread atomic_${type}*, ${type}, thread ${type}*);`); >+ } >+ print(`native void InterlockedCompareExchange(thread atomic_${type}*, ${type}, ${type}, thread ${type}*);`); >+ } >+ print(); >+ >+ for (var type of [`uchar`, `ushort`, `uint`, `char`, `short`, `int`, `half`, `float`]) { >+ for (var length of [``, `2`, `3`, `4`]) { >+ print(`native ${type}${length} Sample(Texture1D<${type}${length}>, sampler, float location);`); >+ print(`native ${type}${length} Sample(Texture1D<${type}${length}>, sampler, float location, int offset);`); >+ print(`native ${type}${length} Load(Texture1D<${type}${length}>, int2 location);`); >+ print(`native ${type}${length} Load(Texture1D<${type}${length}>, int2 location, int offset);`); >+ print(`native void GetDimensions(Texture1D<${type}${length}>, uint MipLevel, thread uint* Width, thread uint* NumberOfLevels);`); >+ print(); >+ print(`native ${type}${length} Sample(Texture1DArray<${type}${length}>, sampler, float2 location);`); >+ print(`native ${type}${length} Sample(Texture1DArray<${type}${length}>, sampler, float2 location, int offset);`); >+ print(`native ${type}${length} Load(Texture1DArray<${type}${length}>, int3 location);`); >+ print(`native ${type}${length} Load(Texture1DArray<${type}${length}>, int3 location, int offset);`); >+ print(`native void GetDimensions(Texture1DArray<${type}${length}>, uint MipLevel, thread uint* Width, thread uint* Elements, thread uint* NumberOfLevels);`); >+ print(); >+ print(`native ${type}${length} Sample(Texture2D<${type}${length}>, sampler, float2 location);`); >+ print(`native ${type}${length} Sample(Texture2D<${type}${length}>, sampler, float2 location, int2 offset);`); >+ print(`native ${type}${length} SampleBias(Texture2D<${type}${length}>, sampler, float2 location, float Bias);`); >+ print(`native ${type}${length} SampleBias(Texture2D<${type}${length}>, sampler, float2 location, float Bias, int2 offset);`); >+ print(`native ${type}${length} SampleGrad(Texture2D<${type}${length}>, sampler, float2 location, float2 DDX, float2 DDY);`); >+ print(`native ${type}${length} SampleGrad(Texture2D<${type}${length}>, sampler, float2 location, float2 DDX, float2 DDY, int2 offset);`); >+ print(`native ${type}${length} SampleLevel(Texture2D<${type}${length}>, sampler, float2 location, float LOD);`); >+ print(`native ${type}${length} SampleLevel(Texture2D<${type}${length}>, sampler, float2 location, float LOD, int2 offset);`); >+ print(`native ${type}4 Gather(Texture2D<${type}${length}>, sampler, float2 location);`); >+ print(`native ${type}4 Gather(Texture2D<${type}${length}>, sampler, float2 location, int2 offset);`); >+ print(`native ${type}4 GatherRed(Texture2D<${type}${length}>, sampler, float2 location);`); >+ print(`native ${type}4 GatherRed(Texture2D<${type}${length}>, sampler, float2 location, int2 offset);`); >+ print(`native ${type}4 GatherGreen(Texture2D<${type}${length}>, sampler, float2 location);`); >+ print(`native ${type}4 GatherGreen(Texture2D<${type}${length}>, sampler, float2 location, int2 offset);`); >+ print(`native ${type}4 GatherBlue(Texture2D<${type}${length}>, sampler, float2 location);`); >+ print(`native ${type}4 GatherBlue(Texture2D<${type}${length}>, sampler, float2 location, int2 offset);`); >+ print(`native ${type}4 GatherAlpha(Texture2D<${type}${length}>, sampler, float2 location);`); >+ print(`native ${type}4 GatherAlpha(Texture2D<${type}${length}>, sampler, float2 location, int2 offset);`); >+ print(`native ${type}${length} Load(Texture2D<${type}${length}>, int3 location);`); >+ print(`native ${type}${length} Load(Texture2D<${type}${length}>, int3 location, int2 offset);`); >+ print(`native void GetDimensions(Texture2D<${type}${length}>, uint MipLevel, thread uint* Width, thread uint* Height, thread uint* NumberOfLevels);`); >+ print(); >+ print(`native ${type}${length} Sample(Texture2DArray<${type}${length}>, sampler, float3 location);`); >+ print(`native ${type}${length} Sample(Texture2DArray<${type}${length}>, sampler, float3 location, int2 offset);`); >+ print(`native ${type}${length} SampleBias(Texture2DArray<${type}${length}>, sampler, float3 location, float Bias);`); >+ print(`native ${type}${length} SampleBias(Texture2DArray<${type}${length}>, sampler, float3 location, float Bias, int2 offset);`); >+ print(`native ${type}${length} SampleGrad(Texture2DArray<${type}${length}>, sampler, float3 location, float2 DDX, float2 DDY);`); >+ print(`native ${type}${length} SampleGrad(Texture2DArray<${type}${length}>, sampler, float3 location, float2 DDX, float2 DDY, int2 offset);`); >+ print(`native ${type}${length} SampleLevel(Texture2DArray<${type}${length}>, sampler, float3 location, float LOD);`); >+ print(`native ${type}${length} SampleLevel(Texture2DArray<${type}${length}>, sampler, float3 location, float LOD, int2 offset);`); >+ print(`native ${type}4 Gather(Texture2DArray<${type}${length}>, sampler, float3 location);`); >+ print(`native ${type}4 Gather(Texture2DArray<${type}${length}>, sampler, float3 location, int2 offset);`); >+ print(`native ${type}4 GatherRed(Texture2DArray<${type}${length}>, sampler, float3 location);`); >+ print(`native ${type}4 GatherRed(Texture2DArray<${type}${length}>, sampler, float3 location, int2 offset);`); >+ print(`native ${type}4 GatherGreen(Texture2DArray<${type}${length}>, sampler, float3 location);`); >+ print(`native ${type}4 GatherGreen(Texture2DArray<${type}${length}>, sampler, float3 location, int2 offset);`); >+ print(`native ${type}4 GatherBlue(Texture2DArray<${type}${length}>, sampler, float3 location);`); >+ print(`native ${type}4 GatherBlue(Texture2DArray<${type}${length}>, sampler, float3 location, int2 offset);`); >+ print(`native ${type}4 GatherAlpha(Texture2DArray<${type}${length}>, sampler, float3 location);`); >+ print(`native ${type}4 GatherAlpha(Texture2DArray<${type}${length}>, sampler, float3 location, int2 offset);`); >+ print(`native ${type}${length} Load(Texture2DArray<${type}${length}>, int4 location);`); >+ print(`native ${type}${length} Load(Texture2DArray<${type}${length}>, int4 location, int2 offset);`); >+ print(`native void GetDimensions(Texture2DArray<${type}${length}>, uint MipLevel, thread uint* Width, thread uint* Height, thread uint* Elements, thread uint* NumberOfLevels);`); >+ print(); >+ print(`native ${type}${length} Sample(Texture3D<${type}${length}>, sampler, float3 location);`); >+ print(`native ${type}${length} Sample(Texture3D<${type}${length}>, sampler, float3 location, int3 offset);`); >+ print(`native ${type}4 Gather(Texture3D<${type}${length}>, sampler, float3 location);`); >+ print(`native ${type}4 Gather(Texture3D<${type}${length}>, sampler, float3 location, int3 offset);`); >+ print(`native ${type}4 GatherRed(Texture3D<${type}${length}>, sampler, float3 location);`); >+ print(`native ${type}4 GatherRed(Texture3D<${type}${length}>, sampler, float3 location, int3 offset);`); >+ print(`native ${type}4 GatherGreen(Texture3D<${type}${length}>, sampler, float3 location);`); >+ print(`native ${type}4 GatherGreen(Texture3D<${type}${length}>, sampler, float3 location, int3 offset);`); >+ print(`native ${type}4 GatherBlue(Texture3D<${type}${length}>, sampler, float3 location);`); >+ print(`native ${type}4 GatherBlue(Texture3D<${type}${length}>, sampler, float3 location, int3 offset);`); >+ print(`native ${type}4 GatherAlpha(Texture3D<${type}${length}>, sampler, float3 location);`); >+ print(`native ${type}4 GatherAlpha(Texture3D<${type}${length}>, sampler, float3 location, int3 offset);`); >+ print(`native ${type}${length} Load(Texture3D<${type}${length}>, int4 location);`); >+ print(`native ${type}${length} Load(Texture3D<${type}${length}>, int4 location, int3 offset);`); >+ print(`native void GetDimensions(Texture3D<${type}${length}>, uint MipLevel, thread uint* Width, thread uint* Height, thread uint* Depth, thread uint* NumberOfLevels);`); >+ print(); >+ print(`native ${type}${length} Sample(TextureCube<${type}${length}>, sampler, float3 location);`); >+ print(`native ${type}${length} SampleBias(TextureCube<${type}${length}>, sampler, float3 location, float Bias);`); >+ print(`native ${type}${length} SampleGrad(TextureCube<${type}${length}>, sampler, float3 location, float3 DDX, float3 DDY);`); >+ print(`native ${type}${length} SampleLevel(TextureCube<${type}${length}>, sampler, float3 location, float LOD);`); >+ print(`native ${type}4 Gather(TextureCube<${type}${length}>, sampler, float3 location);`); >+ print(`native ${type}4 GatherRed(TextureCube<${type}${length}>, sampler, float3 location);`); >+ print(`native ${type}4 GatherGreen(TextureCube<${type}${length}>, sampler, float3 location);`); >+ print(`native ${type}4 GatherBlue(TextureCube<${type}${length}>, sampler, float3 location);`); >+ print(`native ${type}4 GatherAlpha(TextureCube<${type}${length}>, sampler, float3 location);`); >+ print(`native void GetDimensions(TextureCube<${type}${length}>, uint MipLevel, thread uint* Width, thread uint* Height, thread uint* NumberOfLevels);`); >+ print(); >+ print(`native void GetDimensions(RWTexture1D<${type}${length}>, thread uint* Width);`); >+ print(`native void GetDimensions(RWTexture1D<${type}${length}>, thread float* Width);`); >+ print(`native ${type}${length} Load(RWTexture1D<${type}${length}>, int location);`); >+ print(`native void Store(RWTexture1D<${type}${length}>, ${type}${length}, uint location);`); >+ print(); >+ print(`native void GetDimensions(RWTexture1DArray<${type}${length}>, thread uint* Width, thread uint* Elements);`); >+ print(`native void GetDimensions(RWTexture1DArray<${type}${length}>, thread float* Width, thread uint* Elements);`); >+ print(`native ${type}${length} Load(RWTexture1DArray<${type}${length}>, int2 location);`); >+ print(`native void Store(RWTexture1DArray<${type}${length}>, ${type}${length}, uint2 location);`); >+ print(); >+ print(`native void GetDimensions(RWTexture2D<${type}${length}>, thread uint* Width, thread uint* Height);`); >+ print(`native void GetDimensions(RWTexture2D<${type}${length}>, thread float* Width, thread float* Height);`); >+ print(`native ${type}${length} Load(RWTexture2D<${type}${length}>, int2 location);`); >+ print(`native void Store(RWTexture2D<${type}${length}>, ${type}${length}, uint2 location);`); >+ print(); >+ print(`native void GetDimensions(RWTexture2DArray<${type}${length}>, thread uint* Width, thread uint* Height, thread uint* Elements);`); >+ print(`native void GetDimensions(RWTexture2DArray<${type}${length}>, thread float* Width, thread float* Height, thread float* Elements);`); >+ print(`native ${type}${length} Load(RWTexture2DArray<${type}${length}>, int3 location);`); >+ print(`native void Store(RWTexture2DArray<${type}${length}>, ${type}${length}, uint3 location);`); >+ print(); >+ print(`native void GetDimensions(RWTexture3D<${type}${length}>, thread uint* Width, thread uint* Height, thread uint* Depth);`); >+ print(`native void GetDimensions(RWTexture3D<${type}${length}>, thread float* Width, thread float* Height, thread float* Depth);`); >+ print(`native ${type}${length} Load(RWTexture3D<${type}${length}>, int3 location);`); >+ print(`native void Store(RWTexture3D<${type}${length}>, ${type}${length}, uint3 location);`); >+ print(); >+ } >+ } >+ >+ for (var type of [`half`, `float`]) { >+ print(`native ${type} Sample(TextureDepth2D<${type}>, sampler, float2 location);`); >+ print(`native ${type} Sample(TextureDepth2D<${type}>, sampler, float2 location, int2 offset);`); >+ print(`native ${type} SampleCmp(TextureDepth2D<${type}>, SamplerComparisonState, float2 location, float CompareValue);`); >+ print(`native ${type} SampleCmp(TextureDepth2D<${type}>, SamplerComparisonState, float2 location, float CompareValue, int2 offset);`); >+ print(`native ${type} SampleCmpLevelZero(TextureDepth2D<${type}>, SamplerComparisonState, float2 location, float CompareValue);`); >+ print(`native ${type} SampleCmpLevelZero(TextureDepth2D<${type}>, SamplerComparisonState, float2 location, float CompareValue, int2 offset);`); >+ print(`native ${type} SampleBias(TextureDepth2D<${type}>, sampler, float2 location, float Bias);`); >+ print(`native ${type} SampleBias(TextureDepth2D<${type}>, sampler, float2 location, float Bias, int2 offset);`); >+ print(`native ${type} SampleGrad(TextureDepth2D<${type}>, sampler, float2 location, float2 DDX, float2 DDY);`); >+ print(`native ${type} SampleGrad(TextureDepth2D<${type}>, sampler, float2 location, float2 DDX, float2 DDY, int2 offset);`); >+ print(`native ${type} SampleLevel(TextureDepth2D<${type}>, sampler, float2 location, float LOD);`); >+ print(`native ${type} SampleLevel(TextureDepth2D<${type}>, sampler, float2 location, float LOD, int2 offset);`); >+ print(`native ${type} Gather(TextureDepth2D<${type}>, sampler, float2 location);`); >+ print(`native ${type} Gather(TextureDepth2D<${type}>, sampler, float2 location, int2 offset);`); >+ print(`native ${type} GatherRed(TextureDepth2D<${type}>, sampler, float2 location);`); >+ print(`native ${type} GatherRed(TextureDepth2D<${type}>, sampler, float2 location, int2 offset);`); >+ print(`native ${type} GatherGreen(TextureDepth2D<${type}>, sampler, float2 location);`); >+ print(`native ${type} GatherGreen(TextureDepth2D<${type}>, sampler, float2 location, int2 offset);`); >+ print(`native ${type} GatherBlue(TextureDepth2D<${type}>, sampler, float2 location);`); >+ print(`native ${type} GatherBlue(TextureDepth2D<${type}>, sampler, float2 location, int2 offset);`); >+ print(`native ${type} GatherAlpha(TextureDepth2D<${type}>, sampler, float2 location);`); >+ print(`native ${type} GatherAlpha(TextureDepth2D<${type}>, sampler, float2 location, int2 offset);`); >+ print(`native ${type} GatherCmp(TextureDepth2D<${type}>, SamplerComparisonState, float2 location, float compare_value);`); >+ print(`native ${type} GatherCmp(TextureDepth2D<${type}>, SamplerComparisonState, float2 location, float compare_value, int2 offset);`); >+ print(`native ${type} GatherCmpRed(TextureDepth2D<${type}>, SamplerComparisonState, float2 location, float compare_value);`); >+ print(`native ${type} GatherCmpRed(TextureDepth2D<${type}>, SamplerComparisonState, float2 location, float compare_value, int2 offset);`); >+ print(`native ${type} GatherCmpGreen(TextureDepth2D<${type}>, SamplerComparisonState, float2 location, float compare_value);`); >+ print(`native ${type} GatherCmpGreen(TextureDepth2D<${type}>, SamplerComparisonState, float2 location, float compare_value, int2 offset);`); >+ print(`native ${type} GatherCmpBlue(TextureDepth2D<${type}>, SamplerComparisonState, float2 location, float compare_value);`); >+ print(`native ${type} GatherCmpBlue(TextureDepth2D<${type}>, SamplerComparisonState, float2 location, float compare_value, int2 offset);`); >+ print(`native ${type} GatherCmpAlpha(TextureDepth2D<${type}>, SamplerComparisonState, float2 location, float compare_value);`); >+ print(`native ${type} GatherCmpAlpha(TextureDepth2D<${type}>, SamplerComparisonState, float2 location, float compare_value, int2 offset);`); >+ print(`native ${type} Load(TextureDepth2D<${type}>, int3 location);`); >+ print(`native ${type} Load(TextureDepth2D<${type}>, int3 location, int2 offset);`); >+ print(`native void GetDimensions(TextureDepth2D<${type}>, uint MipLevel, thread uint* Width, thread uint* Height, thread uint* NumberOfLevels);`); >+ print(); >+ print(`native ${type} Sample(TextureDepth2DArray<${type}>, sampler, float3 location);`); >+ print(`native ${type} Sample(TextureDepth2DArray<${type}>, sampler, float3 location, int2 offset);`); >+ print(`native ${type} SampleCmp(TextureDepth2DArray<${type}>, SamplerComparisonState, float3 location, float CompareValue);`); >+ print(`native ${type} SampleCmp(TextureDepth2DArray<${type}>, SamplerComparisonState, float3 location, float CompareValue, int2 offset);`); >+ print(`native ${type} SampleCmpLevelZero(TextureDepth2DArray<${type}>, SamplerComparisonState, float3 location, float CompareValue);`); >+ print(`native ${type} SampleCmpLevelZero(TextureDepth2DArray<${type}>, SamplerComparisonState, float3 location, float CompareValue, int2 offset);`); >+ print(`native ${type} SampleBias(TextureDepth2DArray<${type}>, sampler, float3 location, float Bias);`); >+ print(`native ${type} SampleBias(TextureDepth2DArray<${type}>, sampler, float3 location, float Bias, int2 offset);`); >+ print(`native ${type} SampleGrad(TextureDepth2DArray<${type}>, sampler, float3 location, float2 DDX, float2 DDY);`); >+ print(`native ${type} SampleGrad(TextureDepth2DArray<${type}>, sampler, float3 location, float2 DDX, float2 DDY, int2 offset);`); >+ print(`native ${type} SampleLevel(TextureDepth2DArray<${type}>, sampler, float3 location, float LOD);`); >+ print(`native ${type} SampleLevel(TextureDepth2DArray<${type}>, sampler, float3 location, float LOD, int2 offset);`); >+ print(`native ${type} Gather(TextureDepth2DArray<${type}>, sampler, float3 location);`); >+ print(`native ${type} Gather(TextureDepth2DArray<${type}>, sampler, float3 location, int2 offset);`); >+ print(`native ${type} GatherRed(TextureDepth2DArray<${type}>, sampler, float3 location);`); >+ print(`native ${type} GatherRed(TextureDepth2DArray<${type}>, sampler, float3 location, int2 offset);`); >+ print(`native ${type} GatherGreen(TextureDepth2DArray<${type}>, sampler, float3 location);`); >+ print(`native ${type} GatherGreen(TextureDepth2DArray<${type}>, sampler, float3 location, int2 offset);`); >+ print(`native ${type} GatherBlue(TextureDepth2DArray<${type}>, sampler, float3 location);`); >+ print(`native ${type} GatherBlue(TextureDepth2DArray<${type}>, sampler, float3 location, int2 offset);`); >+ print(`native ${type} GatherAlpha(TextureDepth2DArray<${type}>, sampler, float3 location);`); >+ print(`native ${type} GatherAlpha(TextureDepth2DArray<${type}>, sampler, float3 location, int2 offset);`); >+ print(`native ${type} GatherCmp(TextureDepth2DArray<${type}>, SamplerComparisonState, float3 location, float compare_value);`); >+ print(`native ${type} GatherCmp(TextureDepth2DArray<${type}>, SamplerComparisonState, float3 location, float compare_value, int2 offset);`); >+ print(`native ${type} GatherCmpRed(TextureDepth2DArray<${type}>, SamplerComparisonState, float3 location, float compare_value);`); >+ print(`native ${type} GatherCmpRed(TextureDepth2DArray<${type}>, SamplerComparisonState, float3 location, float compare_value, int2 offset);`); >+ print(`native ${type} GatherCmpGreen(TextureDepth2DArray<${type}>, SamplerComparisonState, float3 location, float compare_value);`); >+ print(`native ${type} GatherCmpGreen(TextureDepth2DArray<${type}>, SamplerComparisonState, float3 location, float compare_value, int2 offset);`); >+ print(`native ${type} GatherCmpBlue(TextureDepth2DArray<${type}>, SamplerComparisonState, float3 location, float compare_value);`); >+ print(`native ${type} GatherCmpBlue(TextureDepth2DArray<${type}>, SamplerComparisonState, float3 location, float compare_value, int2 offset);`); >+ print(`native ${type} GatherCmpAlpha(TextureDepth2DArray<${type}>, SamplerComparisonState, float3 location, float compare_value);`); >+ print(`native ${type} GatherCmpAlpha(TextureDepth2DArray<${type}>, SamplerComparisonState, float3 location, float compare_value, int2 offset);`); >+ print(`native ${type} Load(TextureDepth2DArray<${type}>, int4 location);`); >+ print(`native ${type} Load(TextureDepth2DArray<${type}>, int4 location, int2 offset);`); >+ print(`native void GetDimensions(TextureDepth2DArray<${type}>, uint MipLevel, thread uint* Width, thread uint* Height, thread uint* Elements, thread uint* NumberOfLevels);`); >+ print(); >+ print(`native ${type} Sample(TextureDepthCube<${type}>, sampler, float3 location);`); >+ print(`native ${type} SampleCmp(TextureDepthCube<${type}>, SamplerComparisonState, float3 location, float CompareValue);`); >+ print(`native ${type} SampleCmpLevelZero(TextureDepthCube<${type}>, SamplerComparisonState, float3 location, float CompareValue);`); >+ print(`native ${type} SampleBias(TextureDepthCube<${type}>, sampler, float3 location, float Bias);`); >+ print(`native ${type} SampleGrad(TextureDepthCube<${type}>, sampler, float3 location, float2 DDX, float2 DDY);`); >+ print(`native ${type} SampleLevel(TextureDepthCube<${type}>, sampler, float3 location, float LOD);`); >+ print(`native ${type} Gather(TextureDepthCube<${type}>, sampler, float3 location);`); >+ print(`native ${type} GatherRed(TextureDepthCube<${type}>, sampler, float3 location);`); >+ print(`native ${type} GatherGreen(TextureDepthCube<${type}>, sampler, float3 location);`); >+ print(`native ${type} GatherBlue(TextureDepthCube<${type}>, sampler, float3 location);`); >+ print(`native ${type} GatherAlpha(TextureDepthCube<${type}>, sampler, float3 location);`); >+ print(`native ${type} GatherCmp(TextureDepthCube<${type}>, SamplerComparisonState, float3 location, float compare_value);`); >+ print(`native ${type} GatherCmpRed(TextureDepthCube<${type}>, SamplerComparisonState, float3 location, float compare_value);`); >+ print(`native ${type} GatherCmpGreen(TextureDepthCube<${type}>, SamplerComparisonState, float3 location, float compare_value);`); >+ print(`native ${type} GatherCmpBlue(TextureDepthCube<${type}>, SamplerComparisonState, float3 location, float compare_value);`); >+ print(`native ${type} GatherCmpAlpha(TextureDepthCube<${type}>, SamplerComparisonState, float3 location, float compare_value);`); >+ print(`native ${type} Load(TextureDepthCube<${type}>, int4 location);`); >+ print(`native void GetDimensions(TextureDepthCube<${type}>, uint MipLevel, thread uint* Width, thread uint* Height, thread uint* NumberOfLevels);`); >+ print(); >+ print(`native void GetDimensions(RWTextureDepth2D<${type}>, thread uint* Width, thread uint* Height);`); >+ print(`native void GetDimensions(RWTextureDepth2D<${type}>, thread float* Width, thread float* Height);`); >+ print(`native ${type} Load(RWTextureDepth2D<${type}>, int2 location);`); >+ print(`native void Store(RWTextureDepth2D<${type}>, ${type}, uint2 location);`); >+ print(); >+ print(`native void GetDimensions(RWTextureDepth2DArray<${type}>, thread uint* Width, thread uint* Height, thread uint* Elements);`); >+ print(`native void GetDimensions(RWTextureDepth2DArray<${type}>, thread float* Width, thread float* Height, thread float* Elements);`); >+ print(`native ${type} Load(RWTextureDepth2DArray<${type}>, int3 location);`); >+ print(`native void Store(RWTextureDepth2DArray<${type}>, ${type}, uint3 location);`); >+ print(); >+ } >+ */ >+ })(); >+ return result; >+})(); > > // FIXME: Once the standard library has been replaced with a new version, this comments should be removed. > // This list is used to restrict the availability of vector types available in the langauge. >@@ -217,22 +2134,3 @@ function allVectorTypeNames() > } > return names; > } >- >-// Provides operator&[] >-standardLibrary += OperatorAnderIndexer.functions().join(";\n") + ";\n"; >- >-// Native vector types are like structs in the langauge, but they do not have the ander field access. >-// It is not possible to take the address of a vector field. >-standardLibrary += BuiltinVectorGetter.functions().join(";\n") + ";\n"; >-standardLibrary += BuiltinVectorSetter.functions().join(";\n") + ";\n"; >-standardLibrary += BuiltinVectorIndexGetter.functions().join(";\n") + ";\n"; >-standardLibrary += BuiltinVectorIndexSetter.functions().join(";\n") + ";\n"; >- >-// FIXME: For native types these could be included as source in the standard library. >-// https://bugs.webkit.org/show_bug.cgi?id=188685 >-standardLibrary += OperatorBool.functions().join(";\n") + ";\n"; >-standardLibrary += BuiltinVectorEqualityOperator.functions().join(";\n") + ";\n"; >- >-// FIXME: These need to be included as source in the standard library. >-standardLibrary += SwizzleOp.functions().join(";\n") + ";\n"; >-standardLibrary += BuiltinVectorConstructors.functions().join(";\n") + ";\n"; >diff --git a/Tools/WebGPUShadingLanguageRI/SwizzleOp.js b/Tools/WebGPUShadingLanguageRI/SwizzleOp.js >deleted file mode 100644 >index 25998ef79d98a5288209875d346cf5509e9ba726..0000000000000000000000000000000000000000 >--- a/Tools/WebGPUShadingLanguageRI/SwizzleOp.js >+++ /dev/null >@@ -1,107 +0,0 @@ >-/* >- * 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"; >- >-class SwizzleOp { >- constructor(baseTypeName, outSize, components, inSize) >- { >- this._baseTypeName = baseTypeName; >- this._outSize = outSize; >- this._components = components.slice(); // Shallow clone >- this._inSize = inSize; >- } >- >- get baseTypeName() { return this._baseTypeName; } >- get outSize() { return this._outSize; } >- get components() { return this._components; } >- get inSize() { return this._inSize; } >- >- toString() >- { >- return `native ${this.baseTypeName}${this.outSize} operator.${this.components.join("")}(${this.baseTypeName}${this.inSize} v)`; >- } >- >- static intToString(x) >- { >- switch (x) { >- case 0: >- return "x"; >- case 1: >- return "y"; >- case 2: >- return "z"; >- case 3: >- return "w"; >- default: >- throw new Error("Could not generate standard library."); >- } >- } >- >- static functions() >- { >- if (!this._functions) { >- // We can't directly use this._functions in _generateSwizzles. >- const functions = []; >- >- function _generateSwizzle(baseTypeName, maxDepth, maxItems, array) { >- if (!array) >- array = []; >- if (array.length == maxDepth) { >- functions.push(new SwizzleOp(baseTypeName, array.length, array, maxItems)); >- return; >- } >- for (let i = 0; i < maxItems; ++i) { >- array.push(SwizzleOp.intToString(i)); >- _generateSwizzle(baseTypeName, maxDepth, maxItems, array); >- array.pop(); >- } >- }; >- >- for (let typeName of VectorElementTypes) { >- for (let maxDepth of VectorElementSizes) { >- for (let maxItems = 2; maxItems <= 4; maxItems++) >- _generateSwizzle(typeName, maxDepth, maxItems); >- } >- } >- >- this._functions = functions; >- } >- return this._functions; >- } >- >- instantiateImplementation(func) >- { >- func.implementation = ([vec], node) => { >- const outputBuffer = new EBuffer(this.outSize); >- const readIndices = { 'x': 0, 'y': 1, 'z': 2, 'w': 3 }; >- for (let i = 0; i < this.outSize; i++) >- outputBuffer.set(i, vec.get(readIndices[this.components[i]])); >- >- >- return new EPtr(outputBuffer, 0); >- }; >- func.implementationData = this; >- } >-} >\ No newline at end of file >diff --git a/Tools/WebGPUShadingLanguageRI/SynthesizeDefaultConstructorOperator.js b/Tools/WebGPUShadingLanguageRI/SynthesizeDefaultConstructorOperator.js >index 3a3f7673867b9aab013221803568738c163a567e..dc506538d1c6c7109b1ad1ecba3cec278d0f7b5c 100644 >--- a/Tools/WebGPUShadingLanguageRI/SynthesizeDefaultConstructorOperator.js >+++ b/Tools/WebGPUShadingLanguageRI/SynthesizeDefaultConstructorOperator.js >@@ -51,6 +51,12 @@ function synthesizeDefaultConstructorOperator(program) > types.add(node); > super.visitVectorType(node); > } >+ >+ visitMatrixType(node) >+ { >+ types.add(node); >+ super.visitMatrixType(node); >+ } > } > > program.visit(new FindAllTypes()); >diff --git a/Tools/WebGPUShadingLanguageRI/SynthesizeOperatorBool.js b/Tools/WebGPUShadingLanguageRI/SynthesizeOperatorBool.js >deleted file mode 100644 >index 695fe13753d0a2643b095b534b119217f62538b3..0000000000000000000000000000000000000000 >--- a/Tools/WebGPUShadingLanguageRI/SynthesizeOperatorBool.js >+++ /dev/null >@@ -1,37 +0,0 @@ >-/* >- * 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 synthesizeOperatorBool(program) >-{ >- for (let type of program.types.values()) { >- if (!(type instanceof StructType) && !(type instanceof EnumType)) >- continue; >- const func = new NativeFunc(type.origin, "operator cast", TypeRef.wrap(program.types.get("bool")), [ new FuncParameter(type.origin, null, TypeRef.wrap(type)) ], true, null); >- const operatorBool = new OperatorBool(type.name); >- operatorBool.instantiateImplementation(func); >- program.add(func); >- } >-} >diff --git a/Tools/WebGPUShadingLanguageRI/Test.html b/Tools/WebGPUShadingLanguageRI/Test.html >index 7d26d2607a95f9bf64df1bca91658f2e748c043d..607a6953253da727b1de37678ec388b4fa240405 100644 >--- a/Tools/WebGPUShadingLanguageRI/Test.html >+++ b/Tools/WebGPUShadingLanguageRI/Test.html >@@ -11,7 +11,6 @@ > <script src="CreateLiteral.js"></script> > <script src="CreateLiteralType.js"></script> > <script src="PropertyAccessExpression.js"></script> >-<script src="SwizzleOp.js"></script> > <script src="NativeType.js"></script> > > <script src="AddressSpace.js"></script> >@@ -23,12 +22,10 @@ > <script src="Block.js"></script> > <script src="BoolLiteral.js"></script> > <script src="Break.js"></script> >-<script src="BuiltinVectorConstructors.js"></script> >+<script src="BuiltinMatrixGetter.js"></script> >+<script src="BuiltinMatrixSetter.js"></script> > <script src="BuiltinVectorGetter.js"></script> > <script src="BuiltinVectorSetter.js"></script> >-<script src="BuiltinVectorIndexGetter.js"></script> >-<script src="BuiltinVectorIndexSetter.js"></script> >-<script src="BuiltinVectorEqualityOperator.js"></script> > <script src="CallExpression.js"></script> > <script src="CallFunction.js"></script> > <script src="Check.js"></script> >@@ -90,6 +87,7 @@ > <script src="LoopChecker.js"></script> > <script src="MakeArrayRefExpression.js"></script> > <script src="MakePtrExpression.js"></script> >+<script src="MatrixType.js"></script> > <script src="NameContext.js"></script> > <script src="NameFinder.js"></script> > <script src="NameResolver.js"></script> >@@ -97,9 +95,8 @@ > <script src="NormalUsePropertyResolver.js"></script> > <script src="NullLiteral.js"></script> > <script src="NullType.js"></script> >-<script src="OperatorAnderIndex.js"></script> >+<script src="OperatorAnderIndexer.js"></script> > <script src="OperatorArrayRefLength.js"></script> >-<script src="OperatorBool.js"></script> > <script src="OriginKind.js"></script> > <script src="OverloadResolutionFailure.js"></script> > <script src="Parse.js"></script> >@@ -127,7 +124,6 @@ > <script src="SynthesizeArrayOperatorLength.js"></script> > <script src="SynthesizeEnumFunctions.js"></script> > <script src="SynthesizeStructAccessors.js"></script> >-<script src="SynthesizeOperatorBool.js"></script> > <script src="SynthesizeCopyConstructorOperator.js"></script> > <script src="SynthesizeDefaultConstructorOperator.js"></script> > <script src="TernaryExpression.js"></script> >diff --git a/Tools/WebGPUShadingLanguageRI/Test.js b/Tools/WebGPUShadingLanguageRI/Test.js >index 4f395a94cc7283dd62a004fa1d4c3b9faad30a61..ccbdd2786d4522f47c8f0d170b193b66912553eb 100644 >--- a/Tools/WebGPUShadingLanguageRI/Test.js >+++ b/Tools/WebGPUShadingLanguageRI/Test.js >@@ -78,6 +78,11 @@ function makeFloat(program, value) > return TypedValue.box(program.intrinsics.float, value); > } > >+function makeHalf(program, value) >+{ >+ return TypedValue.box(program.intrinsics.half, value); >+} >+ > function makeEnum(program, enumName, value) > { > let enumType = program.types.get(enumName); >@@ -144,6 +149,14 @@ function checkFloat(program, result, expected) > throw new Error("Wrong result: " + result.value + " (expected " + expected + ")"); > } > >+function checkHalf(program, result, expected) >+{ >+ if (!result.type.equals(program.intrinsics.half)) >+ throw new Error("Wrong result type: " + result.type); >+ if (result.value != expected) >+ throw new Error("Wrong result: " + result.value + " (expected " + expected + ")"); >+} >+ > function checkLexerToken(result, expectedIndex, expectedKind, expectedText) > { > if (result._index != expectedIndex) >@@ -2215,41 +2228,6 @@ tests.operatorBool = function() > > bool boolFromFloatFalse() { return bool(float(0)); } > bool boolFromFloatTrue() { return bool(float(1)); } >- >- bool boolFromInt2False() { return bool(int2(0, 0)); } >- bool boolFromInt2True1() { return bool(int2(1, 0)); } >- bool boolFromInt2True2() { return bool(int2(0, 1)); } >- >- bool boolFromFloat3False() { return bool(float3(0, 0, 0)); } >- bool boolFromFloat3True1() { return bool(float3(1, 0, 0)); } >- bool boolFromFloat3True2() { return bool(float3(0, 1, 0)); } >- bool boolFromFloat3True3() { return bool(float3(0, 0, 1)); } >- >- bool boolFromUint4False() { return bool(uint4(0, 0, 0, 0)); } >- bool boolFromUint4True1() { return bool(uint4(1, 0, 0, 0)); } >- bool boolFromUint4True2() { return bool(uint4(0, 1, 0, 0)); } >- bool boolFromUint4True3() { return bool(uint4(0, 0, 1, 0)); } >- bool boolFromUint4True4() { return bool(uint4(0, 0, 0, 1)); } >- >- struct X { int x; } >- >- bool boolFromStructFalse() >- { >- X x; >- return bool(x); >- } >- >- bool boolFromStructTrue() >- { >- X x; >- x.x = 1; >- return bool(x); >- } >- >- enum Y { A, B } >- >- bool boolFromEnumFalse() { return bool(Y.A); } >- bool boolFromEnumTrue() { return bool(Y.B); } > `); > > checkBool(program, callFunction(program, "boolFromUcharFalse", []), false); >@@ -2264,26 +2242,25 @@ tests.operatorBool = function() > checkBool(program, callFunction(program, "boolFromFloatFalse", []), false); > checkBool(program, callFunction(program, "boolFromFloatTrue", []), true); > >- checkBool(program, callFunction(program, "boolFromInt2False", []), false); >- checkBool(program, callFunction(program, "boolFromInt2True1", []), true); >- checkBool(program, callFunction(program, "boolFromInt2True2", []), true); >- >- checkBool(program, callFunction(program, "boolFromFloat3False", []), false); >- checkBool(program, callFunction(program, "boolFromFloat3True1", []), true); >- checkBool(program, callFunction(program, "boolFromFloat3True2", []), true); >- checkBool(program, callFunction(program, "boolFromFloat3True3", []), true); >- >- checkBool(program, callFunction(program, "boolFromUint4False", []), false); >- checkBool(program, callFunction(program, "boolFromUint4True1", []), true); >- checkBool(program, callFunction(program, "boolFromUint4True2", []), true); >- checkBool(program, callFunction(program, "boolFromUint4True3", []), true); >- checkBool(program, callFunction(program, "boolFromUint4True4", []), true); >- >- checkBool(program, callFunction(program, "boolFromStructFalse", []), false); >- checkBool(program, callFunction(program, "boolFromStructTrue", []), true); >+ checkFail( >+ () => doPrep(` >+ void foo() >+ { >+ float3 x; >+ bool r = bool(x); >+ } >+ `), >+ e => e instanceof WTypeError); > >- checkBool(program, callFunction(program, "boolFromEnumFalse", []), false); >- checkBool(program, callFunction(program, "boolFromEnumTrue", []), true); >+ checkFail( >+ () => doPrep(` >+ void foo() >+ { >+ float3x3 x; >+ bool r = bool(x); >+ } >+ `), >+ e => e instanceof WTypeError); > } > > tests.boolBitAnd = function() >@@ -3548,6 +3525,7 @@ tests.trap = function() > e => e instanceof WTrapError); > } > >+/* > tests.swizzle = function() > { > let program = doPrep(` >@@ -3572,6 +3550,7 @@ tests.swizzle = function() > checkFloat(program, callFunction(program, "foo2", []), 6); > checkFloat(program, callFunction(program, "foo3", []), 4); > } >+*/ > > tests.enumWithExplicitIntBase = function() > { >@@ -5322,6 +5301,133 @@ tests.casts = function() > checkInt(program, callFunction(program, "baz", [makeInt(program, 6)]), 14); > } > >+tests.pointerToMember = function() >+{ >+ checkFail( >+ () => doPrep(` >+ void foo() >+ { >+ float3 x; >+ thread float* y = &x[1]; >+ } >+ `), >+ e => e instanceof WTypeError); >+ >+ checkFail( >+ () => doPrep(` >+ void foo() >+ { >+ float3x3 x; >+ thread float3* y = &x[1]; >+ } >+ `), >+ e => e instanceof WTypeError); >+} >+ >+tests.builtinMatrices = function() >+{ >+ let program = doPrep(` >+ float foo() >+ { >+ float2x2 a; >+ a[0][0] = 1; >+ a[0][1] = 2; >+ a[1][0] = 3; >+ a[1][1] = 4; >+ return a[0][0]; >+ } >+ float foo2() >+ { >+ float2x3 a; >+ a[0][0] = 1; >+ a[0][1] = 2; >+ a[0][2] = 3; >+ a[1][0] = 4; >+ a[1][1] = 5; >+ a[1][2] = 6; >+ return a[1][2]; >+ } >+ float foo3() >+ { >+ float2x2 a; >+ return a[0][0]; >+ } >+ bool foo4() >+ { >+ float2x2 a; >+ a[0][0] = 1; >+ a[0][1] = 2; >+ a[1][0] = 3; >+ a[1][1] = 4; >+ float2x2 b; >+ b[0][0] = 5; >+ b[0][1] = 6; >+ b[1][0] = 7; >+ b[1][1] = 8; >+ for (uint i = 0; i < 2; ++i) { >+ for (uint j = 0; j < 2; ++j) { >+ a[i][j] += 4; >+ } >+ } >+ return a == b; >+ } >+ bool foo5() >+ { >+ float2x2 a; >+ a[0] = float2(1, 2); >+ a[1] = float2(3, 4); >+ float2x2 b; >+ b[0][0] = 1; >+ b[0][1] = 2; >+ b[1][0] = 3; >+ b[1][1] = 4; >+ return a == b; >+ } >+ bool foo6() >+ { >+ float2x2 a; >+ a[0][0] = 1; >+ a[0][1] = 2; >+ a[1][0] = 3; >+ a[1][1] = 4; >+ float2x2 b; >+ b[0][0] = 5; >+ b[0][1] = 10; >+ b[1][0] = 18; >+ b[1][1] = 24; >+ a[0] *= 5; >+ a[1] *= 6; >+ return a == b; >+ } >+ float foo7() >+ { >+ float2x3 a = float2x3(float3(3, 4, 5), float3(6, 7, 8)); >+ return a[0][2]; >+ } >+ `); >+ checkFloat(program, callFunction(program, "foo", []), 1); >+ checkFloat(program, callFunction(program, "foo2", []), 6); >+ checkFloat(program, callFunction(program, "foo3", []), 0); >+ checkBool(program, callFunction(program, "foo4", []), true); >+ checkBool(program, callFunction(program, "foo5", []), true); >+ checkBool(program, callFunction(program, "foo6", []), true); >+ checkFloat(program, callFunction(program, "foo7", []), 5); >+} >+ >+tests.halfSimpleMath = function() { >+ let program = doPrep("half foo(half x, half y) { return x + y; }"); >+ checkHalf(program, callFunction(program, "foo", [makeHalf(program, 7), makeHalf(program, 5)]), 12); >+ program = doPrep("half foo(half x, half y) { return x - y; }"); >+ checkHalf(program, callFunction(program, "foo", [makeHalf(program, 7), makeHalf(program, 5)]), 2); >+ checkHalf(program, callFunction(program, "foo", [makeHalf(program, 5), makeHalf(program, 7)]), -2); >+ program = doPrep("half foo(half x, half y) { return x * y; }"); >+ checkHalf(program, callFunction(program, "foo", [makeHalf(program, 7), makeHalf(program, 5)]), 35); >+ checkHalf(program, callFunction(program, "foo", [makeHalf(program, 7), makeHalf(program, -5)]), -35); >+ program = doPrep("half foo(half x, half y) { return x / y; }"); >+ checkHalf(program, callFunction(program, "foo", [makeHalf(program, 7), makeHalf(program, 2)]), 3.5); >+ checkHalf(program, callFunction(program, "foo", [makeHalf(program, 7), makeHalf(program, -2)]), -3.5); >+} >+ > okToTest = true; > > let testFilter = /.*/; // run everything by default >diff --git a/Tools/WebGPUShadingLanguageRI/Visitor.js b/Tools/WebGPUShadingLanguageRI/Visitor.js >index 1f1f54d8cca75c110198e5084588790791de0e58..b9ea7e463c4e08bdf86fe9076ead405876d11592 100644 >--- a/Tools/WebGPUShadingLanguageRI/Visitor.js >+++ b/Tools/WebGPUShadingLanguageRI/Visitor.js >@@ -340,5 +340,12 @@ class Visitor { > node.elementType.visit(this); > node.numElements.visit(this); > } >+ >+ visitMatrixType(node) >+ { >+ node.elementType.visit(this); >+ node.numRows.visit(this); >+ node.numColumns.visit(this); >+ } > } > >diff --git a/Tools/WebGPUShadingLanguageRI/index.html b/Tools/WebGPUShadingLanguageRI/index.html >index 17d0c20c9fd638fb30eed7bb62204aa097c5acbd..65a86411b3e770b557b41acc7e414def42403013 100644 >--- a/Tools/WebGPUShadingLanguageRI/index.html >+++ b/Tools/WebGPUShadingLanguageRI/index.html >@@ -11,7 +11,6 @@ > <script src="CreateLiteral.js"></script> > <script src="CreateLiteralType.js"></script> > <script src="PropertyAccessExpression.js"></script> >-<script src="SwizzleOp.js"></script> > <script src="NativeType.js"></script> > > <script src="AddressSpace.js"></script> >@@ -23,12 +22,10 @@ > <script src="Block.js"></script> > <script src="BoolLiteral.js"></script> > <script src="Break.js"></script> >-<script src="BuiltinVectorConstructors.js"></script> >+<script src="BuiltinMatrixGetter.js"></script> >+<script src="BuiltinMatrixSetter.js"></script> > <script src="BuiltinVectorGetter.js"></script> > <script src="BuiltinVectorSetter.js"></script> >-<script src="BuiltinVectorIndexGetter.js"></script> >-<script src="BuiltinVectorIndexSetter.js"></script> >-<script src="BuiltinVectorEqualityOperator.js"></script> > <script src="CallExpression.js"></script> > <script src="CallFunction.js"></script> > <script src="Check.js"></script> >@@ -90,6 +87,7 @@ > <script src="LoopChecker.js"></script> > <script src="MakeArrayRefExpression.js"></script> > <script src="MakePtrExpression.js"></script> >+<script src="MatrixType.js"></script> > <script src="NameContext.js"></script> > <script src="NameFinder.js"></script> > <script src="NameResolver.js"></script> >@@ -97,9 +95,8 @@ > <script src="NormalUsePropertyResolver.js"></script> > <script src="NullLiteral.js"></script> > <script src="NullType.js"></script> >-<script src="OperatorAnderIndex.js"></script> >+<script src="OperatorAnderIndexer.js"></script> > <script src="OperatorArrayRefLength.js"></script> >-<script src="OperatorBool.js"></script> > <script src="OriginKind.js"></script> > <script src="OverloadResolutionFailure.js"></script> > <script src="Parse.js"></script> >@@ -127,7 +124,6 @@ > <script src="SynthesizeArrayOperatorLength.js"></script> > <script src="SynthesizeEnumFunctions.js"></script> > <script src="SynthesizeStructAccessors.js"></script> >-<script src="SynthesizeOperatorBool.js"></script> > <script src="SynthesizeCopyConstructorOperator.js"></script> > <script src="SynthesizeDefaultConstructorOperator.js"></script> > <script src="TernaryExpression.js"></script>
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 188873
:
347885
|
347895
|
347901
|
347935
|
347936
|
347963
|
347980
|
347993
|
348011
|
348051
|
348053
|
348078
|
348087
|
348088
|
348091
|
348208
|
348224
|
348413
| 348415