Changeset 223246 in webkit


Ignore:
Timestamp:
Oct 12, 2017 11:45:04 AM (7 years ago)
Author:
mmaxfield@apple.com
Message:

Emit SPIR-V from WSL compiler (Part 1)
https://bugs.webkit.org/show_bug.cgi?id=177998

Reviewed by Filip Pizlo.

This patch implements the first half of a SPIR-V codegen phase for WSL.
This includes all the operations which aren't actually emitting the contents
of functions themselves. For example, this includes things like representing
WSL types with SPIR-V types, and declaring shaders' inputs and outputs. A
future patch will actually emit the contents of functions.

There are two helper visitors here: SPIRVTypeAnalyzer which generates SPIR-V
types from WSL types, and SPIRVPrimitiveVariableAnalyzer which identifies
input and output variables from a shader (and assigns location values to
each one).

This patch is currently pursuing the "logical mode" detailed in
https://bugs.webkit.org/show_bug.cgi?id=176967. In this mode, each pointer and
array reference operation can be statically traced to the variable or array it
is operating on.

This has the interesting property where accessing a pointer inside an array is
forbidden, because the array index may be computed at runtime, so the compiler
can't know at compile time which variable the pointer operation will be
accessing. However, this isn't true for structs; the program must statically
state which struct member it is accessing. Therefore, pointers or array
references must not transitively appear within an array, but they may appear
within a struct. The same logic applies to array references; those get lowered
to just two indexes in SPIR-V (a lower bound and an upper bound).

So, outside of an array, SPIR-V types don't need to include any pointers because
any operation with the pointer doesn't need access to the runtime value of the
pointer. Inside of an array, pointers are forbidden. Therefore, SPIR-V types
will never include any pointers.

This means that, for example, WSL can represent a linked list in logical mode.
However, a WSL program cannot iterate across the list, because that would require
assigning to a pointer. So instead, a program using a linked list could only say
something like "list.ptr->ptr->ptr->value".

  • WebGPUShadingLanguageRI/LateChecker.js:

(LateChecker.prototype._checkShaderType):

  • WebGPUShadingLanguageRI/SPIR-V.js:

(SPIRV.OperandChecker.prototype._isStar):
(SPIRV.OperandChecker.prototype.nextComparisonType):
(SPIRV.OperandChecker.prototype.finalize):
(SPIRV.OperandChecker):

  • WebGPUShadingLanguageRI/SPIRV.html:
  • WebGPUShadingLanguageRI/SPIRVCodegen.js: Added.

(findEntryPoints):
(emitTypes.doEmitTypes):
(emitTypes):
(ConstantFinder.prototype.visitGenericLiteralType):
(ConstantFinder):
(generateSPIRV):

  • WebGPUShadingLanguageRI/SPIRVTypeAnalyzer.js: Added.

(SPIRVTypeAnalyzer):
(SPIRVTypeAnalyzer.prototype.get program):
(SPIRVTypeAnalyzer.prototype.get typeMap):
(SPIRVTypeAnalyzer.prototype.get currentId):
(SPIRVTypeAnalyzer.prototype.get stack):
(SPIRVTypeAnalyzer.prototype.visitTypeRef):
(SPIRVTypeAnalyzer.prototype._encounterType):
(SPIRVTypeAnalyzer.prototype.visitNullType):
(SPIRVTypeAnalyzer.prototype.visitGenericLiteralType):
(SPIRVTypeAnalyzer.prototype.visitNativeType):
(SPIRVTypeAnalyzer.prototype.visitEnumType):
(SPIRVTypeAnalyzer.prototype.visitPtrType):
(SPIRVTypeAnalyzer.prototype.visitArrayRefType):
(SPIRVTypeAnalyzer.prototype.visitArrayType):
(SPIRVTypeAnalyzer.prototype.visitStructType):

  • WebGPUShadingLanguageRI/SPIRVVariableAnalyzer.js: Added.

