public static ShaderProgramChunk Parse(BytecodeReader reader)
        {
            var program = new ShaderProgramChunk
            {
                Version = ShaderVersion.ParseShex(reader),

                // Length Token (LenTok)
                // Always follows VerTok
                // [31:00] Unsigned integer count of number of DWORDs in program code, including version and length tokens.
                // So the minimum value is 0x00000002 (if an empty program is ever valid).
                Length = reader.ReadUInt32()
            };

            while (!reader.EndOfBuffer)
            {
                // Opcode Format (OpcodeToken0)
                //
                // [10:00] D3D10_SB_OPCODE_TYPE
                // if( [10:00] == D3D10_SB_OPCODE_CUSTOMDATA )
                // {
                //    Token starts a custom-data block.  See "Custom-Data Block Format".
                // }
                // else // standard opcode token
                // {
                //    [23:11] Opcode-Specific Controls
                //    [30:24] Instruction length in DWORDs including the opcode token.
                //    [31]    0 normally. 1 if extended operand definition, meaning next DWORD
                //            contains extended opcode token.
                // }
                var opcodeHeaderReader = reader.CopyAtCurrentPosition();
                var opcodeToken0       = opcodeHeaderReader.ReadUInt32();
                var opcodeHeader       = new OpcodeHeader
                {
                    OpcodeType = opcodeToken0.DecodeValue <OpcodeType>(0, 10),
                    Length     = opcodeToken0.DecodeValue(24, 30),
                    IsExtended = (opcodeToken0.DecodeValue(31, 31) == 1)
                };

                OpcodeToken opcodeToken;
                if (opcodeHeader.OpcodeType == OpcodeType.CustomData)
                {
                    opcodeToken = CustomDataToken.Parse(reader, opcodeToken0);
                }
                else if (opcodeHeader.OpcodeType.IsDeclaration())
                {
                    opcodeToken = DeclarationToken.Parse(reader, opcodeHeader.OpcodeType);
                }
                else                 // Not custom data or declaration, so must be instruction.
                {
                    opcodeToken = InstructionToken.Parse(reader, opcodeHeader);
                }

                opcodeToken.Header = opcodeHeader;
                program.Tokens.Add(opcodeToken);
            }

            program.LinkControlFlowInstructions();

            return(program);
        }
        public static VariableBlob Parse(BytecodeReader reader, BytecodeReader dataReader)
        {
            var result = new VariableBlob();

            result.Index = dataReader.ReadUInt32();
            var blobSize     = dataReader.ReadUInt32();
            var paddedSize   = blobSize + (blobSize % 4 == 0 ? 0 : 4 - blobSize % 4);
            var shaderReader = dataReader.CopyAtCurrentPosition();
            var data         = dataReader.ReadBytes((int)paddedSize);

            if (!_IsShader(data))
            {
                if (blobSize == 0)
                {
                    result.Value = "";
                }
                else
                {
                    result.Value = Encoding.UTF8.GetString(data, 0, (int)(blobSize - 1));
                }
            }
            else
            {
                result.Shader = ShaderModel.Parse(shaderReader);
            }
            return(result);
        }
        public static RootSignatureChunk Parse(BytecodeReader reader, uint chunkSize)
        {
            var chunkReader = reader.CopyAtCurrentPosition();
            var result      = new RootSignatureChunk();

            result.Version = (RootSignatureVersion)chunkReader.ReadUInt32();
            var numParameters        = chunkReader.ReadUInt32();
            var parameterOffset      = chunkReader.ReadUInt32();
            var numberStaticSamplers = chunkReader.ReadUInt32();
            var staticSamplerOffset  = chunkReader.ReadUInt32();

            result.Flags = (RootSignatureFlags)chunkReader.ReadUInt32();
            var paramReader = reader.CopyAtOffset((int)parameterOffset);

            for (int i = 0; i < numParameters; i++)
            {
                result.RootParameters.Add(RootParameter.Parse(chunkReader, paramReader, result.Version));
            }
            var staticSamplerReader = reader.CopyAtOffset((int)staticSamplerOffset);

            for (int i = 0; i < numberStaticSamplers; i++)
            {
                result.StaticSamplers.Add(StaticSampler.Parse(staticSamplerReader));
            }
            return(result);
        }
        } = new byte[4];                                                                 // Array for GS Stream Out Index

        public static PipelineStateValidationChunk Parse(BytecodeReader reader, uint chunkSize)
        {
            var result = new PipelineStateValidationChunk();

            result.Reader = reader.CopyAtCurrentPosition();
            return(result);
        }
