/// <summary> /// Initializes a new instance of the <see cref="GlobalUniformVisitor"/> class. /// </summary> /// <param name="shader">The shader.</param> public GlobalUniformVisitor(Shader shader) { this.shader = shader; uniformReadList = new List<Variable>(); this.UniformUsedWriteFirstList = new List<Variable>(); this.UniformReadWriteList = new List<Variable>(); }
public SamplerMappingVisitor(Shader shader, Dictionary<SamplerTextureKey, Variable> samplerMapping) { this.shader = shader; this.samplerMapping = samplerMapping; textureAccesses = new HashSet<Variable>(); // Add all global declarations for clone context in order to avoid any clone on this object foreach (var variable in shader.Declarations) { cloneContext.Add(variable, variable); } }
/// <summary> /// Initializes a new instance of the <see cref="ShaderMixinCodeGen" /> class. /// </summary> /// <param name="shader">The shader.</param> /// <param name="logging">The logging.</param> /// <exception cref="System.ArgumentNullException">shader or logging</exception> /// <exception cref="System.InvalidOperationException">Cannot process shaders having already parsing errors</exception> public ShaderMixinCodeGen(Shader shader, LoggerResult logging) { if (shader == null) throw new ArgumentNullException("shader"); if (logging == null) throw new ArgumentNullException("logging"); this.shader = shader; this.logging = logging; EnablePreprocessorLine = false; }
/// <summary> /// Run the analysis /// </summary> /// <param name="mixinToAnalyze">the current context (virtual table) from mixin inheritance</param> /// <param name="compilationContext">List of all the mixin in the compilation context</param> /// <returns>true if the shader is correct, false otherwise</returns> public static XenkoParsingInfo RunAnalysis(ModuleMixin mixinToAnalyze, List<ModuleMixin> compilationContext, bool transformForEach = false) { var shader = new Shader(); shader.Declarations.Add(mixinToAnalyze.Shader); var toParse = new ParsingResult { Shader = shader }; var analysis = new XenkoSemanticAnalysis(toParse, mixinToAnalyze, compilationContext) { parsingInfo = new XenkoParsingInfo() }; analysis.expandForEachStatements = transformForEach; analysis.Run(); // look at the static classes analysis.parsingInfo.StaticClasses.UnionWith(analysis.parsingInfo.StaticReferences.VariablesReferences.Select(x => x.Key.GetTag(XenkoTags.ShaderScope) as ModuleMixin)); analysis.parsingInfo.StaticClasses.UnionWith(analysis.parsingInfo.StaticReferences.MethodsReferences.Select(x => x.Key.GetTag(XenkoTags.ShaderScope) as ModuleMixin)); analysis.parsingInfo.StaticClasses.Remove(mixinToAnalyze); analysis.parsingInfo.ErrorsWarnings = analysis.ParsingResult; return analysis.parsingInfo; }
public virtual void Visit(Shader shader) { Visit((Node)shader); }
public void Run(Shader shader) { Visit(shader); }
public Shader GetMixedShader() { var shader = new Shader(); shader.Declarations.AddRange(MixedShader.Members); return shader; }
/// <summary> /// Visits the specified shader. /// </summary> /// <param name="shader">The shader.</param> /// <returns></returns> public override void Visit(Shader shader) { base.Visit(shader); }
public void Visit(Shader shader) { indirectReferences = new Dictionary<Node, HashSet<Node>>(); // Visit AST. Visit((Node) shader); // Get list of function referenced (directly or indirectly) by entry point. // Using hashset and recursion to avoid cycle. var collectedReferences = new List<Node>(); foreach (var entryPointName in entryPoints) { // Find entry point var entryPoint = shader.Declarations.OfType<MethodDefinition>().FirstOrDefault(x => x.Name == entryPointName); if (entryPoint == null) throw new ArgumentException(string.Format("Could not find entry point named {0}", entryPointName)); CollectReferences(collectedReferences, entryPoint); } if (KeepConstantBuffers) { // Include dependencies of cbuffer (i.e. dependent types) foreach (var variable in shader.Declarations.OfType<ConstantBuffer>()) { CollectReferences(collectedReferences, variable); } } StripDeclarations(shader.Declarations, collectedReferences, StripUniforms); }
public override void Visit(Shader shader) { indirectReferences = new Dictionary<Node, HashSet<Node>>(); // Visit AST. base.Visit( shader); // Get list of function referenced (directly or indirectly) by entry point. // Using hashset and recursion to avoid cycle. var collectedReferences = new List<Node>(); foreach (var entryPointName in entryPoints) { // Find entry point var entryPoint = shader.Declarations.OfType<MethodDefinition>().FirstOrDefault(x => x.Name == entryPointName); if (entryPoint == null) throw new ArgumentException(string.Format("Could not find entry point named {0}", entryPointName)); CollectReferences(collectedReferences, entryPoint); } StripDeclarations(shader.Declarations, collectedReferences, StripUniforms); }
public void Run(ShaderClassType shaderClassType) { var shader = new Shader(); shader.Declarations.Add(shaderClassType); Run(shader); }
public void Run(Shader shader) { VisitDynamic(shader); }
/// <inheritdoc/> public override void Visit(Shader shader) { // #version Write("#version "); Write(shaderVersion.ToString()); // ES3+ expects "es" at the end of #version if (shaderPlatform == GlslShaderPlatform.OpenGLES && shaderVersion >= 300) Write(" es"); WriteLine(); WriteLine(); if (shaderPlatform == GlslShaderPlatform.OpenGLES) { WriteLine("precision highp float;"); WriteLine("precision highp int;"); if (shaderVersion >= 300) { WriteLine("precision lowp sampler3D;"); WriteLine("precision lowp samplerCubeShadow;"); WriteLine("precision lowp sampler2DShadow;"); WriteLine("precision lowp sampler2DArray;"); WriteLine("precision lowp sampler2DArrayShadow;"); WriteLine("precision lowp isampler2D;"); WriteLine("precision lowp isampler3D;"); WriteLine("precision lowp isamplerCube;"); WriteLine("precision lowp isampler2DArray;"); WriteLine("precision lowp usampler2D;"); WriteLine("precision lowp usampler3D;"); WriteLine("precision lowp usamplerCube;"); WriteLine("precision lowp usampler2DArray;"); } if (shaderVersion >= 320 || SupportsTextureBuffer) { WriteLine("precision lowp samplerBuffer;"); WriteLine("precision lowp isamplerBuffer;"); WriteLine("precision lowp usamplerBuffer;"); } WriteLine(); if (shaderVersion < 320 && SupportsTextureBuffer) { // In ES 3.1 and previous, we use texelFetchBuffer in case it needs to be remapped into something else by user WriteLine("#define texelFetchBuffer(sampler, P) texelFetch(sampler, P)"); } } if (ExtraHeaders != null) WriteLine(ExtraHeaders); if (shader == null) { // null entry point for pixel shader means no pixel shader. In that case, we return a default function. // TODO: support that directly in HlslToGlslConvertor? if (pipelineStage == PipelineStage.Pixel) { WriteLine("out float fragmentdepth; void main(){ fragmentdepth = gl_FragCoord.z; }"); } else { throw new NotSupportedException($"Can't output empty {pipelineStage} shader for platform {shaderPlatform} version {shaderVersion}."); } } else { base.Visit(shader); } }
private static Shader PrepareShader(Shader shader) { if (shader == null) { return null; } // Replace all variable in constant buffers by single variable with a constant buffer tag foreach (var classType in GetShaderClassTypes(shader.Declarations)) { var members = new List<Node>(); foreach (var member in classType.Members) { var constantBuffer = member as ConstantBuffer; if (constantBuffer != null) { var variables = new List<Node>(); foreach (var variable in constantBuffer.Members.OfType<Variable>()) { foreach (var subVariable in variable.Instances()) { subVariable.SetTag(XenkoTags.ConstantBuffer, constantBuffer); if (variable.IsGroup && !ReferenceEquals(variable, subVariable)) { subVariable.Qualifiers |= variable.Qualifiers; subVariable.Attributes.AddRange(variable.Attributes); } variables.Add(subVariable); } } members.AddRange(variables); } else { members.Add(member); } } classType.Members = members; } return shader; }