protected override void OnTranslate(ShaderTranslationContext sc, MethodDeclarationSyntax syntax, ScopeInfo scope) { MethodInfo info = sc.GetMethodInfo(syntax); if (info != null) { MappedEntryPoint ep = null; sc.EntryPointsByMethod.TryGetValue(info, out ep); sc.Source.AppendLineBreak(); ScopeInfo mScope = sc.Source.OpenScope(ScopeType.Method, null, ep); mScope.Method = info; ShaderType returnType = ShaderType.TranslateType(sc, syntax.ReturnType.ToString()); ep?.Translator?.TranslatePrefix(sc, info, syntax, ep); sc.Source.Append($"{returnType.Translation} {syntax.Identifier.ValueText}"); sc.Complete(syntax.ReturnType); sc.Complete(syntax.ConstraintClauses); sc.Complete(syntax.AttributeLists); if (syntax.TypeParameterList != null) { sc.CompleteSelfAndChildren(syntax.TypeParameterList); } // Translate parameters before method body. sc.Runner.Translate(sc, syntax.ParameterList, 0); ep?.Translator?.TranslatePostfix(sc, info, syntax, ep); } }
protected override void OnTranslate(ShaderTranslationContext sc, IdentifierNameSyntax syntax, ScopeInfo scope) { if (syntax.Parent is InvocationExpressionSyntax invSyntax) { string translatedIntrinsic = ShaderType.GetIntrinsicTranslation(sc, syntax.Identifier.ValueText); sc.Source.Append(translatedIntrinsic); } else { ScopeInfo cScope = scope.FindOfType(ScopeType.Class); PropertyInfo pInfo = cScope?.TypeInfo.OriginalType.GetProperty(syntax.Identifier.ValueText); if (pInfo != null) { if (syntax.Parent is AssignmentExpressionSyntax aSyntax) { if (aSyntax.Left == syntax) { TranslatePropertyAssignment(sc, syntax, aSyntax); } } else if (syntax.Parent is MemberAccessExpressionSyntax mSyntax && mSyntax.Parent is AssignmentExpressionSyntax maSyntax && maSyntax.Left == mSyntax) { TranslatePropertyAssignment(sc, syntax, maSyntax); } else // Safe to assume it's a property get call. { sc.Source.Append($"get{syntax.Identifier}()"); } }
protected override void OnTranslate(ShaderTranslationContext sc, StructDeclarationSyntax syntax, ScopeInfo scope) { string typeName = syntax.Identifier.ToString(); string headerTranslation = ""; StructScopeType scopeType = StructScopeType.Struct; Type sType = null; if (sc.ConstantBuffers.TryGetValue(typeName, out MappedConstantBuffer cMap)) { sType = cMap.TypeInfo; IEnumerable <Attribute> cBufferAttributes = sType.GetCustomAttributes(false).Cast <Attribute>(); sc.Language.TranslateConstBufferHeader(sc, syntax, cMap, cBufferAttributes); scopeType = StructScopeType.ConstantBuffer; } else if (sc.Structures.TryGetValue(typeName, out sType)) { //IEnumerable<Attribute> cBufferAttributes = structInfo.GetCustomAttributes(false).Cast<Attribute>(); // TODO Add translation of struct attributes (e.g. [InputStructure] or [OutputStructure]). sc.Source.AppendLineBreak(); sc.Source.Append($"struct {syntax.Identifier}"); scopeType = StructScopeType.Struct; } sc.Source.Append(headerTranslation); ScopeInfo structScope = sc.Source.OpenScope(ScopeType.Struct, sType); structScope.StructType = scopeType; sc.CompleteSelfAndChildren(syntax.AttributeLists); }
public virtual void TranslateParameterPrefix(ShaderTranslationContext sc, ParameterSyntax syntax, MappedEntryPoint ep, ParameterInfo pInfo, IEnumerable <Attribute> attributes, int parameterIndex) { foreach (Attribute a in attributes) { TranslateParameterAttributePrefix(sc, a, pInfo, ep); } }
protected override void OnTranslate(ShaderTranslationContext sc, PredefinedTypeSyntax syntax, ScopeInfo scope) { string typeName = syntax.Keyword.ToString(); ShaderType type = ShaderType.TranslateType(sc, typeName); sc.Source.Append(type.Translation); }
protected override void OnTranslate(ShaderTranslationContext sc, ElseClauseSyntax syntax, ScopeInfo scope) { sc.Source.Append("else "); if (!(syntax.Statement is BlockSyntax || syntax.Statement is IfStatementSyntax)) { sc.Source.OpenScope(ScopeType.Block); } }
protected override void OnTranslate(ShaderTranslationContext sc, ConditionalExpressionSyntax syntax, ScopeInfo scope) { sc.Runner.Translate(sc, syntax.Condition); sc.Source.Append(" ? "); sc.Runner.Translate(sc, syntax.WhenTrue); sc.Source.Append(" : "); sc.Runner.Translate(sc, syntax.WhenFalse); }
protected override void OnTranslate(ShaderTranslationContext sc, InitializerExpressionSyntax syntax, ScopeInfo scope) { if (syntax.Parent is ArrayCreationExpressionSyntax arrayCreationSyntax || syntax.Parent is EqualsValueClauseSyntax equalsAssignmentSyntax) { ScopeInfo iScope = sc.Source.OpenScope(ScopeType.ArrayInitializer); iScope.Items = syntax.Expressions; } }
public virtual void TranslatePostfix(ShaderTranslationContext sc, MethodInfo info, MethodDeclarationSyntax syntax, MappedEntryPoint ep) { SemanticAttribute attSemantic = info.GetCustomAttribute <SemanticAttribute>(); if (attSemantic != null) { TranslateSemantic(sc, attSemantic); } }
public override void TranslatePrefix(ShaderTranslationContext sc, MethodInfo info, MethodDeclarationSyntax syntax, MappedEntryPoint ep) { ComputeShaderAttribute attCompute = ep.Attribute as ComputeShaderAttribute; sc.Source.Append($"[numthreads({attCompute.ThreadsX}, {attCompute.ThreadsY}, {attCompute.ThreadsZ})]"); sc.Source.AppendLineBreak(); base.TranslatePrefix(sc, info, syntax, ep); }
protected override void OnTranslate(ShaderTranslationContext sc, ArgumentSyntax syntax, ScopeInfo scope) { if (scope.Type == ScopeType.Parentheses) { if (scope.Items.Last() != syntax) { sc.Source.OpenScope(ScopeType.ParenthesesItem); } } }
public override void TranslatePrefix(ShaderTranslationContext sc, MethodInfo info, MethodDeclarationSyntax syntax, MappedEntryPoint ep) { DomainShaderAttribute attHull = ep.Attribute as DomainShaderAttribute; string patchType = attHull.PatchType.ToString().ToLower(); sc.Source.Append($"[domain(\"{patchType}\")]"); sc.Source.AppendLineBreak(); base.TranslatePrefix(sc, info, syntax, ep); }
protected override void OnTranslate(ShaderTranslationContext sc, IfStatementSyntax syntax, ScopeInfo scope) { sc.Source.Append("if("); sc.Runner.Translate(sc, syntax.Condition); sc.Source.Append(")"); if (!(syntax.Statement is BlockSyntax)) { sc.Source.OpenScope(ScopeType.Block); } }
protected override void OnTranslate(ShaderTranslationContext sc, BlockSyntax syntax, ScopeInfo scope) { if (syntax.Parent is UnsafeStatementSyntax || scope == sc.Source.RootScope) { return; } bool declarative = scope.Parent.Type == ScopeType.Method; sc.Source.OpenScope(ScopeType.Block); }
protected override void OnTranslate(ShaderTranslationContext sc, PropertyDeclarationSyntax syntax, ScopeInfo scope) { ScopeInfo classScope = scope.FindOfType(ScopeType.Class); ScopeInfo pScope = sc.Source.OpenScope(ScopeType.Property); pScope.Identifier = syntax.Identifier.ValueText; sc.Complete(syntax.Type); pScope.TypeInfo = ShaderType.TranslateType(sc, syntax.Type.ToString()); }
private void TranslateSemantic(ShaderTranslationContext sc, SemanticAttribute attribute) { string semanticName = attribute.Semantic.ToString().ToUpper(); sc.Source.Append($" : {semanticName}"); if (attribute.Slot >= 0) { sc.Source.Append(attribute.Slot.ToString()); } }
protected override void OnTranslate(ShaderTranslationContext sc, ObjectCreationExpressionSyntax syntax, ScopeInfo scope) { // Are we directly inside an initializer? (i.e. array initializer) if (scope.Type == ScopeType.ArrayInitializer) { if (syntax != scope.Items.Last()) { sc.Source.OpenScope(ScopeType.ArrayElement); } } string typeName = syntax.Type.ToString(); ShaderType type = ShaderType.TranslateType(sc, typeName); sc.Complete(syntax.Type); // Handle initializers. These require declaring as a local variable above the current syntax node. if (syntax.Initializer != null) { switch (syntax.Parent) { case ReturnStatementSyntax returnSyntax: case AssignmentExpressionSyntax assignSyntax: string strInit = type.Translation; string varName = sc.Parent.GetNewVariableName("oc_init"); scope.DeclareLocal(sc, () => { sc.Source.Append($"{type.Translation} {varName} = {type.Translation}"); sc.Runner.Translate(sc, syntax.ArgumentList); sc.Source.Append(";"); sc.Source.AppendLineBreak(); ScopeInfo iScope = sc.Source.OpenScope(ScopeType.ExpandedInitializer); iScope.Identifier = varName; sc.Runner.Translate(sc, syntax.Initializer); }); sc.Source.Append(varName); break; default: sc.Source.Append(type.Translation); break; } } else { sc.Source.Append(type.Translation); } }
protected override void OnTranslate(ShaderTranslationContext sc, ArrowExpressionClauseSyntax syntax, ScopeInfo scope) { if (scope.Type == ScopeType.Method) { sc.Source.OpenScope(ScopeType.Block); if (scope.Method.ReturnType != typeof(void)) { sc.Source.Append("return "); } sc.Source.OpenScope(ScopeType.Variable); } }
protected override void OnTranslate(ShaderTranslationContext sc, ClassDeclarationSyntax syntax, ScopeInfo scope) { if ($"{sc.ShaderType.Namespace}.{syntax.Identifier.ValueText}" != sc.Name) { // TODO does the shader language support classes? // If not, we need a system to translate the class into another form of usable output source. Type t = sc.Parent.Reflection.Assembly.GetType($"{scope.Namespace}+{syntax.Identifier.ValueText}"); ScopeInfo cScope = sc.Source.OpenScope(ScopeType.Class, t); } else { sc.Complete(syntax.BaseList); } }
protected override void OnTranslate(ShaderTranslationContext sc, OmittedArraySizeExpressionSyntax syntax, ScopeInfo scope) { ArrayCreationExpressionSyntax arrayCreationSyntax = syntax.FirstAncestorOrSelf <ArrayCreationExpressionSyntax>(); if (arrayCreationSyntax != null) { if (arrayCreationSyntax.Initializer != null) { IEnumerable <SyntaxNode> initChildren = arrayCreationSyntax.Initializer.ChildNodes(); int arraySize = initChildren.Count(); sc.Source.Append(arraySize.ToString()); } } }
protected override void OnTranslate(ShaderTranslationContext sc, FieldDeclarationSyntax syntax, ScopeInfo scope) { // Does the language allow instanced constant buffers and does the field use a constant buffer struct type? if (sc.ConstantBuffers.ContainsKey(syntax.Declaration.Type.ToString())) { if (!sc.Language.InstancedConstantBuffers) { sc.CompleteSelfAndChildren(syntax); } } else { sc.CompleteSelfAndChildren(syntax.AttributeLists); } }
private void TranslateList <T>(ShaderTranslationContext sc, SeparatedSyntaxList <T> list) where T : SyntaxNode { T firstIncrementor = list.FirstOrDefault(); foreach (T es in list) { Type test = es.GetType(); if (es != firstIncrementor) { sc.Source.Append(", "); } sc.Runner.Translate(sc, es); } }
public virtual void TranslateParameterPostfix(ShaderTranslationContext sc, ParameterSyntax syntax, MappedEntryPoint ep, ParameterInfo pInfo, IEnumerable <Attribute> attributes, int parameterIndex) { foreach (Attribute a in attributes) { switch (a) { case SemanticAttribute attSemantic: TranslateSemantic(sc, attSemantic); break; default: TranslateParameterAttributePostfix(sc, a, pInfo, ep); break; } } }
protected override void OnTranslate(ShaderTranslationContext sc, ForStatementSyntax syntax, ScopeInfo scope) { sc.Language.TranslateForLoopPrefix(sc, syntax); sc.Source.AppendLineBreak(); sc.Source.Append("for("); if (syntax.Declaration != null) { sc.Runner.Translate(sc, syntax.Declaration); } TranslateList(sc, syntax.Initializers); sc.Source.Append("; "); sc.Runner.Translate(sc, syntax.Condition); sc.Source.Append("; "); TranslateList(sc, syntax.Incrementors); sc.Source.Append(")"); }
protected override void OnTranslate(ShaderTranslationContext sc, AssignmentExpressionSyntax syntax, ScopeInfo scope) { if (scope.Type == ScopeType.ExpandedInitializer) { sc.Source.Append($"{scope.Identifier}."); sc.Source.OpenScope(ScopeType.Variable); } // TODO check if the assignment uses a valid operator. Does the language support operand assignments (e.g *= += or /=) sc.Runner.Translate(sc, syntax.Left); if (sc.IsCompleted(syntax.Right)) // Property translation may have replaced the assignment with a set-method call. { return; } sc.Source.Append($" {syntax.OperatorToken} "); sc.Runner.Translate(sc, syntax.Right); }
protected override void OnTranslate(ShaderTranslationContext sc, VariableDeclarationSyntax syntax, ScopeInfo scope) { string typeName = syntax.Type.ToString(); ShaderType type = ShaderType.TranslateType(sc, typeName); ScopeInfo tScope = sc.Source.OpenScope(ScopeType.Typed, type); tScope.TypeInfo = type; tScope.IsLocal = syntax.Parent is LocalDeclarationStatementSyntax; tScope.Items = syntax.Variables; if (syntax.Parent is FieldDeclarationSyntax fieldSyntax) { tScope.TranslatedModifiers = sc.Language.TranslateModifiers(fieldSyntax.Modifiers); } sc.Complete(syntax.Type); }
protected override void OnTranslate(ShaderTranslationContext sc, ParameterSyntax syntax, ScopeInfo scope) { ScopeInfo methodScope = scope.FindOfType(ScopeType.Method); MethodInfo methodInfo = null; MappedEntryPoint ep = null; if (scope.Type == ScopeType.Parentheses) { if (scope.Items.Last() != syntax) { sc.Source.OpenScope(ScopeType.ParenthesesItem); } } if (methodScope != null) { methodInfo = methodScope.Method; sc.EntryPointsByMethod.TryGetValue(methodInfo, out ep); } // TODO pass to language variable translation, since parameters can have attributes ShaderType type = ShaderType.TranslateType(sc, syntax.Type.ToString()); bool wasAppended = false; if (ep != null) { (ParameterInfo pInfo, int pIndex) = sc.GetParameterInfo(methodInfo, syntax.Identifier.ValueText); IEnumerable <Attribute> pAttributes = pInfo.GetCustomAttributes(); ep.Translator?.TranslateParameterPrefix(sc, syntax, ep, pInfo, pAttributes, pIndex); sc.Source.Append($"{type.Translation} {syntax.Identifier.ValueText}"); ep.Translator?.TranslateParameterPostfix(sc, syntax, ep, pInfo, pAttributes, pIndex); wasAppended = true; } if (!wasAppended) { sc.Source.Append($"{type.Translation} {syntax.Identifier.ValueText}"); } sc.Complete(syntax.Type); sc.Complete(syntax.AttributeLists); }
protected override void OnTranslate(ShaderTranslationContext sc, AccessorDeclarationSyntax syntax, ScopeInfo scope) { if (scope.Type == ScopeType.Property) { switch (syntax.Keyword.ValueText) { case "get": sc.Source.Append($"{scope.TypeInfo.Translation} get{scope.Identifier}()"); break; case "set": sc.Source.Append($"void set{scope.Identifier}({scope.TypeInfo.Translation} value)"); break; } ScopeInfo mScope = sc.Source.OpenScope(ScopeType.Method); ScopeInfo classScope = scope.FindOfType(ScopeType.Class); mScope.Method = classScope.TypeInfo.OriginalType.GetMethod($"{syntax.Keyword.ValueText}_{scope.Identifier}"); } }
public override void TranslatePrefix(ShaderTranslationContext sc, MethodInfo info, MethodDeclarationSyntax syntax, MappedEntryPoint ep) { HullShaderAttribute attHull = ep.Attribute as HullShaderAttribute; string patchType = attHull.PatchType.ToString().ToLower(); sc.Source.Append($"[domain(\"{patchType}\")]"); sc.Source.AppendLineBreak(); string partType = _partitionNames[attHull.Partitioning]; sc.Source.Append($"[partitioning(\"{partType}\")]"); sc.Source.AppendLineBreak(); string topology = _topologyNames[attHull.Topology]; sc.Source.Append($"[outputtopology(\"{topology}\")]"); sc.Source.AppendLineBreak(); sc.Source.Append($"[outputcontrolpoints({attHull.OutputControlPoints})]"); sc.Source.AppendLineBreak(); sc.Source.Append($"[patchconstantfunc(\"{attHull.PatchConstantCallback}\")]"); sc.Source.AppendLineBreak(); }
protected override void OnTranslate(ShaderTranslationContext sc, ArgumentListSyntax syntax, ScopeInfo scope) { ScopeInfo pScope = sc.Source.OpenScope(ScopeType.Parentheses); pScope.Items = syntax.Arguments; }