示例#1
0
        ///// <summary>
        ///// Gets the corresponding interface slot for a variable that represents an interface pointer.
        ///// </summary>
        //public List<uint> InterfaceSlots { get; private set; }

        public static ShaderVariable Parse(BytecodeReader reader,
                                           BytecodeReader variableReader, ShaderVersion target,
                                           bool isFirst)
        {
            uint nameOffset = variableReader.ReadUInt32();
            var  nameReader = reader.CopyAtOffset((int)nameOffset);

            var  startOffset = variableReader.ReadUInt32();
            uint size        = variableReader.ReadUInt32();
            var  flags       = (ShaderVariableFlags)variableReader.ReadUInt32();

            var typeOffset = variableReader.ReadUInt32();
            var typeReader = reader.CopyAtOffset((int)typeOffset);
            var shaderType = ShaderType.Parse(reader, typeReader, target, 2, isFirst, startOffset);

            var           defaultValueOffset = variableReader.ReadUInt32();
            List <Number> defaultValue       = null;

            if (defaultValueOffset != 0)
            {
                defaultValue = new List <Number>();
                var defaultValueReader = reader.CopyAtOffset((int)defaultValueOffset);
                if (size % 4 != 0)
                {
                    throw new ParseException("Can only deal with 4-byte default values at the moment.");
                }
                for (int i = 0; i < size; i += 4)
                {
                    defaultValue.Add(new Number(defaultValueReader.ReadBytes(4)));
                }
            }

            var name   = nameReader.ReadString();
            var result = new ShaderVariable
            {
                DefaultValue = defaultValue,
                Member       = new ShaderTypeMember(0)
                {
                    Name   = name,
                    Offset = startOffset,
                    Type   = shaderType
                },
                BaseType = name,
                Size     = size,
                Flags    = flags
            };

            if (target.MajorVersion >= 5)
            {
                result.StartTexture = variableReader.ReadInt32();
                result.TextureSize  = variableReader.ReadInt32();
                result.StartSampler = variableReader.ReadInt32();
                result.SamplerSize  = variableReader.ReadInt32();
            }

            return(result);
        }
        public static ShaderTypeMember Parse(BytecodeReader reader, BytecodeReader memberReader, ShaderVersion target,
                                             int indent, bool isFirst, uint parentOffset)
        {
            var nameOffset = memberReader.ReadUInt32();
            var nameReader = reader.CopyAtOffset((int)nameOffset);
            var name       = nameReader.ReadString();

            var memberTypeOffset = memberReader.ReadUInt32();

            var offset = memberReader.ReadUInt32();

            var memberTypeReader = reader.CopyAtOffset((int)memberTypeOffset);
            var memberType       = ShaderType.Parse(reader, memberTypeReader, target, indent, isFirst, parentOffset + offset);

            return(new ShaderTypeMember(parentOffset)
            {
                Name = name,
                Type = memberType,
                Offset = offset
            });
        }
示例#3
0
        public static ShaderType Parse(BytecodeReader reader, BytecodeReader typeReader, ShaderVersion target,
                                       int indent, bool isFirst, uint parentOffset)
        {
            var result = new ShaderType(indent, isFirst)
            {
                VariableClass = (ShaderVariableClass)typeReader.ReadUInt16(),
                VariableType  = (ShaderVariableType)typeReader.ReadUInt16(),
                Rows          = typeReader.ReadUInt16(),
                Columns       = typeReader.ReadUInt16(),
                ElementCount  = typeReader.ReadUInt16()
            };

            var memberCount  = typeReader.ReadUInt16();
            var memberOffset = typeReader.ReadUInt32();

            if (target.MajorVersion >= 5)
            {
                var subTypeOffset = typeReader.ReadUInt32();                 // Guessing
                if (subTypeOffset != 0)
                {
                    var parentTypeReader = reader.CopyAtOffset((int)subTypeOffset);
                    result.SubType = ShaderType.Parse(reader, parentTypeReader, target,
                                                      indent + 4, true, parentOffset);
                    Debug.Assert(
                        result.SubType.VariableClass == ShaderVariableClass.Vector ||
                        result.SubType.VariableClass == ShaderVariableClass.InterfaceClass);
                }

                var baseClassOffset = typeReader.ReadUInt32();
                if (baseClassOffset != 0)
                {
                    var baseClassReader = reader.CopyAtOffset((int)baseClassOffset);
                    result.BaseClass = ShaderType.Parse(reader, baseClassReader, target,
                                                        indent + 4, true, parentOffset);
                    Debug.Assert(
                        result.BaseClass.VariableClass == ShaderVariableClass.Scalar ||
                        result.BaseClass.VariableClass == ShaderVariableClass.Struct);
                }

                var interfaceCount         = typeReader.ReadUInt32();
                var interfaceSectionOffset = typeReader.ReadUInt32();
                if (interfaceSectionOffset != 0)
                {
                    var interfaceSectionReader = reader.CopyAtOffset((int)interfaceSectionOffset);
                    for (int i = 0; i < interfaceCount; i++)
                    {
                        var interfaceTypeOffset = interfaceSectionReader.ReadUInt32();
                        var interfaceReader     = reader.CopyAtOffset((int)interfaceTypeOffset);
                        result.Interfaces.Add(ShaderType.Parse(reader, interfaceReader, target,
                                                               indent + 4, i == 0, parentOffset));
                    }
                }

                var parentNameOffset = typeReader.ReadUInt32();
                if (parentNameOffset > 0)
                {
                    var parentNameReader = reader.CopyAtOffset((int)parentNameOffset);
                    result.BaseTypeName = parentNameReader.ReadString();
                }
            }

            if (memberCount > 0)
            {
                var memberReader = reader.CopyAtOffset((int)memberOffset);
                for (int i = 0; i < memberCount; i++)
                {
                    result.Members.Add(ShaderTypeMember.Parse(reader, memberReader, target, indent + 4, i == 0,
                                                              parentOffset));
                }
            }

            if (target.ProgramType == ProgramType.LibraryShader && target.MajorVersion == 4)
            {
                var unk1           = typeReader.ReadUInt32();
                var unk2           = typeReader.ReadUInt32();
                var unk3           = typeReader.ReadUInt32();
                var unk4           = typeReader.ReadUInt32();
                var typeNameOffset = typeReader.ReadUInt32();
                var typeNameReader = reader.CopyAtOffset((int)typeNameOffset);
                typeNameReader.ReadString();
                Debug.Assert(unk1 == 0, $"ShaderType.Unk1={unk1}");
                Debug.Assert(unk2 == 0, $"ShaderType.Unk2={unk2}");
                Debug.Assert(unk3 == 0, $"ShaderType.Unk3={unk3}");
                Debug.Assert(unk4 == 0, $"ShaderType.Unk4={unk4}");
            }

            return(result);
        }