Exemple #5
0
        public static InterfacesChunk Parse(BytecodeReader reader, uint sizeInBytes)
        {
            var headerReader = reader.CopyAtCurrentPosition();

            var result = new InterfacesChunk();

            var classInstanceCount       = headerReader.ReadUInt32();
            var classTypeCount           = headerReader.ReadUInt32();
            var interfaceSlotRecordCount = headerReader.ReadUInt32();

            // Will be same as interfaceSlotRecordCount unless there are interface arrays.
            result.InterfaceSlotCount = headerReader.ReadUInt32();

            // Think this is offset to start of interface slot info, but we
            // don't need it because it is also contained in the InterfaceSlot class
            var typeIDsOffset = headerReader.ReadUInt32();

            var classTypeOffset      = headerReader.ReadUInt32();
            var availableClassReader = reader.CopyAtOffset((int)classTypeOffset);

            var interfaceSlotOffset = headerReader.ReadUInt32();
            var interfaceSlotReader = reader.CopyAtOffset((int)interfaceSlotOffset);

            var unknown1 = headerReader.ReadUInt32();

            Debug.Assert(unknown1.ToFourCcString() == "OSGN");
            var unknown2 = headerReader.ReadUInt16();

            Debug.Assert(unknown2 == 32);
            var unknown3 = headerReader.ReadUInt16();

            Debug.Assert(unknown3 == 16);

            for (uint i = 0; i < classTypeCount; i++)
            {
                var classType = ClassType.Parse(reader, availableClassReader);
                classType.ID = i;                 // Really??
                result.AvailableClassTypes.Add(classType);
            }

            for (uint i = 0; i < classInstanceCount; i++)
            {
                var classInstance = ClassInstance.Parse(reader, availableClassReader);
                result.AvailableClassInstances.Add(classInstance);
            }

            uint startSlot = 0;

            for (uint i = 0; i < interfaceSlotRecordCount; i++)
            {
                var interfaceSlot = InterfaceSlot.Parse(reader, interfaceSlotReader);
                interfaceSlot.StartSlot = startSlot;                 // Really??
                result.InterfaceSlots.Add(interfaceSlot);

                startSlot += interfaceSlot.SlotSpan;
            }

            return(result);
        }
Exemple #6
0
        public static BytecodeChunk Parse(BytecodeReader reader, uint chunkSize)
        {
            var result      = new CtabChunk();
            var chunkReader = reader.CopyAtCurrentPosition();

            result.ConstantTable = ConstantTable.Parse(chunkReader);
            return(result);
        }
        public static BytecodeChunk Parse(BytecodeReader reader, uint chunkSize, BytecodeContainer container)
        {
            var result      = new FxlcChunk();
            var chunkReader = reader.CopyAtCurrentPosition();

            result.Fxlc = FxlcBlock.Parse(chunkReader);
            return(result);
        }
        public static LibfChunk Parse(BytecodeReader reader, uint chunkSize)
        {
            var result      = new LibfChunk();
            var chunkReader = reader.CopyAtCurrentPosition();
            var data        = chunkReader.ReadBytes((int)chunkSize);

            result.LibraryContainer = new BytecodeContainer(data);
            return(result);
        }
