Example #1
0
 public ResourceDefinition(string name, int binding, TypeReference type, ShaderResourceKind kind)
 {
     Name         = name;
     Binding      = binding;
     ValueType    = type;
     ResourceKind = kind;
 }
        public override void VisitVariableDeclaration(VariableDeclarationSyntax node)
        {
            int resourceBinding = _lastResourceBinding++;

            if (node.Variables.Count != 1)
            {
                throw new ShaderGenerationException("Cannot declare multiple variables together.");
            }

            VariableDeclaratorSyntax vds = node.Variables[0];

            string             resourceName = vds.Identifier.Text;
            TypeInfo           typeInfo     = GetModel(node).GetTypeInfo(node.Type);
            string             fullTypeName = GetModel(node).GetFullTypeName(node.Type);
            TypeReference      tr           = new TypeReference(fullTypeName);
            ShaderResourceKind kind         = ClassifyResourceKind(fullTypeName);
            ResourceDefinition rd           = new ResourceDefinition(resourceName, resourceBinding, tr, kind);

            if (kind == ShaderResourceKind.Uniform)
            {
                ValidateResourceType(typeInfo);
            }

            foreach (LanguageBackend b in _backends)
            {
                b.AddResource(_shaderSet.Name, rd);
            }
        }
Example #3
0
        private static ResourceKind GetResourceKind(ShaderResourceKind resourceKind)
        {
            switch (resourceKind)
            {
            case ShaderResourceKind.Uniform:
                return(ResourceKind.UniformBuffer);

            case ShaderResourceKind.Texture2D:
            case ShaderResourceKind.Texture2DArray:
            case ShaderResourceKind.TextureCube:
            case ShaderResourceKind.Texture2DMS:
                return(ResourceKind.TextureReadOnly);

            case ShaderResourceKind.Sampler:
                return(ResourceKind.Sampler);

            case ShaderResourceKind.StructuredBuffer:
                return(ResourceKind.StructuredBufferReadOnly);

            case ShaderResourceKind.RWStructuredBuffer:
                return(ResourceKind.StructuredBufferReadWrite);

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Example #4
0
        public override void VisitVariableDeclaration(VariableDeclarationSyntax node)
        {
            if (node.Variables.Count != 1)
            {
                throw new ShaderGenerationException("Cannot declare multiple variables together.");
            }

            VariableDeclaratorSyntax vds = node.Variables[0];

            string             resourceName = vds.Identifier.Text;
            TypeInfo           typeInfo     = GetModel(node).GetTypeInfo(node.Type);
            string             fullTypeName = GetModel(node).GetFullTypeName(node.Type);
            TypeReference      valueType    = new TypeReference(fullTypeName, typeInfo);
            ShaderResourceKind kind         = ClassifyResourceKind(fullTypeName);

            if (kind == ShaderResourceKind.StructuredBuffer ||
                kind == ShaderResourceKind.RWStructuredBuffer ||
                kind == ShaderResourceKind.RWTexture2D)
            {
                valueType = ParseElementType(vds);
            }

            int set = 0; // Default value if not otherwise specified.

            if (GetResourceDecl(node, out AttributeSyntax resourceSetDecl))
            {
                set = GetAttributeArgumentIntValue(resourceSetDecl, 0, GetModel(node));
            }

            int resourceBinding = GetAndIncrementBinding(set);

            ResourceDefinition rd = new ResourceDefinition(resourceName, set, resourceBinding, valueType, kind);

            if (kind == ShaderResourceKind.Uniform)
            {
                ValidateResourceType(typeInfo);
            }

            foreach (LanguageBackend b in _backends)
            {
                b.AddResource(_shaderSet.Name, rd);
            }
        }
Example #5
0
        public override void VisitVariableDeclaration(VariableDeclarationSyntax node)
        {
            if (node.Variables.Count != 1)
            {
                throw new ShaderGenerationException("Cannot declare multiple variables together.");
            }

            VariableDeclaratorSyntax vds = node.Variables[0];

            string             resourceName = vds.Identifier.Text;
            TypeInfo           typeInfo     = GetModel(node).GetTypeInfo(node.Type);
            string             fullTypeName = GetModel(node).GetFullTypeName(node.Type);
            TypeReference      valueType    = new TypeReference(fullTypeName, typeInfo.Type);
            ShaderResourceKind kind         = ClassifyResourceKind(fullTypeName);

            var structure = _backends.Select(b => b.GetContext(_shaderSet.Name).Structures
                                             .FirstOrDefault(s => SymbolEqualityComparer.Default.Equals(s.Type, typeInfo.Type)))
                            .FirstOrDefault();

            if (structure != null && structure.Fields.Any(f => f.IsBuiltIn))
            {
                kind = ShaderResourceKind.BuiltIn;
            }

            ShaderBuiltin builtin = default;

            if (kind == ShaderResourceKind.Uniform)
            {
                if (node.Parent is FieldDeclarationSyntax field)
                {
                    if (field.Modifiers.Any(f => f.IsKind(SyntaxKind.PrivateKeyword)))
                    {
                        kind = ShaderResourceKind.Local;
                    }
                    else if (field.AttributeLists.Any(l => l.Attributes.Any(a => a.Name.ToString().Contains("Semantic"))))
                    {
                        kind = ShaderResourceKind.BuiltIn;
                        SemanticType semanticType = GetSemanticType(vds);
                        if (semanticType == SemanticType.None)
                        {
                            var geometrySemantic = GetGeometrySemantic(vds);
                            if (geometrySemantic != GeometrySemantic.None)
                            {
                                builtin = new ShaderBuiltin(geometrySemantic);
                            }
                        }
                        else
                        {
                            builtin = new ShaderBuiltin(semanticType);
                        }
                    }
                }
                else if (typeInfo.Type.GetAttributes().Any(a => a.AttributeClass.Name.Contains("Semantic")))
                {
                    kind = ShaderResourceKind.BuiltIn;
                }
            }

            if (kind == ShaderResourceKind.StructuredBuffer ||
                kind == ShaderResourceKind.RWStructuredBuffer ||
                kind == ShaderResourceKind.RWTexture2D ||
                valueType.Name.Contains(nameof(UniformBuffer <int>)))
            {
                valueType = ParseElementType(vds);
            }

            if (node.Parent is FieldDeclarationSyntax)
            {
                var arraySize = node.Parent.DescendantNodes().OfType <AttributeSyntax>().FirstOrDefault(
                    attrSyntax => attrSyntax.Name.ToString().EndsWith("ArraySize"));
                if (arraySize != null)
                {
                    var fixedSize = (int)GetModel(node).GetConstantValue(arraySize.ArgumentList.Arguments.First().Expression).Value;
                    valueType = new TypeReference(valueType.Name, valueType.TypeInfo, fixedSize);
                }

                var emitAttribute = node.Parent.DescendantNodes().OfType <AttributeSyntax>().FirstOrDefault(
                    attrSyntax => attrSyntax.Name.ToString().EndsWith("EmitVertex"));
                if (emitAttribute != null)
                {
                    kind = ShaderResourceKind.Emit;
                }
            }

            ResourceDefinition rd;

            if (kind == ShaderResourceKind.Local)
            {
                rd = new ResourceDefinition(resourceName, 0, 0, valueType, kind);
            }
            else
            {
                int set = 0; // Default value if not otherwise specified.
                if (GetResourceDecl(node, out AttributeSyntax resourceSetDecl))
                {
                    set = GetAttributeArgumentIntValue(resourceSetDecl, 0, GetModel(node));
                }

                int resourceBinding = GetAndIncrementBinding(set);

                if (kind == ShaderResourceKind.Uniform)
                {
                    ValidateUniformType(typeInfo);
                }
                rd = new ResourceDefinition(resourceName, set, resourceBinding, valueType, kind);
            }

            rd.Semantic = builtin.Semantic;

            foreach (LanguageBackend b in _backends)
            {
                b.AddResource(_shaderSet.Name, rd);
            }
        }
Example #6
0
        private static byte[] GetShaderBytecode(EngineDevice device, ResourceLink resourceLink, ShaderResourceKind resourceKind, string shaderModel)
        {
            switch (resourceKind)
            {
            case ShaderResourceKind.Bytecode:
                using (var inStream = resourceLink.OpenInputStream())
                {
                    return(inStream.ReadAllBytes());
                }

            case ShaderResourceKind.HlsFile:
                using (ReusableStringBuilders.Current.UseStringBuilder(out var singleShaderSourceBuilder, 10024))
                {
                    SingleShaderFileBuilder.ReadShaderFileAndResolveIncludes(
                        resourceLink,
                        singleShaderSourceBuilder);

                    // device.DebugEnabled ? D3DCompiler.ShaderFlags.Debug : D3DCompiler.ShaderFlags.None
                    var shaderSource  = singleShaderSourceBuilder.ToString();
                    var compileResult = Compiler.Compile(
                        shaderSource,
                        Array.Empty <D3D.ShaderMacro>(),
                        null !,
                        "main",
                        resourceLink.ToString() ?? "",
                        shaderModel,
                        device.DebugEnabled ? ShaderFlags.Debug : ShaderFlags.None,
                        out var compBlob, out var compErrorBlob);
                    try
                    {
                        if (compileResult.Failure)
                        {
                            throw new SeeingSharpGraphicsException($"Unable to compile shader from {resourceLink}: {compileResult.Code} - {compileResult.ToString()}");
                        }
                        return(compBlob.GetBytes());
                    }
                    finally
                    {
                        SeeingSharpUtil.SafeDispose(ref compBlob);
                        SeeingSharpUtil.SafeDispose(ref compErrorBlob);
                    }
                }

            default:
                throw new SeeingSharpException($"Unhandled {nameof(ShaderResourceKind)}: {resourceKind}");
            }
        }
Example #7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ShaderResource"/> class.
 /// </summary>
 /// <param name="shaderProfile">Shader profile used for compilation.</param>
 /// <param name="resourceLink">The source of the resource.</param>
 /// <param name="resourceKind">Kind of the shader resource.</param>
 protected ShaderResource(string shaderProfile, ResourceLink resourceLink, ShaderResourceKind resourceKind)
 {
     _resourceKind  = resourceKind;
     _shaderProfile = shaderProfile;
     _resourceLink  = resourceLink;
 }