public DebugBytecodeContainer(DebugBytecodeReader reader)
        {
            try
            {
                Chunks = new List <DebugBytecodeChunk>();

                _reader = reader;
                var magicNumber = reader.PeakUint32();
                if (magicNumber == 0xFEFF2001)
                {
                    Chunks.Add(DebugEffectChunk.Parse(reader, (uint)reader.Count));
                    return;
                }
                Header = DebugBytecodeContainerHeader.Parse(reader);

                for (uint i = 0; i < Header.ChunkCount; i++)
                {
                    uint chunkOffset = reader.ReadUInt32("chunkOffset");
                    var  fourCC      = DebugUtil.ToReadable(reader.PeakUInt32At((int)chunkOffset).ToFourCcString());
                    var  chunkReader = reader.CopyAtOffset($"Chunk{fourCC}", reader, (int)chunkOffset);

                    var chunk = DebugBytecodeChunk.ParseChunk(chunkReader, this);
                    if (chunk != null)
                    {
                        Chunks.Add(chunk);
                    }
                }
            }
            catch (Exception ex)
            {
                Exception = ex;
                Error     = ex.ToString();
            }
        }
示例#2
0
        public void DumpStructure(string relPath)
        {
            string file = $"{ShaderDirectory}/{relPath}";
            // Arrange.
            // Act.
            var bytecode = File.ReadAllBytes(file + ".o");

            var    reader = new DebugParser.DebugBytecodeReader(bytecode, 0, bytecode.Length);
            string error  = "";

            try
            {
                if (bytecode[2] == 255 && bytecode[3] == 254)
                {
                    reader.ReadByte("minorVersion");
                    reader.ReadByte("majorVersion");
                    reader.ReadUInt16("shaderType");
                    DebugEffectChunk.Parse(reader, (uint)(bytecode.Length - 4));
                }
                else
                {
                    var shaderModel = DebugShaderModel.Parse(reader);
                }
            }
            catch (Exception ex)
            {
                error = ex.ToString();
            }
            var dump = reader.DumpStructure();

            if (!string.IsNullOrEmpty(error))
            {
                dump += "\n" + error;
            }
            File.WriteAllText($"{file}.d.txt", dump);
            var dumpHtml = "";

            try
            {
                dumpHtml = reader.DumpHtml();
            }
            catch (Exception ex)
            {
            }
            File.WriteAllText($"{file}.d.html", dumpHtml);
            if (!string.IsNullOrEmpty(error))
            {
                Assert.That(false, error);
            }
            //Assert.That(!dump.Contains("Unread Memory"), "Unread memory found");

            // Assert.
        }
        public DebugBytecodeContainer(byte[] rawBytes)
        {
            try
            {
                _rawBytes = rawBytes;
                var reader = new DebugBytecodeReader(rawBytes, 0, rawBytes.Length);

                Chunks = new List <DebugBytecodeChunk>();

                _reader = reader;
                var magicNumber = reader.PeekUint32();
                if (magicNumber == 0xFEFF2001)
                {
                    Chunks.Add(DebugEffectChunk.Parse(reader, (uint)rawBytes.Length));
                    return;
                }

                Header = DebugBytecodeContainerHeader.Parse(reader);

                for (uint i = 0; i < Header.ChunkCount; i++)
                {
                    uint chunkOffset = reader.ReadUInt32("chunkOffset");
                    var  fourCC      = DebugUtil.ToReadable(reader.PeekUInt32At((int)chunkOffset).ToFourCcString());
                    var  chunkReader = reader.CopyAtOffset($"Chunk{fourCC}", reader, (int)chunkOffset);

                    var chunk = DebugBytecodeChunk.ParseChunk(chunkReader, this);
                    if (chunk != null)
                    {
                        Chunks.Add(chunk);
                    }
                }
                foreach (var chunk in Chunks.OfType <DebugPipelineStateValidationChunk>())
                {
                    chunk.UpdateVersion(Chunks.OfType <DebugDxilChunk>().First().Version);
                }
            }
            catch (Exception ex)
            {
                Exception = ex;
                Error     = ex.ToString();
            }
        }