Exemple #9
0
        public static InputOutputSignatureChunk Parse(BytecodeReader reader, ChunkType chunkType,
                                                      ProgramType programType)
        {
            InputOutputSignatureChunk result;

            switch (chunkType)
            {
            case ChunkType.Isgn:
                result = new InputSignatureChunk();
                break;

            case ChunkType.Osgn:
            case ChunkType.Osg5:
                result = new OutputSignatureChunk();
                break;

            case ChunkType.Pcsg:
                result = new PatchConstantSignatureChunk();
                break;

            default:
                throw new ArgumentOutOfRangeException("chunkType", "Unrecognised chunk type: " + chunkType);
            }

            var chunkReader  = reader.CopyAtCurrentPosition();
            var elementCount = chunkReader.ReadUInt32();
            var uniqueKey    = chunkReader.ReadUInt32();

            SignatureElementSize elementSize;

            switch (chunkType)
            {
            case ChunkType.Osg5:
                elementSize = SignatureElementSize._7;
                break;

            case ChunkType.Isgn:
            case ChunkType.Osgn:
            case ChunkType.Pcsg:
                elementSize = SignatureElementSize._6;
                break;

            default:
                throw new ArgumentOutOfRangeException("chunkType", "Unrecognised chunk type: " + chunkType);
            }

            for (int i = 0; i < elementCount; i++)
            {
                result.Parameters.Add(SignatureParameterDescription.Parse(reader, chunkReader, chunkType, elementSize,
                                                                          programType));
            }

            return(result);
        }
Exemple #10
0
        public static BytecodeChunk Parse(BytecodeReader reader, uint chunkSize)
        {
            var result      = new Cli4Chunk();
            var chunkReader = reader.CopyAtCurrentPosition();
            var count       = chunkReader.ReadUInt32();

            for (int i = 0; i < count; i++)
            {
                result.Numbers.Add(Number.Parse(chunkReader));
            }
            return(result);
        }
        public static LibraryParameterSignatureChunk Parse(BytecodeReader reader, uint chunkSize)
        {
            var result         = new LibraryParameterSignatureChunk();
            var chunkReader    = reader.CopyAtCurrentPosition();
            var parameterCount = chunkReader.ReadUInt32();
            var paramterOffset = chunkReader.ReadUInt32();

            for (int i = 0; i < parameterCount; i++)
            {
                var parameterReader = chunkReader.CopyAtOffset((int)paramterOffset + 12 * 4 * i);
                result.Parameters.Add(LibraryParameterDescription.Parse(reader, parameterReader));
            }
            return(result);
        }
Exemple #12
0
        protected void ParseInstance(BytecodeReader reader, uint chunkSize)
        {
            Version = ShaderVersion.ParseShex(reader);
            var sizeInUint32 = reader.ReadUInt32();
            var dxilMagic    = reader.ReadUInt32();

            DxilVersion = reader.ReadUInt32();
            var bitcodeOffset = reader.ReadUInt32();

            Debug.Assert(bitcodeOffset == 16, "Unexpected bitcode offset found");
            var bitcodeLength = reader.ReadInt32();
            var bitcodeReader = reader.CopyAtCurrentPosition();

            Bitcode = bitcodeReader.ReadBytes(bitcodeLength);
        }