(SPIRVPrimitiveVariableAnalyzer):
(SPIRVPrimitiveVariableAnalyzer.prototype.get program):
(SPIRVPrimitiveVariableAnalyzer.prototype.get typeMap):
(SPIRVPrimitiveVariableAnalyzer.prototype.get currentId):
(SPIRVPrimitiveVariableAnalyzer.prototype.get currentLocation):
(SPIRVPrimitiveVariableAnalyzer.prototype.get nameComponents):
(SPIRVPrimitiveVariableAnalyzer.prototype.get result):
(SPIRVPrimitiveVariableAnalyzer.prototype.visitTypeRef):
(SPIRVPrimitiveVariableAnalyzer.prototype.visitNullType):
(SPIRVPrimitiveVariableAnalyzer.prototype.visitGenericLiteralType):
(SPIRVPrimitiveVariableAnalyzer.prototype.visitNativeType):
(SPIRVPrimitiveVariableAnalyzer.prototype.visitEnumType):
(SPIRVPrimitiveVariableAnalyzer.prototype.visitPtrType):
(SPIRVPrimitiveVariableAnalyzer.prototype.visitArrayRefType):
(SPIRVPrimitiveVariableAnalyzer.prototype.visitArrayType):
(SPIRVPrimitiveVariableAnalyzer.prototype.visitStructType):

  • WebGPUShadingLanguageRI/WSL.md:
  • WebGPUShadingLanguageRI/index.html:
Location:
trunk/Tools
Files:
3 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Tools/ChangeLog

    r223239 r223246  
     12017-10-12  Myles C. Maxfield  <mmaxfield@apple.com>
     2
     3        Emit SPIR-V from WSL compiler (Part 1)
     4        https://bugs.webkit.org/show_bug.cgi?id=177998
     5
     6        Reviewed by Filip Pizlo.
     7
     8        This patch implements the first half of a SPIR-V codegen phase for WSL.
     9        This includes all the operations which aren't actually emitting the contents
     10        of functions themselves. For example, this includes things like representing
     11        WSL types with SPIR-V types, and declaring shaders' inputs and outputs. A
     12        future patch will actually emit the contents of functions.
     13
     14        There are two helper visitors here: SPIRVTypeAnalyzer which generates SPIR-V
     15        types from WSL types, and SPIRVPrimitiveVariableAnalyzer which identifies
     16        input and output variables from a shader (and assigns location values to
     17        each one).
     18
     19        This patch is currently pursuing the "logical mode" detailed in
     20        https://bugs.webkit.org/show_bug.cgi?id=176967. In this mode, each pointer and
     21        array reference operation can be statically traced to the variable or array it
     22        is operating on.
     23
     24        This has the interesting property where accessing a pointer inside an array is
     25        forbidden, because the array index may be computed at runtime, so the compiler
     26        can't know at compile time which variable the pointer operation will be
     27        accessing. However, this isn't true for structs; the program must statically
     28        state which struct member it is accessing. Therefore, pointers or array
     29        references must not transitively appear within an array, but they may appear
     30        within a struct. The same logic applies to array references; those get lowered
     31        to just two indexes in SPIR-V (a lower bound and an upper bound).
     32
     33        So, outside of an array, SPIR-V types don't need to include any pointers because
     34        any operation with the pointer doesn't need access to the runtime value of the
     35        pointer. Inside of an array, pointers are forbidden. Therefore, SPIR-V types
     36        will never include any pointers.
     37
     38        This means that, for example, WSL can represent a linked list in logical mode.
     39        However, a WSL program cannot iterate across the list, because that would require
     40        assigning to a pointer. So instead, a program using a linked list could only say
     41        something like "list.ptr->ptr->ptr->value".
     42
     43        * WebGPUShadingLanguageRI/LateChecker.js:
     44        (LateChecker.prototype._checkShaderType):
     45        * WebGPUShadingLanguageRI/SPIR-V.js:
     46        (SPIRV.OperandChecker.prototype._isStar):
     47        (SPIRV.OperandChecker.prototype.nextComparisonType):
     48        (SPIRV.OperandChecker.prototype.finalize):
     49        (SPIRV.OperandChecker):
     50        * WebGPUShadingLanguageRI/SPIRV.html:
     51        * WebGPUShadingLanguageRI/SPIRVCodegen.js: Added.
     52        (findEntryPoints):
     53        (emitTypes.doEmitTypes):
     54        (emitTypes):
     55        (ConstantFinder.prototype.visitGenericLiteralType):
     56        (ConstantFinder):
     57        (generateSPIRV):
     58        * WebGPUShadingLanguageRI/SPIRVTypeAnalyzer.js: Added.
     59        (SPIRVTypeAnalyzer):
     60        (SPIRVTypeAnalyzer.prototype.get program):
     61        (SPIRVTypeAnalyzer.prototype.get typeMap):
     62        (SPIRVTypeAnalyzer.prototype.get currentId):
     63        (SPIRVTypeAnalyzer.prototype.get stack):
     64        (SPIRVTypeAnalyzer.prototype.visitTypeRef):
     65        (SPIRVTypeAnalyzer.prototype._encounterType):
     66        (SPIRVTypeAnalyzer.prototype.visitNullType):
     67        (SPIRVTypeAnalyzer.prototype.visitGenericLiteralType):
     68        (SPIRVTypeAnalyzer.prototype.visitNativeType):
     69        (SPIRVTypeAnalyzer.prototype.visitEnumType):
     70        (SPIRVTypeAnalyzer.prototype.visitPtrType):
     71        (SPIRVTypeAnalyzer.prototype.visitArrayRefType):
     72        (SPIRVTypeAnalyzer.prototype.visitArrayType):
     73        (SPIRVTypeAnalyzer.prototype.visitStructType):
     74        * WebGPUShadingLanguageRI/SPIRVVariableAnalyzer.js: Added.
     75        (SPIRVPrimitiveVariableAnalyzer):
     76        (SPIRVPrimitiveVariableAnalyzer.prototype.get program):
     77        (SPIRVPrimitiveVariableAnalyzer.prototype.get typeMap):
     78        (SPIRVPrimitiveVariableAnalyzer.prototype.get currentId):
     79        (SPIRVPrimitiveVariableAnalyzer.prototype.get currentLocation):
     80        (SPIRVPrimitiveVariableAnalyzer.prototype.get nameComponents):
     81        (SPIRVPrimitiveVariableAnalyzer.prototype.get result):
     82        (SPIRVPrimitiveVariableAnalyzer.prototype.visitTypeRef):
     83        (SPIRVPrimitiveVariableAnalyzer.prototype.visitNullType):
     84        (SPIRVPrimitiveVariableAnalyzer.prototype.visitGenericLiteralType):
     85        (SPIRVPrimitiveVariableAnalyzer.prototype.visitNativeType):
     86        (SPIRVPrimitiveVariableAnalyzer.prototype.visitEnumType):
     87        (SPIRVPrimitiveVariableAnalyzer.prototype.visitPtrType):
     88        (SPIRVPrimitiveVariableAnalyzer.prototype.visitArrayRefType):
     89        (SPIRVPrimitiveVariableAnalyzer.prototype.visitArrayType):
     90        (SPIRVPrimitiveVariableAnalyzer.prototype.visitStructType):
     91        * WebGPUShadingLanguageRI/WSL.md:
     92        * WebGPUShadingLanguageRI/index.html:
     93
    1942017-09-29  Filip Pizlo  <fpizlo@apple.com>
    295
  • trunk/Tools/WebGPUShadingLanguageRI/LateChecker.js

    r222413 r223246  
    3737    _checkShaderType(node)
    3838    {
     39        // FIXME: Tighten these checks. For now, we should only accept int32, uint32, float32, and float64.
    3940        let assertPrimitive = type => {
    4041            if (!type.isPrimitive)
  • trunk/Tools/WebGPUShadingLanguageRI/SPIR-V.js

    r222825 r223246  
    3939        case "BitEnum":
    4040        case "ValueEnum":
    41             let enumerants = {};
     41            let enumerants = { category: kind.category };
    4242            for (let enumerant of kind.enumerants) {
    4343                enumerants[enumerant.enumerant] = enumerant;
     
    113113        }
    114114
    115         nextComparisonType(operand)
    116         {
    117             if (this._operandInfoIndex >= this._operandInfos.length)
    118                 throw new Error("Specified operand does not correspond to any that the instruction expects.");
    119             let operandInfo = this._operandInfos[this._operandInfoIndex];
    120 
    121             let isStar = operandInfo.quantifier && operandInfo.quantifier == "*";
     115        _isStar(operandInfo)
     116        {
    122117            switch (operandInfo.kind) {
    123118                case "LiteralContextDependentNumber":
    124119                case "LiteralSpecConstantOpInteger":
    125120                    // These types can be any width.
    126                     isStar = true;
    127                     break;
    128             }
     121                    return true;
     122            }
     123            return operandInfo.quantifier && operandInfo.quantifier == "*";
     124        }
     125
     126        nextComparisonType(operand)
     127        {
     128            if (this._operandInfoIndex >= this._operandInfos.length)
     129                throw new Error("Specified operand does not correspond to any that the instruction expects.");
     130            let operandInfo = this._operandInfos[this._operandInfoIndex];
     131
     132            let isStar = this._isStar(operandInfo);
    129133
    130134            if (this._parameters.length != 0) {
     
    177181                throw new Error("Operand not specified for parameter.");
    178182            for (let i = this._operandInfoIndex; i < this._operandInfos.length; ++i) {
    179                 let quantifier = this._operandInfos[i].quantifier;
    180                 if (quantifier != "?" && quantifier != "*")
     183                let operandInfo = this._operandInfos[i];
     184                let quantifier = operandInfo.quantifier;
     185                if (quantifier != "?" && !this._isStar(operandInfo))
    181186                    throw new Error("Did not specify operand " + i + " to instruction.");
    182187            }
     
    191196            constructor(...operands)
    192197            {
    193                 // FIXME: Handle OpConstant, OpSpecConstant, OpSpecConstantOp specially.
    194198                let operandChecker = new OperandChecker(instruction.operands);
    195199                for (let operand of operands)
  • trunk/Tools/WebGPUShadingLanguageRI/SPIRV.html

    r222825 r223246  
    22<html>
    33<head>
    4 <script src="SPIR-V.js"></script>
     4<style>
     5td {
     6    border: solid black 1px;
     7}
     8</style>
     9    <!-- FIXME: Migrate to ES6 modules -->
     10    <script src="Node.js"></script>
     11    <script src="Type.js"></script>
     12    <script src="ReferenceType.js"></script>
     13    <script src="Value.js"></script>
     14    <script src="Expression.js"></script>
     15    <script src="Rewriter.js"></script>
     16    <script src="Visitor.js"></script>
     17    <script src="CreateLiteral.js"></script>
     18    <script src="CreateLiteralType.js"></script>
     19    <script src="PropertyAccessExpression.js"></script>
     20
     21    <script src="AddressSpace.js"></script>
     22    <script src="AnonymousVariable.js"></script>
     23    <script src="ArrayRefType.js"></script>
     24    <script src="ArrayType.js"></script>
     25    <script src="Assignment.js"></script>
     26    <script src="AutoWrapper.js"></script>
     27    <script src="Block.js"></script>
     28    <script src="BoolLiteral.js"></script>
     29    <script src="Break.js"></script>
     30    <script src="CallExpression.js"></script>
     31    <script src="CallFunction.js"></script>
     32    <script src="Check.js"></script>
     33    <script src="CheckLiteralTypes.js"></script>
     34    <script src="CheckLoops.js"></script>
     35    <script src="CheckRecursion.js"></script>
     36    <script src="CheckRecursiveTypes.js"></script>
     37    <script src="CheckReturns.js"></script>
     38    <script src="CheckUnreachableCode.js"></script>
     39    <script src="CheckWrapped.js"></script>
     40    <script src="Checker.js"></script>
     41    <script src="CloneProgram.js"></script>
     42    <script src="CommaExpression.js"></script>
     43    <script src="ConstexprFolder.js"></script>
     44    <script src="ConstexprTypeParameter.js"></script>
     45    <script src="Continue.js"></script>
     46    <script src="ConvertPtrToArrayRefExpression.js"></script>
     47    <script src="DoWhileLoop.js"></script>
     48    <script src="DotExpression.js"></script>
     49    <script src="DoubleLiteral.js"></script>
     50    <script src="DoubleLiteralType.js"></script>
     51    <script src="DereferenceExpression.js"></script>
     52    <script src="EArrayRef.js"></script>
     53    <script src="EBuffer.js"></script>
     54    <script src="EBufferBuilder.js"></script>
     55    <script src="EPtr.js"></script>
     56    <script src="EnumLiteral.js"></script>
     57    <script src="EnumMember.js"></script>
     58    <script src="EnumType.js"></script>
     59    <script src="EvaluationCommon.js"></script>
     60    <script src="Evaluator.js"></script>
     61    <script src="ExpressionFinder.js"></script>
     62    <script src="ExternalOrigin.js"></script>
     63    <script src="Field.js"></script>
     64    <script src="FindHighZombies.js"></script>
     65    <script src="FlattenProtocolExtends.js"></script>
     66    <script src="FlattenedStructOffsetGatherer.js"></script>
     67    <script src="FloatLiteral.js"></script>
     68    <script src="FloatLiteralType.js"></script>
     69    <script src="FoldConstexprs.js"></script>
     70    <script src="ForLoop.js"></script>
     71    <script src="Func.js"></script>
     72    <script src="FuncDef.js"></script>
     73    <script src="FuncInstantiator.js"></script>
     74    <script src="FuncParameter.js"></script>
     75    <script src="FunctionLikeBlock.js"></script>
     76    <script src="HighZombieFinder.js"></script>
     77    <script src="IdentityExpression.js"></script>
     78    <script src="IfStatement.js"></script>
     79    <script src="IndexExpression.js"></script>
     80    <script src="InferTypesForCall.js"></script>
     81    <script src="Inline.js"></script>
     82    <script src="Inliner.js"></script>
     83    <script src="InstantiateImmediates.js"></script>
     84    <script src="IntLiteral.js"></script>
     85    <script src="IntLiteralType.js"></script>
     86    <script src="Intrinsics.js"></script>
     87    <script src="LateChecker.js"></script>
     88    <script src="Lexer.js"></script>
     89    <script src="LexerToken.js"></script>
     90    <script src="LiteralTypeChecker.js"></script>
     91    <script src="LogicalExpression.js"></script>
     92    <script src="LogicalNot.js"></script>
     93    <script src="LoopChecker.js"></script>
     94    <script src="MakeArrayRefExpression.js"></script>
     95    <script src="MakePtrExpression.js"></script>
     96    <script src="NameContext.js"></script>
     97    <script src="NameFinder.js"></script>
     98    <script src="NameResolver.js"></script>
     99    <script src="NativeFunc.js"></script>
     100    <script src="NativeFuncInstance.js"></script>
     101    <script src="NativeType.js"></script>
     102    <script src="NativeTypeInstance.js"></script>
     103    <script src="NormalUsePropertyResolver.js"></script>
     104    <script src="NullLiteral.js"></script>
     105    <script src="NullType.js"></script>
     106    <script src="OriginKind.js"></script>
     107    <script src="OverloadResolutionFailure.js"></script>
     108    <script src="Parse.js"></script>
     109    <script src="Prepare.js"></script>
     110    <script src="PropertyResolver.js"></script>
     111    <script src="Program.js"></script>
     112    <script src="ProgramWithUnnecessaryThingsRemoved.js"></script>
     113    <script src="Protocol.js"></script>
     114    <script src="ProtocolDecl.js"></script>
     115    <script src="ProtocolFuncDecl.js"></script>
     116    <script src="ProtocolRef.js"></script>
     117    <script src="PtrType.js"></script>
     118    <script src="ReadModifyWriteExpression.js"></script>
     119    <script src="RecursionChecker.js"></script>
     120    <script src="RecursiveTypeChecker.js"></script>
     121    <script src="ResolveNames.js"></script>
     122    <script src="ResolveOverloadImpl.js"></script>
     123    <script src="ResolveProperties.js"></script>
     124    <script src="ResolveTypeDefs.js"></script>
     125    <script src="Return.js"></script>
     126    <script src="ReturnChecker.js"></script>
     127    <script src="ReturnException.js"></script>
     128    <script src="SPIR-V.js"></script>
     129    <script src="SPIRVCodegen.js"></script>
     130    <script src="SPIRVTypeAnalyzer.js"></script>
     131    <script src="SPIRVVariableAnalyzer.js"></script>
     132    <script src="StandardLibrary.js"></script>
     133    <script src="StatementCloner.js"></script>
     134    <script src="StructLayoutBuilder.js"></script>
     135    <script src="StructType.js"></script>
     136    <script src="Substitution.js"></script>
     137    <script src="SwitchCase.js"></script>
     138    <script src="SwitchStatement.js"></script>
     139    <script src="SynthesizeEnumFunctions.js"></script>
     140    <script src="SynthesizeStructAccessors.js"></script>
     141    <script src="TrapStatement.js"></script>
     142    <script src="TypeDef.js"></script>
     143    <script src="TypeDefResolver.js"></script>
     144    <script src="TypeOrVariableRef.js"></script>
     145    <script src="TypeParameterRewriter.js"></script>
     146    <script src="TypeRef.js"></script>
     147    <script src="TypeVariable.js"></script>
     148    <script src="TypeVariableTracker.js"></script>
     149    <script src="TypedValue.js"></script>
     150    <script src="UintLiteral.js"></script>
     151    <script src="UintLiteralType.js"></script>
     152    <script src="UnificationContext.js"></script>
     153    <script src="UnreachableCodeChecker.js"></script>
     154    <script src="VariableDecl.js"></script>
     155    <script src="VariableRef.js"></script>
     156    <script src="VisitingSet.js"></script>
     157    <script src="WSyntaxError.js"></script>
     158    <script src="WTrapError.js"></script>
     159    <script src="WTypeError.js"></script>
     160    <script src="WhileLoop.js"></script>
     161    <script src="WrapChecker.js"></script>
    5162<script>
     163    let code = `
     164struct VertexInput {
     165    float2 position;
     166    float3 color;
     167}
     168
     169struct VertexOutput {
     170    float4 wsl_Position;
     171    float4 color;
     172}
     173
     174struct FragmentOutput {
     175    float4 wsl_Color;
     176}
     177
     178vertex VertexOutput vertexShader(VertexInput vertexInput) {
     179    VertexOutput result;
     180    result.wsl_Position = float4(vertexInput.position, 0., 1.);
     181    result.color = float4(vertexInput.color, 1);
     182   
     183    int[10] a;
     184    int[10u] b;
     185    return result;
     186}
     187
     188fragment FragmentOutput fragmentShader(VertexOutput stageIn) {
     189    FragmentOutput result;
     190    result.wsl_Color = stageIn.color;
     191    return result;
     192}`;
    6193
    7194    window.addEventListener("load", function () {
    8195        fetch("spirv.core.grammar.json").then(response => response.json()).then(function (json) {
    9196            let spirv = SPIRV(json);
    10             let assembler = new SPIRVAssembler();
    11             assembler.append(new spirv.ops.Capability(spirv.kinds.Capability.Shader));
    12             assembler.append(new spirv.ops.MemoryModel(spirv.kinds.AddressingModel.Logical, spirv.kinds.MemoryModel.GLSL450));
    13             assembler.append(new spirv.ops.EntryPoint(spirv.kinds.ExecutionModel.Fragment, 5, "main", 10, 17));
    14             assembler.append(new spirv.ops.ExecutionMode(5, spirv.kinds.ExecutionMode.OriginLowerLeft));
    15             assembler.append(new spirv.ops.Decorate(10, spirv.kinds.Decoration.Location, 0));
    16             assembler.append(new spirv.ops.Decorate(14, spirv.kinds.Decoration.DescriptorSet, 0));
    17             assembler.append(new spirv.ops.Decorate(14, spirv.kinds.Decoration.Binding, 1));
    18             assembler.append(new spirv.ops.Decorate(17, spirv.kinds.Decoration.Location, 0));
    19             assembler.append(new spirv.ops.TypeVoid(3));
    20             assembler.append(new spirv.ops.TypeFunction(4, 3));
    21             assembler.append(new spirv.ops.TypeFloat(7, 32));
    22             assembler.append(new spirv.ops.TypeVector(8, 7, 4));
    23             assembler.append(new spirv.ops.TypePointer(9, spirv.kinds.StorageClass.Output, 8));
    24             assembler.append(new spirv.ops.Variable(9, 10, spirv.kinds.StorageClass.Output));
    25             assembler.append(new spirv.ops.TypeImage(11, 7, spirv.kinds.Dim["2D"], 0, 0, 0, 1, spirv.kinds.ImageFormat.Unknown));
    26             assembler.append(new spirv.ops.TypeSampledImage(12, 11));
    27             assembler.append(new spirv.ops.TypePointer(13, spirv.kinds.StorageClass.UniformConstant, 12));
    28             assembler.append(new spirv.ops.Variable(13, 14, spirv.kinds.StorageClass.UniformConstant));
    29             assembler.append(new spirv.ops.TypePointer(16, spirv.kinds.StorageClass.Input, 8));
    30             assembler.append(new spirv.ops.Variable(16, 17, spirv.kinds.StorageClass.Input));
    31             assembler.append(new spirv.ops.TypeVector(18, 7, 2));
    32             assembler.append(new spirv.ops.Function(3, 5, spirv.kinds.FunctionControl.None, 4));
    33             assembler.append(new spirv.ops.Label(6));
    34             assembler.append(new spirv.ops.Load(12, 15, 14));
    35             assembler.append(new spirv.ops.Load(8, 19, 17));
    36             assembler.append(new spirv.ops.VectorShuffle(18, 20, 19, 19, 0, 1));
    37             assembler.append(new spirv.ops.ImageSampleImplicitLod(8, 21, 15, 20));
    38             assembler.append(new spirv.ops.Store(10, 21));
    39             assembler.append(new spirv.ops.Return());
    40             assembler.append(new spirv.ops.FunctionEnd());
    41             let result = assembler.result;
    42            
     197            let program = prepare("/internal/test", 0, code);
     198            let result = generateSPIRV(spirv, program);
     199            return result;
     200        }).then(function(result) {
    43201            let resultElement = document.getElementById("Result");
    44202            while (resultElement.childNodes.length != 0)
    45203                resultElement.removeChild(resultElement.childNodes[0]);
    46204            let anchor = document.createElement("a");
    47             let blob = new Blob([result], { type: "application/octet-binary" });
     205            let blob = new Blob([result.file], { type: "application/octet-binary" });
    48206            anchor.href = URL.createObjectURL(blob);
    49207            anchor.download = "result.spv";
    50208            anchor.textContent = "Download generated SPIR-V";
    51209            resultElement.appendChild(anchor);
     210
     211            let table = document.createElement("table");
     212            let tableHeader = document.createElement("thead");
     213            let headerRow = document.createElement("tr");
     214            let nameHeader = document.createElement("th");
     215            nameHeader.textContent = "Attribute name";
     216            let locationHeader = document.createElement("th");
     217            locationHeader.textContent = "Location";
     218            headerRow.appendChild(nameHeader);
     219            headerRow.appendChild(locationHeader);
     220            tableHeader.appendChild(headerRow);
     221            table.appendChild(tableHeader);
     222            for (let location of result.locations) {
     223                let tableRow = document.createElement("tr");
     224                let nameElement = document.createElement("td");
     225                nameElement.textContent = location.name;
     226                let locationElement = document.createElement("td");
     227                locationElement.textContent = location.location;
     228                tableRow.appendChild(nameElement);
     229                tableRow.appendChild(locationElement);
     230                table.appendChild(tableRow);
     231            }
     232            resultElement.appendChild(table);
    52233        }).then(undefined, function () {
    53234            let resultElement = document.getElementById("Result");
  • trunk/Tools/WebGPUShadingLanguageRI/WSL.md

    r222179 r223246  
    474474
    475475- `device`, `constant`, and `threadgroup` pointers cannot point to data that may have pointers in it. This safety check is not done as part of the normal type system checks. It's performed only after instantiation.
    476 - Pointers and array references (collectively, *references*) may be restricted to support compiling to SPIR-V *logical mode*. In this mode, references may never point to data structures that have references in them. References must be initialized upon declaration and never reassigned. Functions that return references must have one return point. Ternary expressions may not return references.
     476- Pointers and array references (collectively, *references*) may be restricted to support compiling to SPIR-V *logical mode*. In this mode, arrays must not transitively hold references. References must be initialized upon declaration and never reassigned. Functions that return references must have one return point. Ternary expressions may not return references.
    477477- Graphics entry points must transitively never refer to the `threadgroup` memory space.
    478478
  • trunk/Tools/WebGPUShadingLanguageRI/index.html

    r222770 r223246  
    301301    availableVertexShaders = [];
    302302    availableFragmentShaders = [];
    303     for (functionNames of program.functions.values()) {
    304         for (func of functionNames) {
     303    for (let functionNames of program.functions.values()) {
     304        for (let func of functionNames) {
    305305            if (func.shaderType == "vertex")
    306306                availableVertexShaders.push(func);
Note: See TracChangeset for help on using the changeset viewer.