Exemple #1
0
 public void AddFunctionStatement(ResultId?resultId, SpirvStatement statement)
 {
     this.GetEntryList(3).Add(new StatementEntry
     {
         ResultId  = resultId,
         Statement = statement
     });
 }
Exemple #2
0
 public void AddGlobalStatement(ResultId?resultId, SpirvStatement statement)
 {
     this.GetEntryList(2).Add(new StatementEntry
     {
         ResultId  = resultId,
         Statement = statement
     });
 }
Exemple #3
0
 public void AddHeaderStatement(ResultId?resultId, SpirvStatement statement)
 {
     this.GetEntryList(0).Add(new StatementEntry
     {
         ResultId  = resultId,
         Statement = statement
     });
 }
Exemple #4
0
        private ResultId VisitNew(NewExpression expression)
        {
            SpirvStatement statement;

            if (this.vectorLibrary.IsVectorType(expression.Type))
            {
                var operands = new[] { this.Visit(Expression.Constant(expression.Type)) }
                .Concat(this.ExpandNewArguments(expression.Arguments));

                statement = new SpirvStatement(Op.OpCompositeConstruct, operands.Cast <object>().ToArray());
            }
            else
            {
                throw new NotImplementedException("New expressions are only implemented for vector types.");
            }

            ResultId resultId = this.file.GetNextResultId();

            this.file.AddFunctionStatement(resultId, statement);

            return(resultId);
        }
Exemple #5
0
        private ResultId VisitConstant(ConstantExpression expression)
        {
            SpirvStatement statement;

            if (this.vectorLibrary.IsVectorType(expression.Type))
            {
                var operands = new object[] { expression.Type }
                .Concat(((IEnumerable)expression.Value).OfType <object>())
                .Select(x => (object)this.Visit(Expression.Constant(x)));

                statement = new SpirvStatement(Op.OpConstantComposite, operands.ToArray());
            }
            else if (typeof(Type).IsAssignableFrom(expression.Type))
            {
                Type value = (Type)expression.Value;

                if (this.vectorLibrary.IsMatrixType(value))
                {
                    Type  rowType    = this.vectorLibrary.GetMatrixRowType(value);
                    int[] dimensions = this.vectorLibrary.GetMatrixDimensions(value);

                    ResultId rowTypeId = this.Visit(Expression.Constant(rowType));

                    statement = new SpirvStatement(Op.OpTypeMatrix, rowTypeId, dimensions[0]);
                }
                else if (this.vectorLibrary.IsVectorType(value))
                {
                    Type elementType = this.vectorLibrary.GetVectorElementType(value);
                    int  length      = this.vectorLibrary.GetVectorLength(value);

                    ResultId elementTypeId = this.Visit(Expression.Constant(elementType));

                    statement = new SpirvStatement(Op.OpTypeVector, elementTypeId, length);
                }
                else if (typeof(Delegate).IsAssignableFrom(value))
                {
                    var returnType = value.GetMethod("Invoke").ReturnType;

                    ResultId returnTypeId = this.Visit(Expression.Constant(returnType));

                    if (value.GetMethod("Invoke").GetParameters().Length > 0)
                    {
                        throw new NotImplementedException();
                    }

                    statement = new SpirvStatement(Op.OpTypeFunction, returnTypeId);
                }
                else if (value.BaseType.IsGenericType && value.BaseType.GetGenericTypeDefinition() == typeof(Pointer <>))
                {
                    StorageClass storage = (StorageClass)value.GetProperty("Storage").GetValue(null);
                    ResultId     typeId  = this.Visit(Expression.Constant(value.GetGenericArguments()[0]));

                    statement = new SpirvStatement(Op.OpTypePointer, storage, typeId);
                }
                else if (IsTupleType(value))
                {
                    var fieldTypes = value.GetGenericArguments();

                    var fieldTypeIds = fieldTypes.Select(x => (object)this.Visit(Expression.Constant(x))).ToArray();

                    statement = new SpirvStatement(Op.OpTypeStruct, fieldTypeIds);
                }
                else if (value == typeof(float))
                {
                    statement = new SpirvStatement(Op.OpTypeFloat, 32);
                }
                else if (value == typeof(int))
                {
                    statement = new SpirvStatement(Op.OpTypeInt, 32, 1);
                }
                else if (value == typeof(void))
                {
                    statement = new SpirvStatement(Op.OpTypeVoid);
                }
                else if (value.IsValueType)
                {
                    var fieldTypeIds = value.GetFields().Select(x => (object)this.Visit(Expression.Constant(x.FieldType))).ToArray();

                    statement = new SpirvStatement(Op.OpTypeStruct, fieldTypeIds);
                }
                else
                {
                    throw new NotImplementedException($"Constants of type {value} are not implemented.");
                }
            }
            else
            {
                ResultId typeOperand = this.Visit(Expression.Constant(expression.Type));
                statement = new SpirvStatement(Op.OpConstant, typeOperand, expression.Value);
            }

            ResultId resultId;

            if (!this.expressionResults.TryGetValue(statement, out resultId))
            {
                resultId = this.file.GetNextResultId();

                this.expressionResults.Add(statement, resultId);

                this.file.AddGlobalStatement(resultId, statement);
            }

            return(resultId);
        }
Exemple #6
0
 /// <summary>
 /// Output the specified statement
 /// </summary>
 /// <param name="sink">
 /// The sink to which to output the statement.
 /// </param>
 /// <param name="statement">
 /// The SPIR-V statement to output to this sink instance.
 /// </param>
 public static void AddStatement(this ISpirvSink sink, SpirvStatement statement)
 {
     sink.AddStatement(null, statement);
 }