Exemple #13
0
        public static EffectChunk Parse(BytecodeReader reader, uint size)
        {
            var headerReader = reader.CopyAtCurrentPosition();
            var result       = new EffectChunk();
            var header       = result.Header = EffectHeader.Parse(headerReader);
            var bodyOffset   = header.Version.MajorVersion < 5 ?
                               0x4C : 0x60;
            var footerOffset = (int)(result.Header.FooterOffset + bodyOffset);
            var bodyReader   = reader.CopyAtOffset((int)bodyOffset);
            var footerReader = reader.CopyAtOffset(footerOffset);
            var version      = header.Version;

            for (int i = 0; i < header.ConstantBuffers; i++)
            {
                result.LocalBuffers.Add(EffectBuffer.Parse(bodyReader, footerReader, version, false));
            }
            for (int i = 0; i < header.ObjectCount; i++)
            {
                result.LocalVariables.Add(EffectObjectVariable.Parse(bodyReader, footerReader, version, false));
            }
            for (int i = 0; i < header.SharedConstantBuffers; i++)
            {
                result.SharedBuffers.Add(EffectBuffer.Parse(bodyReader, footerReader, version, true));
            }
            for (int i = 0; i < header.SharedObjectCount; i++)
            {
                result.SharedVariables.Add(EffectObjectVariable.Parse(bodyReader, footerReader, version, true));
            }
            if (header.Version.MajorVersion >= 5)
            {
                for (int i = 0; i < header.InterfaceVariableCount; i++)
                {
                    result.InterfaceVariables.Add(EffectInterfaceVariable.Parse(bodyReader, footerReader, version));
                }
                for (int i = 0; i < header.GroupCount; i++)
                {
                    result.Groups.Add(EffectGroup.Parse(bodyReader, footerReader, header.Version));
                }
            }
            else
            {
                for (int i = 0; i < header.Techniques; i++)
                {
                    result.Techniques.Add(EffectTechnique.Parse(bodyReader, footerReader, header.Version));
                }
            }
            return(result);
        }
Exemple #14
0
        public static InterfacesChunk Parse(BytecodeReader reader, uint sizeInBytes)
        {
            var headerReader = reader.CopyAtCurrentPosition();

            var result = new InterfacesChunk();

            var classInstanceCount       = headerReader.ReadUInt32();
            var classTypeCount           = headerReader.ReadUInt32();
            var interfaceSlotRecordCount = headerReader.ReadUInt32();

            // Will be same as interfaceSlotRecordCount unless there are interface arrays.
            result.InterfaceSlotCount = headerReader.ReadUInt32();

            headerReader.ReadUInt32();             // Think this is offset to start of interface slot info, but we don't need it.

            var classTypeOffset      = headerReader.ReadUInt32();
            var availableClassReader = reader.CopyAtOffset((int)classTypeOffset);

            var interfaceSlotOffset = headerReader.ReadUInt32();
            var interfaceSlotReader = reader.CopyAtOffset((int)interfaceSlotOffset);

            for (uint i = 0; i < classTypeCount; i++)
            {
                var classType = ClassType.Parse(reader, availableClassReader);
                classType.ID = i;                 // Really??
                result.AvailableClassTypes.Add(classType);
            }

            for (uint i = 0; i < classInstanceCount; i++)
            {
                var classInstance = ClassInstance.Parse(reader, availableClassReader);
                result.AvailableClassInstances.Add(classInstance);
            }

            uint startSlot = 0;

            for (uint i = 0; i < interfaceSlotRecordCount; i++)
            {
                var interfaceSlot = InterfaceSlot.Parse(reader, interfaceSlotReader);
                interfaceSlot.StartSlot = startSlot;                 // Really??
                result.InterfaceSlots.Add(interfaceSlot);

                startSlot += interfaceSlot.SlotSpan;
            }

            return(result);
        }
