Exemple #1
0
 public StructureDefinition(ITypeSymbol type, FieldDefinition[] fields, AlignmentInfo?size = null)
 {
     Type      = type ?? throw new ArgumentNullException(nameof(type));
     Name      = type.GetFullMetadataName();
     Fields    = fields;
     Alignment = size ?? TypeSizeCache.Get(type);
     if (Alignment.CSharpSize == Alignment.ShaderSize)
     {
         CSharpMatchesShaderAlignment = true;
     }
     else
     {
         CSharpMatchesShaderAlignment = GetCSharpMatchesShaderAlignment();
     }
 }
        public static bool TryGetStructDefinition(SemanticModel model, StructDeclarationSyntax node, out StructureDefinition sd)
        {
            string fullNestedTypePrefix = Utilities.GetFullNestedTypePrefix(node, out bool nested);
            string structName           = node.Identifier.ToFullString().Trim();

            if (!string.IsNullOrEmpty(fullNestedTypePrefix))
            {
                string joiner = nested ? "+" : ".";
                structName = fullNestedTypePrefix + joiner + structName;
            }

            int structCSharpSize          = 0;
            int structShaderSize          = 0;
            int structCSharpAlignment     = 0;
            int structShaderAlignment     = 0;
            List <FieldDefinition> fields = new List <FieldDefinition>();

            foreach (MemberDeclarationSyntax member in node.Members)
            {
                if (member is FieldDeclarationSyntax fds && !fds.Modifiers.Any(x => x.IsKind(SyntaxKind.ConstKeyword)))
                {
                    VariableDeclarationSyntax varDecl = fds.Declaration;
                    foreach (VariableDeclaratorSyntax vds in varDecl.Variables)
                    {
                        string fieldName         = vds.Identifier.Text.Trim();
                        string typeName          = model.GetFullTypeName(varDecl.Type, out bool isArray);
                        int    arrayElementCount = 0;
                        if (isArray)
                        {
                            arrayElementCount = GetArrayCountValue(vds, model);
                        }

                        TypeInfo typeInfo = model.GetTypeInfo(varDecl.Type);

                        AlignmentInfo fieldSizeAndAlignment;

                        if (typeInfo.Type.Kind == SymbolKind.ArrayType)
                        {
                            ITypeSymbol   elementType             = ((IArrayTypeSymbol)typeInfo.Type).ElementType;
                            AlignmentInfo elementSizeAndAlignment = TypeSizeCache.Get(elementType);
                            fieldSizeAndAlignment = new AlignmentInfo(
                                elementSizeAndAlignment.CSharpSize * arrayElementCount,
                                elementSizeAndAlignment.ShaderSize * arrayElementCount,
                                elementSizeAndAlignment.CSharpAlignment,
                                elementSizeAndAlignment.ShaderAlignment);
                        }
                        else
                        {
                            fieldSizeAndAlignment = TypeSizeCache.Get(typeInfo.Type);
                        }

                        structCSharpSize     += structCSharpSize % fieldSizeAndAlignment.CSharpAlignment;
                        structCSharpSize     += fieldSizeAndAlignment.CSharpSize;
                        structCSharpAlignment = Math.Max(structCSharpAlignment, fieldSizeAndAlignment.CSharpAlignment);

                        structShaderSize     += structShaderSize % fieldSizeAndAlignment.ShaderAlignment;
                        structShaderSize     += fieldSizeAndAlignment.ShaderSize;
                        structShaderAlignment = Math.Max(structShaderAlignment, fieldSizeAndAlignment.ShaderAlignment);

                        TypeReference tr           = new TypeReference(typeName, model.GetTypeInfo(varDecl.Type).Type);
                        SemanticType  semanticType = GetSemanticType(vds);
                        fields.Add(new FieldDefinition(fieldName, tr, semanticType, arrayElementCount, fieldSizeAndAlignment));
                    }
                }
            }

            sd = new StructureDefinition(
                structName.Trim(),
                fields.ToArray(),
                new AlignmentInfo(structCSharpSize, structShaderSize, structCSharpAlignment, structShaderAlignment));
            return(true);
        }