示例#4
0
        static void Main(string[] args)
        {
            args = new string[]
            {
                "-O",
                "test.html",
                "-h",
                @"C:\Files\KM\ShaderStudio\src\UnityTests\bin\Debug\Blob\outer_wilds\Assets\Shader\SpritesDefault\VS_BF58DDF502C51FEB5145F1D0310B4327.o"
            };
            var options = new Options();

            for (int i = 0; i < args.Length; i++)
            {
                switch (args[i])
                {
                case "-O":
                    if (args.Length <= i + 1)
                    {
                        Console.Error.WriteLine("No output path specified");
                        return;
                    }
                    options.DestPath = args[i + 1];
                    i += 1;
                    break;

                case "-a":
                    options.Mode = DecompileMode.Dissassemble;
                    break;

                case "-d":
                    options.Mode = DecompileMode.Debug;
                    break;

                case "-h":
                    options.Mode = DecompileMode.DebugHtml;
                    break;

                default:
                    options.SourcePath = args[i];
                    break;
                }
            }
            if (string.IsNullOrEmpty(options.SourcePath))
            {
                Console.Error.WriteLine("No source path specified");
                Environment.Exit(1);
            }

            byte[] data = null;
            try
            {
                data = File.ReadAllBytes(options.SourcePath);
            } catch (Exception ex) {
                Console.Error.WriteLine("Error reading source");
                Console.Error.WriteLine(ex);
                Environment.Exit(1);
            }
            var programType = GetProgramType(data);

            using (var sw = GetStream(options))
            {
                if (programType == ProgramType.Unknown)
                {
                    Console.Error.WriteLine($"Unable to identify shader object format");
                    Environment.Exit(1);
                }
                else if (programType == ProgramType.DXBC)
                {
                    if (options.Mode == DecompileMode.Dissassemble)
                    {
                        var container = new BytecodeContainer(data);
                        sw.Write(container.ToString());
                    }
                    else if (options.Mode == DecompileMode.Decompile)
                    {
                        var hlsl = DXDecompiler.Decompile(data);
                        sw.Write(hlsl);
                    }
                    else if (options.Mode == DecompileMode.Debug)
                    {
                        sw.WriteLine(string.Join(" ", args));
                        var shaderBytecode = DebugBytecodeContainer.Parse(data);
                        var result         = shaderBytecode.Dump();
                        sw.Write(result);
                    }
                    else if (options.Mode == DecompileMode.DebugHtml)
                    {
                        var shaderBytecode = DebugBytecodeContainer.Parse(data);
                        var result         = shaderBytecode.DumpHTML();
                        sw.Write(result);
                    }
                }
                else if (programType == ProgramType.DX9)
                {
                    if (options.Mode == DecompileMode.Dissassemble)
                    {
                        var disasm = SlimShader.DX9Shader.AsmWriter.Disassemble(data);
                        sw.Write(disasm);
                    }
                    else if (options.Mode == DecompileMode.Decompile)
                    {
                        var hlsl = SlimShader.DX9Shader.HlslWriter.Decompile(data);
                        sw.Write(hlsl);
                    }
                    else if (options.Mode == DecompileMode.Debug)
                    {
                        sw.WriteLine(string.Join(" ", args));
                        var shaderType = (SlimShader.DX9Shader.ShaderType)BitConverter.ToUInt16(data, 2);
                        if (shaderType == SlimShader.DX9Shader.ShaderType.Effect)
                        {
                            var    reader = new DebugBytecodeReader(data, 0, data.Length);
                            string error  = "";
                            try
                            {
                                reader.ReadByte("minorVersion");
                                reader.ReadByte("majorVersion");
                                reader.ReadUInt16("shaderType");
                                DebugEffectChunk.Parse(reader, (uint)(data.Length - 4));
                            }
                            catch (Exception ex)
                            {
                                error = ex.ToString();
                            }
                            var dump = reader.DumpStructure();
                            if (!string.IsNullOrEmpty(error))
                            {
                                dump += "\n" + error;
                            }
                            sw.Write(dump);
                        }
                        else
                        {
                            var    reader = new DebugBytecodeReader(data, 0, data.Length);
                            string error  = "";
                            try
                            {
                                DebugShaderModel.Parse(reader);
                            }
                            catch (Exception ex)
                            {
                                error = ex.ToString();
                            }
                            var dump = reader.DumpStructure();
                            if (!string.IsNullOrEmpty(error))
                            {
                                dump += "\n" + error;
                            }
                            sw.Write(dump);
                        }
                    }
                    else if (options.Mode == DecompileMode.DebugHtml)
                    {
                        var shaderType = (SlimShader.DX9Shader.ShaderType)BitConverter.ToUInt16(data, 2);
                        if (shaderType == SlimShader.DX9Shader.ShaderType.Effect)
                        {
                            var    reader = new DebugBytecodeReader(data, 0, data.Length);
                            string error  = "";
                            try
                            {
                                reader.ReadByte("minorVersion");
                                reader.ReadByte("majorVersion");
                                reader.ReadUInt16("shaderType");
                                DebugEffectChunk.Parse(reader, (uint)(data.Length - 4));
                            }
                            catch (Exception ex)
                            {
                                error = ex.ToString();
                            }
                            var dump = reader.DumpHtml();
                            if (!string.IsNullOrEmpty(error))
                            {
                                dump += "\n" + error;
                            }
                            sw.Write(dump);
                        }
                        else
                        {
                            var    reader = new DebugBytecodeReader(data, 0, data.Length);
                            string error  = "";
                            try
                            {
                                DebugShaderModel.Parse(reader);
                            }
                            catch (Exception ex)
                            {
                                error = ex.ToString();
                            }
                            var dump = reader.DumpHtml();
                            if (!string.IsNullOrEmpty(error))
                            {
                                dump += "\n" + error;
                            }
                            sw.Write(dump);
                        }
                    }
                }
            }
        }
        public static DebugBytecodeChunk ParseChunk(DebugBytecodeReader chunkReader, DebugBytecodeContainer container)
        {
            // Type of chunk this is.
            uint fourCc = BitConverter.ToUInt32(chunkReader.ReadBytes("fourCc", 4), 0);

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

            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($"{fourCc.ToFourCcString()}", chunkReader, (int)chunkSize);
            DebugBytecodeChunk chunk = null;

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

            case ChunkType.Isgn:
            case ChunkType.Osgn:
            case ChunkType.Osg5:
            case ChunkType.Pcsg:
            case ChunkType.Isg1:
            case ChunkType.Osg1:
                chunk = DebugInputOutputSignatureChunk.Parse(chunkContentReader, chunkType,
                                                             container.ResourceDefinition?.Target?.ProgramType ??
                                                             (SlimShader.Chunks.Common.ProgramType) 100);
                break;

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

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

            case ChunkType.Sfi0:
                chunk = DebugSfi0Chunk.Parse(chunkContentReader, null, chunkSize);
                break;

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

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

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

            case ChunkType.Priv:
                break;

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

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

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

            case ChunkType.Fx10:
                chunk = DebugEffectChunk.Parse(chunkContentReader, chunkSize);
                break;

            case ChunkType.Ctab:
                chunk = DebugCtabChunk.Parse(chunkContentReader, chunkSize);
                break;

            case ChunkType.Cli4:
                chunk = DebugCli4Chunk.Parse(chunkContentReader, chunkSize);
                break;

            case ChunkType.Fxlc:
                chunk = DebugFxlcChunk.Parse(chunkContentReader, chunkSize, container);
                break;
                //default:
                //	throw new ParseException("Invalid chunk type: " + chunkType);
            }
            if (chunk == null)
            {
                chunkReader.ReadBytes("UnknownChunk", (int)chunkSize);
                return(null);
            }
            chunk.Container = container;
            chunk.FourCc    = fourCc;
            chunk.ChunkSize = chunkSize;
            chunk.ChunkType = chunkType;

            return(chunk);
        }