Exemple #15
0
        public static StateBlob Parse(BytecodeReader reader, BytecodeReader shaderReader)
        {
            var result = new StateBlob();

            result.TechniqueIndex    = shaderReader.ReadUInt32();
            result.PassIndex         = shaderReader.ReadUInt32();
            result.SamplerStateIndex = shaderReader.ReadUInt32();
            result.AssignmentIndex   = shaderReader.ReadUInt32();
            result.BlobType          = (StateBlobType)shaderReader.ReadUInt32();
            var dataReader = shaderReader.CopyAtCurrentPosition();
            var blobSize   = shaderReader.ReadUInt32();
            var paddedSize = blobSize + (blobSize % 4 == 0 ? 0 : 4 - blobSize % 4);
            //Seak ahead
            var data = shaderReader.ReadBytes((int)paddedSize);

            if (result.BlobType == StateBlobType.Shader)
            {
                result.Shader = ShaderReader.ReadShader(data);
            }
            else if (result.BlobType == StateBlobType.Variable)
            {
                result.VariableName = dataReader.TryReadString();
            }
            else if (result.BlobType == StateBlobType.IndexShader)
            {
                var _blobSize    = dataReader.ReadUInt32();
                var variableSize = dataReader.ReadUInt32();
                result.VariableName = dataReader.ReadString();
                if (variableSize > (result.VariableName.Length + 1))
                {
                    var paddingCount = variableSize - (result.VariableName.Length + 1);
                    var padding      = dataReader.ReadBytes((int)paddingCount);
                }
                result.Shader = result.Shader = ShaderModel.Parse(dataReader);
            }
            return(result);
        }
        public static LibHeaderChunk Parse(BytecodeReader reader, uint chunkSize)
        {
            var chunkReader = reader.CopyAtCurrentPosition();
            var result      = new LibHeaderChunk();

            //multiple creator strings?
            var unknown1 = chunkReader.ReadUInt32();

            Debug.Assert(unknown1 == 1, $"LibraryHeader.unknown1 is {unknown1}");
            var creatorStringOffset = chunkReader.ReadUInt32();
            //guessing flags, library chunk never seems to flags set.
            var unknown0 = chunkReader.ReadUInt32();

            Debug.Assert(unknown0 == 0, "Unexpected value for LibHeaderChunk.Unknown0");
            var functionCount = chunkReader.ReadUInt32();
            //Contains function strings and function flags
            var functionInfoOffset = chunkReader.ReadUInt32();

            var creatorStringReader = chunkReader.CopyAtOffset((int)creatorStringOffset);

            result.CreatorString = creatorStringReader.ReadString();
            var functionInfoReader = reader.CopyAtOffset((int)functionInfoOffset);

            for (int i = 0; i < functionCount; i++)
            {
                // is 0 for lib_4_0, lib_4_1, lib_5_0
                // is 1 for lib_4_0_level_9_1_vs_only, lib_4_0_level_9_3_vs_only
                // is 2 for lib_4_0_level_9_1_ps_only, lib_4_0_level_9_3_ps_only
                // is 3 for lib_4_0_level_9_1, lib_4_0_level_9_3
                var mode = (ProfileMode)functionInfoReader.ReadUInt32();
                var functionNameOffset = functionInfoReader.ReadUInt32();
                var functionNameReader = reader.CopyAtOffset((int)functionNameOffset);
                var name = functionNameReader.ReadString();
                result.FunctionDescs.Add(new LibraryDesc(name, mode));
            }
            return(result);
        }
        public static EffectContainer Parse(BytecodeReader reader, uint length)
        {
            var result         = new EffectContainer();
            var chunkReader    = reader.CopyAtCurrentPosition();
            var footerOffset   = chunkReader.ReadUInt32() + 4;
            var bodyReader     = chunkReader.CopyAtCurrentPosition();
            var footerReader   = reader.CopyAtOffset((int)footerOffset);
            var variableCount  = footerReader.ReadUInt32();
            var techniqueCount = footerReader.ReadUInt32();
            var passCount      = footerReader.ReadUInt32();
            var shaderCount    = footerReader.ReadUInt32();

            for (int i = 0; i < variableCount; i++)
            {
                result.Variables.Add(Variable.Parse(bodyReader, footerReader));
            }
            for (int i = 0; i < techniqueCount; i++)
            {
                result.Techniques.Add(Technique.Parse(bodyReader, footerReader));
            }
            var variableBlobCount = footerReader.ReadUInt32();
            var stateBlobCount    = footerReader.ReadUInt32();

            for (int i = 0; i < variableBlobCount; i++)
            {
                var data = VariableBlob.Parse(bodyReader, footerReader);
                result.VariableBlobs.Add(data);
            }
            for (int i = 0; i < stateBlobCount; i++)
            {
                var data = StateBlob.Parse(bodyReader, footerReader);
                result.StateBlobs.Add(data);
            }
            result.BuildBlobLookup();
            return(result);
        }
        public static ResourceDefinitionChunk Parse(BytecodeReader reader)
        {
            var headerReader = reader.CopyAtCurrentPosition();

            uint constantBufferCount   = headerReader.ReadUInt32();
            uint constantBufferOffset  = headerReader.ReadUInt32();
            uint resourceBindingCount  = headerReader.ReadUInt32();
            uint resourceBindingOffset = headerReader.ReadUInt32();
            var  target = ShaderVersion.ParseRdef(headerReader);
            uint flags  = headerReader.ReadUInt32();

            var creatorOffset = headerReader.ReadUInt32();
            var creatorReader = reader.CopyAtOffset((int)creatorOffset);
            var creator       = creatorReader.ReadString();

            var result = new ResourceDefinitionChunk
            {
                Target  = target,
                Flags   = (ShaderFlags)flags,
                Creator = creator
            };

            if (target.MajorVersion >= 5)
            {
                string rd11 = headerReader.ReadUInt32().ToFourCcString();
                if (rd11 != "RD11")
                {
                    throw new ParseException("Expected RD11.");
                }

                var unknown1 = headerReader.ReadUInt32();                 // TODO
                Debug.Assert(unknown1 == 60);

                var unknown2 = headerReader.ReadUInt32();
                Debug.Assert(unknown2 == 24);

                var unknown3 = headerReader.ReadUInt32();
                Debug.Assert(unknown3 == 32);

                var unknown4 = headerReader.ReadUInt32();
                Debug.Assert(unknown4 == 40);

                var unknown5 = headerReader.ReadUInt32();
                Debug.Assert(unknown5 == 36);

                var unknown6 = headerReader.ReadUInt32();
                Debug.Assert(unknown6 == 12);

                result.InterfaceSlotCount = headerReader.ReadUInt32();
            }

            var constantBufferReader = reader.CopyAtOffset((int)constantBufferOffset);

            for (int i = 0; i < constantBufferCount; i++)
            {
                result.ConstantBuffers.Add(ConstantBuffer.Parse(reader, constantBufferReader, result.Target));
            }

            var resourceBindingReader = reader.CopyAtOffset((int)resourceBindingOffset);

            for (int i = 0; i < resourceBindingCount; i++)
            {
                result.ResourceBindings.Add(ResourceBinding.Parse(reader, resourceBindingReader));
            }

            return(result);
        }
        Token ReadInstruction(BytecodeReader reader)
        {
            uint   instructionToken = reader.ReadUInt32();
            Opcode opcode           = (Opcode)(instructionToken & 0xffff);
            int    size;

            if (opcode == Opcode.Comment)
            {
                size = (int)((instructionToken >> 16) & 0x7FFF);
            }
            else
            {
                size = (int)((instructionToken >> 24) & 0x0f);
            }
            Token token = null;

            if (opcode == Opcode.Comment)
            {
                var fourCC = reader.ReadUInt32();
                if (KnownCommentTypes.ContainsKey(fourCC))
                {
                    var commentReader = reader.CopyAtCurrentPosition();
                    reader.ReadBytes(size * 4 - 4);
                    switch (KnownCommentTypes[fourCC])
                    {
                    case CommentType.CTAB:
                        ConstantTable = ConstantTable.Parse(commentReader);
                        return(null);

                    case CommentType.C**T:
                        Cli = CliToken.Parse(commentReader);
                        return(null);

                    case CommentType.FXLC:
                        Fxlc = FxlcBlock.Parse(commentReader);
                        return(null);

                    case CommentType.PRES:
                        Preshader = Preshader.Parse(commentReader);
                        return(null);

                    case CommentType.PRSI:
                        Prsi = PrsiToken.Parse(commentReader);
                        return(null);
                    }
                }
                token         = new CommentToken(opcode, size, this);
                token.Data[0] = fourCC;
                for (int i = 1; i < size; i++)
                {
                    token.Data[i] = reader.ReadUInt32();
                }
            }
            else
            {
                token = new InstructionToken(opcode, size, this);
                var inst = token as InstructionToken;

                for (int i = 0; i < size; i++)
                {
                    token.Data[i] = reader.ReadUInt32();
                    if (opcode == Opcode.Def || opcode == Opcode.DefB || opcode == Opcode.DefI)
                    {
                        if (i == 0)
                        {
                            inst.Operands.Add(new DestinationOperand(token.Data[i]));
                        }
                    }
                    else if (opcode == Opcode.Dcl)
                    {
                        if (i == 0)
                        {
                            inst.Operands.Add(new DeclarationOperand(token.Data[i]));
                        }
                        else
                        {
                            inst.Operands.Add(new DestinationOperand(token.Data[i]));
                        }
                    }
                    else if (i == 0 && opcode.HasDestination())
                    {
                        if ((token.Data[i] & (1 << 13)) != 0)
                        {
                            //Relative Address mode
                            token.Data[i + 1] = reader.ReadUInt32();
                            inst.Operands.Add(new DestinationOperand(token.Data[i], token.Data[i + 1]));
                            i++;
                        }
                        else
                        {
                            inst.Operands.Add(new DestinationOperand(token.Data[i]));
                        }
                    }
                    else if ((token.Data[i] & (1 << 13)) != 0)
                    {
                        //Relative Address mode
                        token.Data[i + 1] = reader.ReadUInt32();
                        inst.Operands.Add(new SourceOperand(token.Data[i], token.Data[i + 1]));
                        i++;
                    }
                    else
                    {
                        inst.Operands.Add(new SourceOperand(token.Data[i]));
                    }
                }
                if (opcode != Opcode.Comment)
                {
                    token.Modifier   = (int)((instructionToken >> 16) & 0xff);
                    token.Predicated = (instructionToken & 0x10000000) != 0;
                    token.CoIssue    = (instructionToken & 0x40000000) != 0;
                    Debug.Assert((instructionToken & 0xA0000000) == 0, $"Instruction has unexpected bits set {instructionToken & 0xE0000000}");
                }
            }
            return(token);
        }
        public static BytecodeChunk ParseChunk(BytecodeReader chunkReader, BytecodeContainer container)
        {
            // Type of chunk this is.
            uint fourCc = chunkReader.ReadUInt32();

            // Total length of the chunk in bytes.
            uint chunkSize = chunkReader.ReadUInt32();

            ChunkType chunkType;

            if (KnownChunkTypes.ContainsKey(fourCc))
            {
                chunkType = KnownChunkTypes[fourCc];
            }
            else
            {
                System.Diagnostics.Debug.Assert(false, "Chunk type '" + fourCc.ToFourCcString() + "' is not yet supported.");
                System.Diagnostics.Debug.WriteLine("Chunk type '" + fourCc.ToFourCcString() + "' is not yet supported.");
                return(null);
            }

            var           chunkContentReader = chunkReader.CopyAtCurrentPosition((int)chunkSize);
            BytecodeChunk chunk;

            switch (chunkType)
            {
            case ChunkType.Ifce:
                chunk = InterfacesChunk.Parse(chunkContentReader, chunkSize);
                break;

            case ChunkType.Isgn:
            case ChunkType.Osgn:
            case ChunkType.Osg5:
            case ChunkType.Pcsg:
            case ChunkType.Isg1:
            case ChunkType.Osg1:
                chunk = InputOutputSignatureChunk.Parse(chunkContentReader, chunkType,
                                                        container.Version.ProgramType);
                break;

            case ChunkType.Rdef:
                chunk = ResourceDefinitionChunk.Parse(chunkContentReader);
                break;

            case ChunkType.Sdbg:
            case ChunkType.Spdb:
                chunk = DebuggingChunk.Parse(chunkContentReader, chunkType, chunkSize);
                break;

            case ChunkType.Sfi0:
                chunk = Sfi0Chunk.Parse(chunkContentReader, container.Version, chunkSize);
                break;

            case ChunkType.Shdr:
            case ChunkType.Shex:
                chunk = ShaderProgramChunk.Parse(chunkContentReader);
                break;

            case ChunkType.Stat:
                chunk = StatisticsChunk.Parse(chunkContentReader, chunkSize);
                break;

            case ChunkType.Xnas:
            case ChunkType.Xnap:
            case ChunkType.Aon9:
                chunk = Level9ShaderChunk.Parse(chunkContentReader, chunkSize);
                break;

            case ChunkType.Priv:
                chunk = PrivateChunk.Parse(chunkContentReader, chunkSize);
                break;

            case ChunkType.Rts0:
                chunk = RootSignatureChunk.Parse(chunkContentReader, chunkSize);
                break;

            case ChunkType.Libf:
                chunk = LibfChunk.Parse(chunkContentReader, chunkSize);
                break;

            case ChunkType.Libh:
                chunk = LibHeaderChunk.Parse(chunkContentReader, chunkSize);
                break;

            case ChunkType.Lfs0:
                chunk = LibraryParameterSignatureChunk.Parse(chunkContentReader, chunkSize);
                break;

            default:
                throw new ParseException("Invalid chunk type: " + chunkType);
            }

            chunk.Container = container;
            chunk.FourCc    = fourCc;
            chunk.ChunkSize = chunkSize;
            chunk.ChunkType = chunkType;

            return(chunk);
        }
