Exemplo n.º 1
0
    static void BuildOutputDescription(StringBuilder sb, VeldridTypeInfo type, VeldridMemberInfo depth)
    {
        sb.AppendLine($@"        public override OutputDescription? OutputDescription
        {{
            get
            {{
                OutputAttachmentDescription? depthAttachment = {(depth == null ? "null" : $"new(global::{depth.DepthAttachment.Format})")};
                OutputAttachmentDescription[] colorAttachments =
                {{");
        bool first = true;

        foreach (var color in type.Members.Where(x => x.ColorAttachment != null))
        {
            if (!first)
            {
                sb.AppendLine(",");
            }
            sb.Append($"                    new(global::{color.ColorAttachment.Format})");
            first = false;
        }

        sb.AppendLine(@"
                };
                return new OutputDescription(depthAttachment, colorAttachments);
            }
        }
");
    }
Exemplo n.º 2
0
    public static void EmitEnums(StringBuilder sb, VeldridTypeInfo shaderType, GenerationContext context)
    {
        var enumTypes = FindEnumTypes(shaderType, context);

        foreach (var kvp in enumTypes)
        {
            var underlying = kvp.Key.EnumUnderlyingType;
            if (underlying == null)
            {
                continue;
            }

            sb.Append("// ");
            sb.AppendLine(kvp.Key.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat));

            var affix = EnumAffix(underlying.SpecialType);
            foreach (var value in EnumUtil.GetEnumValues(kvp.Key).OrderBy(x => x.value))
            {
                sb.Append("#define ");
                sb.Append(TweakEnumMemberName(value.field.Name, kvp.Value));
                sb.Append(" 0x");
                sb.AppendFormat("{0:X}", value.value);
                sb.AppendLine(affix);
            }

            sb.AppendLine();
        }
    }
Exemplo n.º 3
0
 static void EmitResourceSets(StringBuilder sb, VeldridTypeInfo shaderType, GenerationContext context)
 {
     var stageValue = EnumUtil.GetEnumValue((IFieldSymbol)(shaderType.Shader.ShaderType switch
     {
         ShaderType.Vertex => context.Symbols.ShaderStages.Vertex,
         ShaderType.Fragment => context.Symbols.ShaderStages.Fragment,
         ShaderType.Compute => context.Symbols.ShaderStages.Compute,
         _ => throw new ArgumentOutOfRangeException(nameof(shaderType), $"\"{shaderType}\" shaders are currently unsupported.")
     }));
Exemplo n.º 4
0
    public static void Generate(StringBuilder sb, VeldridTypeInfo type)
    {
        var depth = type.Members.SingleOrDefault(x => x.DepthAttachment != null);

        BuildConstructor(sb, type, depth);
        BuildCreateFramebuffer(sb, type, depth);
        BuildOutputDescription(sb, type, depth);
        BuildDispose(sb, type, depth);
    }
Exemplo n.º 5
0
    static void BuildDispose(StringBuilder sb, VeldridTypeInfo type, VeldridMemberInfo depth)
    {
        sb.AppendLine(@"        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);");
        if (depth != null)
        {
            sb.AppendLine($@"            {depth.Symbol.Name}.DeviceTexture?.Dispose();");
            sb.AppendLine($@"            {depth.Symbol.Name}.DeviceTexture = null;");
        }

        foreach (var member in type.Members.Where(member => member.ColorAttachment != null))
        {
            sb.AppendLine($@"            {member.Symbol.Name}.DeviceTexture?.Dispose();");
            sb.AppendLine($@"            {member.Symbol.Name}.DeviceTexture = null;");
        }

        sb.AppendLine(@"        }");
    }
Exemplo n.º 6
0
    static void BuildConstructor(StringBuilder sb, VeldridTypeInfo type, VeldridMemberInfo depth)
    {
        var typeName = type.Symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat);

        sb.AppendLine(
            $@"        public {typeName}(uint width, uint height, string name) : base(width, height, name)
        {{");
        if (depth != null)
        {
            sb.AppendLine($@"            {depth.Symbol.Name} = new global::UAlbion.Core.Veldrid.Textures.Texture2DHolder(name + "".{depth.Symbol.Name}"");");
        }

        foreach (var color in type.Members.Where(member => member.ColorAttachment != null))
        {
            sb.AppendLine($@"            {color.Symbol.Name} = new global::UAlbion.Core.Veldrid.Textures.Texture2DHolder(name + "".{color.Symbol.Name}"");");
        }

        sb.AppendLine(@"        }
");
    }
Exemplo n.º 7
0
    static void BuildCreateFramebuffer(StringBuilder sb, VeldridTypeInfo type, VeldridMemberInfo depth)
    {
        sb.AppendLine(@"        protected override Framebuffer CreateFramebuffer(global::Veldrid.GraphicsDevice device)
        {
            if (device == null) throw new System.ArgumentNullException(nameof(device));");

        if (depth != null)
        {
            sb.AppendLine($@"            {depth.Symbol.Name}.DeviceTexture = device.ResourceFactory.CreateTexture(new TextureDescription(
                    Width, Height, 1, 1, 1,
                    global::{depth.DepthAttachment.Format}, TextureUsage.DepthStencil, TextureType.Texture2D));
            {depth.Symbol.Name}.DeviceTexture.Name = {depth.Symbol.Name}.Name;
");
        }

        foreach (var color in type.Members.Where(member => member.ColorAttachment != null))
        {
            sb.AppendLine($@"            {color.Symbol.Name}.DeviceTexture = device.ResourceFactory.CreateTexture(new TextureDescription(
                    Width, Height, 1, 1, 1,
                    global::{color.ColorAttachment.Format}, TextureUsage.RenderTarget | TextureUsage.Sampled, TextureType.Texture2D));
            {color.Symbol.Name}.DeviceTexture.Name = {color.Symbol.Name}.Name;
");
        }

        sb.Append("            var description = new FramebufferDescription(");
        sb.Append(depth != null ? depth.Symbol.Name + ".DeviceTexture" : "null");

        foreach (var member in type.Members.Where(member => member.ColorAttachment != null))
        {
            sb.Append(", ");
            sb.Append(member.Symbol.Name);
            sb.Append(".DeviceTexture");
        }

        sb.AppendLine(@");
            var framebuffer = device.ResourceFactory.CreateFramebuffer(ref description);
            framebuffer.Name = Name;
            return framebuffer;
        }
");
    }
Exemplo n.º 8
0
        public static void Generate(StringBuilder sb, VeldridTypeInfo shaderType, GenerationContext context)
        {
            var extension      = Path.GetExtension(shaderType.Shader.Filename);
            var headerFilename = Path.GetFileNameWithoutExtension(shaderType.Shader.Filename) + ".h" + extension;

            sb.AppendLine($@"        public static (string, string) ShaderSource()
        {{
            return (""{headerFilename}"", @""// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// !!! This file was auto-generated using VeldridGen. It should not be edited by hand. !!!
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//!#version 450 // Comments with //! are just for the VS GLSL plugin
//!#extension GL_KHR_vulkan_glsl: enable
");
            ShaderEnumGenerator.EmitEnums(sb, shaderType, context);
            EmitResourceSets(sb, shaderType, context);
            EmitInputs(sb, shaderType, context);
            EmitOutputs(sb, shaderType, context);

            sb.AppendLine(@""");
        }");
        }
Exemplo n.º 9
0
    public static void Generate(StringBuilder sb, VeldridTypeInfo type)
    {
        var members = type.Members.Where(x => (x.Vertex != null)).ToList();

        if (members.Count == 0)
        {
            return;
        }

        sb.AppendLine(@"        public static VertexLayoutDescription GetLayout(bool input) => new(");
        bool first = true;

        foreach (var member in members)
        {
            if (!first)
            {
                sb.AppendLine(",");
            }
            sb.Append($@"            new VertexElementDescription((input ? ""i"" : ""o"") + ""{member.Vertex.Name}"", VertexElementSemantic.TextureCoordinate, {member.Vertex.Format})");
            first = false;
        }
        sb.AppendLine(");");
    }
Exemplo n.º 10
0
 protected override void GenerateResourceSet(StringBuilder sb, VeldridTypeInfo type, GenerationContext context) => ResourceSetGenerator.Generate(sb, type, context);
Exemplo n.º 11
0
        public static void Generate(StringBuilder sb, VeldridTypeInfo type, GenerationContext context)
        {
            // TODO: Ensure the types actually exist, ensure that they're shaders of the appropriate type etc.
            // TODO: Ensure vertex shader outputs are compatible with fragment shader inputs
            var vshader = context.Types[type.Pipeline.VertexShader];
            var fshader = context.Types[type.Pipeline.FragmentShader];

            foreach (var input in vshader.Shader.Inputs.Where(x => x.Item3 != 0))
            {
                sb.AppendLine($@"        static VertexLayoutDescription {LayoutHelperName(input.Item2)}
        {{
            get
            {{
                var layout = {input.Item2.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)}.Layout;
                layout.InstanceStepRate = {input.Item3};
                return layout;
            }}
        }}
");
            }

            sb.Append($@"
        public {type.Symbol.Name}() : base(""{vshader.Shader.Filename}"", ""{fshader.Shader.Filename}"",
            new[] {{ ");

            // e.g. Vertex2DTextured.Layout, SpriteInstanceDataLayout
            bool first = true;

            foreach (var input in vshader.Shader.Inputs.OrderBy(x => x.Item1))
            {
                if (!first)
                {
                    sb.Append(", ");
                }

                sb.Append(input.Item3 == 0
                    ? $"{input.Item2.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)}.Layout"
                    : LayoutHelperName(input.Item2));
                first = false;
            }

            sb.AppendLine("},");

            sb.Append(@"            new[] { ");
            // e.g. typeof(CommonSet), typeof(SpriteArraySet) }})
            first = true;
            foreach (var set in vshader.Shader.ResourceSets.Union(fshader.Shader.ResourceSets))
            {
                if (!first)
                {
                    sb.Append(", ");
                }

                sb.Append($"typeof({set.Item2.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)})");
                first = false;
            }
            sb.AppendLine(" })");

            sb.AppendLine(@"        { }");

            /* e.g.
             * static VertexLayoutDescription SpriteInstanceDataLayout
             * {
             *  get
             *  {
             *      var layout = SpriteInstanceData.Layout;
             *      layout.InstanceStepRate = 1;
             *      return layout;
             *  }
             * }
             *
             * public SpritePipeline() : base("SpriteSV.vert", "SpriteSF.frag",
             *  new[] { Vertex2DTextured.Layout, SpriteInstanceDataLayout },
             *  new[] { typeof(CommonSet), typeof(SpriteArraySet) })
             * {
             * }
             */
        }
Exemplo n.º 12
0
 protected override void GenerateShader(StringBuilder sb, VeldridTypeInfo type, GenerationContext context) => ShaderGenerator.Generate(sb, type, context);
Exemplo n.º 13
0
 protected override void GeneratePipeline(StringBuilder sb, VeldridTypeInfo type, GenerationContext context) => PipelineGenerator.Generate(sb, type, context);
Exemplo n.º 14
0
 protected override void GenerateFramebuffer(StringBuilder sb, VeldridTypeInfo type, GenerationContext context) => FramebufferGenerator.Generate(sb, type);
Exemplo n.º 15
0
 protected override void GenerateVertexFormat(StringBuilder sb, VeldridTypeInfo type, GenerationContext context) => VertexFormatGenerator.Generate(sb, type);
Exemplo n.º 16
0
    public static void Generate(StringBuilder sb, VeldridTypeInfo type, GenerationContext context)
    {
        /* e.g.
         * new ResourceLayoutElementDescription("uSprite", ResourceKind.TextureReadOnly, ShaderStages.Fragment),
         * new ResourceLayoutElementDescription("uSpriteSampler", ResourceKind.Sampler, ShaderStages.Fragment),
         * new ResourceLayoutElementDescription("_Uniform", ResourceKind.UniformBuffer, ShaderStages.Vertex | ShaderStages.Fragment));
         */
        sb.AppendLine("        public static readonly ResourceLayoutDescription Layout = new(");
        bool first = true;

        foreach (var member in type.Members.Where(x => x.Resource != null))
        {
            if (!first)
            {
                sb.AppendLine(",");
            }

            var shaderStages = member.Resource.Stages.ToString(); // Util.FormatFlagsEnum(member.Resource.Stages);
            sb.Append($"            new ResourceLayoutElementDescription(\"{member.Resource.Name}\", global::{member.Resource.Kind}, (ShaderStages){shaderStages})");
            first = false;
        }
        sb.AppendLine(");");
        sb.AppendLine();

        foreach (var member in type.Members.Where(x => x.Resource != null))
        {
            if (Equals(member.Resource.Kind, context.Symbols.ResourceKind.UniformBuffer.ToDisplayString()))
            {
                GenerateUniform(sb, member, context);
            }
            else if (Equals(member.Resource.Kind, context.Symbols.ResourceKind.TextureReadOnly.ToDisplayString()))
            {
                GenerateTexture(sb, member, context);
            }
            else if (Equals(member.Resource.Kind, context.Symbols.ResourceKind.Sampler.ToDisplayString()))
            {
                GenerateSampler(sb, member, context);
            }
            else
            {
                context.Report($"Resource {member.Symbol.ToDisplayString()} in set {type.Symbol.ToDisplayString()} was of unexpected kind {member.Resource.Kind}");
            }
        }

        /* e.g. protected override ResourceSet Build(GraphicsDevice device, ResourceLayout layout) =>
         *  device.ResourceFactory.CreateResourceSet(new ResourceSetDescription(
         *      layout,
         *      _globalInfo.DeviceBuffer,
         *      _projection.DeviceBuffer,
         *      _view.DeviceBuffer,
         *      _palette.DeviceTexture)); */

        sb.Append(@"        protected override ResourceSet Build(GraphicsDevice device, ResourceLayout layout) =>
            device.ResourceFactory.CreateResourceSet(new ResourceSetDescription(
                layout");

        foreach (var member in type.Members.Where(x => x.Resource != null))
        {
            sb.AppendLine(",");

            if (member.Symbol is not IFieldSymbol field)
            {
                context.Report($"Resource set backing members must be fields (member {member.Symbol.ToDisplayString()} in {type.Symbol.ToDisplayString()} was a {member.Symbol.GetType().Name})");
                continue;
            }

            sb.Append("                ");
            sb.Append(field.Name);
            sb.Append('.');

            if (Equals(member.Resource.Kind, context.Symbols.ResourceKind.UniformBuffer.ToDisplayString()))
            {
                sb.Append("DeviceBuffer");
            }
            else if (Equals(member.Resource.Kind, context.Symbols.ResourceKind.TextureReadOnly.ToDisplayString()))
            {
                sb.Append("DeviceTexture");
            }
            else if (Equals(member.Resource.Kind, context.Symbols.ResourceKind.Sampler.ToDisplayString()))
            {
                sb.Append("Sampler");
            }
            else
            {
                context.Report($"Resource {member.Symbol.ToDisplayString()} in {type.Symbol.ToDisplayString()} was of unexpected kind \"{member.Resource.Kind}\"");
            }
        }

        sb.AppendLine("));");

        sb.AppendLine(@"
        protected override void Resubscribe()
        {");
        foreach (var member in type.Members.Where(x => x.Resource != null))
        {
            if (member.Type.AllInterfaces.Any(x => x.Equals(context.Symbols.NotifyPropertyChanged, SymbolEqualityComparer.Default)))
            {
                var field = (IFieldSymbol)member.Symbol;
                sb.AppendLine(
                    $@"            if ({field.Name} != null)
                {field.Name}.PropertyChanged += PropertyDirty;");
            }
        }

        sb.AppendLine("        }");

        sb.AppendLine(@"
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);");
        foreach (var member in type.Members.Where(x => x.Resource != null))
        {
            if (member.Type.AllInterfaces.Any(x => x.Equals(context.Symbols.NotifyPropertyChanged, SymbolEqualityComparer.Default)))
            {
                var field = (IFieldSymbol)member.Symbol;
                sb.AppendLine(
                    $@"            if ({field.Name} != null)
                {field.Name}.PropertyChanged -= PropertyDirty;");
            }
        }

        sb.AppendLine("        }");
    }