Exemple #3
0
        public static bool TryGetStructDefinition(SemanticModel model, StructDeclarationSyntax node, out StructureDefinition sd)
        {
            //string fullNestedTypePrefix = Utilities.GetFullNestedTypePrefix(node, out bool nested);
            //string structName = node.Identifier.ToFullString().Trim();
            //if (!string.IsNullOrEmpty(fullNestedTypePrefix))
            //{
            //    string joiner = nested ? "+" : ".";
            //    structName = fullNestedTypePrefix + joiner + structName;
            //}

            int structCSharpSize          = 0;
            int structShaderSize          = 0;
            int structCSharpAlignment     = 0;
            int structShaderAlignment     = 0;
            List <FieldDefinition> fields = new List <FieldDefinition>();

            foreach (MemberDeclarationSyntax member in node.Members)
            {
                if (member is FieldDeclarationSyntax fds && !fds.Modifiers.Any(x => x.IsKind(SyntaxKind.ConstKeyword)))
                {
                    VariableDeclarationSyntax varDecl = fds.Declaration;
                    foreach (VariableDeclaratorSyntax vds in varDecl.Variables)
                    {
                        string fieldName         = vds.Identifier.Text.Trim();
                        string typeName          = model.GetFullTypeName(varDecl.Type, out bool isArray);
                        int    arrayElementCount = 0;
                        if (isArray)
                        {
                            arrayElementCount = GetArrayCountValue(vds, model);
                        }

                        TypeInfo typeInfo = model.GetTypeInfo(varDecl.Type);

                        AlignmentInfo fieldSizeAndAlignment;

                        int fixedSize = 1;
                        if (typeInfo.Type.Kind == SymbolKind.ArrayType)
                        {
                            var arraySize = fds.DescendantNodes().OfType <AttributeSyntax>().FirstOrDefault(
                                attrSyntax => attrSyntax.Name.ToString().EndsWith("ArraySize"));
                            fixedSize = (int)model.GetConstantValue(arraySize.ArgumentList.Arguments.First().Expression).Value;
                            ITypeSymbol   elementType             = ((IArrayTypeSymbol)typeInfo.Type).ElementType;
                            AlignmentInfo elementSizeAndAlignment = TypeSizeCache.Get(elementType);
                            fieldSizeAndAlignment = new AlignmentInfo(
                                elementSizeAndAlignment.CSharpSize * arrayElementCount,
                                elementSizeAndAlignment.ShaderSize * arrayElementCount,
                                elementSizeAndAlignment.CSharpAlignment,
                                elementSizeAndAlignment.ShaderAlignment);
                        }
                        else
                        {
                            fieldSizeAndAlignment = TypeSizeCache.Get(typeInfo.Type);
                        }

                        structCSharpSize     += structCSharpSize % fieldSizeAndAlignment.CSharpAlignment;
                        structCSharpSize     += fieldSizeAndAlignment.CSharpSize;
                        structCSharpAlignment = Math.Max(structCSharpAlignment, fieldSizeAndAlignment.CSharpAlignment);

                        structShaderSize     += structShaderSize % fieldSizeAndAlignment.ShaderAlignment;
                        structShaderSize     += fieldSizeAndAlignment.ShaderSize;
                        structShaderAlignment = Math.Max(structShaderAlignment, fieldSizeAndAlignment.ShaderAlignment);

                        TypeReference tr           = new TypeReference(typeName, model.GetTypeInfo(varDecl.Type).Type, fixedSize);
                        SemanticType  semanticType = GetSemanticType(vds);
                        if (semanticType == SemanticType.None)
                        {
                            var geometrySemantic = GetGeometrySemantic(vds);
                            if (geometrySemantic != GeometrySemantic.None)
                            {
                                fields.Add(new FieldDefinition(fieldName, tr, geometrySemantic, arrayElementCount, fieldSizeAndAlignment));
                                continue;
                            }
                        }

                        fields.Add(new FieldDefinition(fieldName, tr, semanticType, arrayElementCount, fieldSizeAndAlignment));
                    }
                }
            }

            var type = model.GetDeclaredSymbol(node);

            sd = new StructureDefinition(
                type,
                fields.ToArray(),
                new AlignmentInfo(structCSharpSize, structShaderSize, structCSharpAlignment, structShaderAlignment));
            return(true);
        }
        private FieldDefinition ReflectField(IFieldSymbol field)
        {
            int           fixedSize;
            AlignmentInfo fieldSizeAndAlignment;

            if (field.Type is IArrayTypeSymbol arrayType)
            {
                var elementSizeAndAlignment = TypeSizeCache.Get(arrayType.ElementType);
                var arraySizeAttribute      = field.GetAttributes().Single(a => a.AttributeClass.Name == nameof(ArraySizeAttribute));
                fixedSize             = (int)arraySizeAttribute.ConstructorArguments[0].Value;
                fieldSizeAndAlignment = new AlignmentInfo(
                    elementSizeAndAlignment.CSharpSize * fixedSize,
                    elementSizeAndAlignment.ShaderSize * fixedSize,
                    elementSizeAndAlignment.CSharpAlignment,
                    elementSizeAndAlignment.ShaderAlignment);
            }
            else
            {
                fixedSize             = 0;
                fieldSizeAndAlignment = TypeSizeCache.Get(field.Type);
            }

            SemanticType semantic          = SemanticType.None;
            var          semanticAttribute = field.GetAttributes().SingleOrDefault(a => a.AttributeClass.Name.Contains("Semantic"));

            if (semanticAttribute != null)
            {
                switch (semanticAttribute.AttributeClass.Name)
                {
                case nameof(PositionSemanticAttribute):
                    semantic = SemanticType.Position;
                    break;

                case nameof(SystemPositionSemanticAttribute):
                    semantic = SemanticType.SystemPosition;
                    break;

                case nameof(ColorSemanticAttribute):
                    semantic = SemanticType.Color;
                    break;

                case nameof(ColorTargetSemanticAttribute):
                    semantic = SemanticType.ColorTarget;
                    break;

                case nameof(NormalSemanticAttribute):
                    semantic = SemanticType.Normal;
                    break;

                case nameof(TangentSemanticAttribute):
                    semantic = SemanticType.Tangent;
                    break;

                case nameof(TextureCoordinateSemanticAttribute):
                    semantic = SemanticType.TextureCoordinate;
                    break;

                case nameof(GeometrySemanticAttribute):
                    var geometrySemantic = semanticAttribute.ConstructorArguments.First();
                    return(new FieldDefinition(field.Name,
                                               new TypeReference(field.Type.GetFullMetadataName(), field.Type, fixedSize),
                                               (GeometrySemantic)Enum.ToObject(typeof(GeometrySemantic), geometrySemantic.Value),
                                               fixedSize, fieldSizeAndAlignment));

                default:
                    throw new NotSupportedException();
                }
            }

            return(new FieldDefinition(field.Name,
                                       new TypeReference(field.Type.GetFullMetadataName(), field.Type, fixedSize),
                                       semantic, fixedSize, fieldSizeAndAlignment));
        }