Exemple #21
0
        public static ResourceDefinitionChunk Parse(BytecodeReader reader)
        {
            var headerReader = reader.CopyAtCurrentPosition();

            uint constantBufferCount   = headerReader.ReadUInt32();
            uint constantBufferOffset  = headerReader.ReadUInt32();
            uint resourceBindingCount  = headerReader.ReadUInt32();
            uint resourceBindingOffset = headerReader.ReadUInt32();
            var  target = ShaderVersion.ParseRdef(headerReader);
            uint flags  = headerReader.ReadUInt32();

            var creatorOffset = headerReader.ReadUInt32();
            var creatorReader = reader.CopyAtOffset((int)creatorOffset);
            var creator       = creatorReader.ReadString();

            var result = new ResourceDefinitionChunk
            {
                Target  = target,
                Flags   = (ShaderFlags)flags,
                Creator = creator
            };

            if (target.MajorVersion == 5 || target.ProgramType == ProgramType.LibraryShader)
            {
                if (target.MinorVersion == 0)
                {
                    string rd11 = headerReader.ReadUInt32().ToFourCcString();
                    if (rd11 != "RD11")
                    {
                        throw new ParseException("Expected RD11.");
                    }
                }
                else
                {
                    var unknown0 = headerReader.ReadUInt32();
                    Debug.Assert(unknown0 == 625218323);
                }

                var unknown1 = headerReader.ReadUInt32();                 // TODO
                Debug.Assert(unknown1 == 60);

                var constantBufferStride = headerReader.ReadUInt32();
                Debug.Assert(constantBufferStride == 24);

                var resourceBindingStride = headerReader.ReadUInt32();
                Debug.Assert(resourceBindingStride == (target.MinorVersion == 0 ? 32 : 40));

                //Shader Variable Stride?
                var unknown4 = headerReader.ReadUInt32();
                Debug.Assert(unknown4 == 40);

                var unknown5 = headerReader.ReadUInt32();
                Debug.Assert(unknown5 == 36);

                //Shader Type Member Stride?
                var unknown6 = headerReader.ReadUInt32();
                Debug.Assert(unknown6 == 12);

                result.InterfaceSlotCount = headerReader.ReadUInt32();
            }

            var constantBufferReader = reader.CopyAtOffset((int)constantBufferOffset);

            for (int i = 0; i < constantBufferCount; i++)
            {
                result.ConstantBuffers.Add(ConstantBuffer.Parse(reader, constantBufferReader, result.Target));
            }

            var resourceBindingReader = reader.CopyAtOffset((int)resourceBindingOffset);

            for (int i = 0; i < resourceBindingCount; i++)
            {
                result.ResourceBindings.Add(ResourceBinding.Parse(reader, resourceBindingReader, target));
            }

            return(result);
        }