예제 #1
0
        public static DebugPreshader Parse(DebugBytecodeReader reader)
        {
            var result = new DebugPreshader();

            result.Shader = DebugShaderModel.Parse(reader);
            return(result);
        }
예제 #2
0
        public static DebugStateBlob Parse(DebugBytecodeReader reader, DebugBytecodeReader blobReader)
        {
            var result = new DebugStateBlob();

            result.TechniqueIndex    = blobReader.ReadUInt32("TechniqueIndex");
            result.PassIndex         = blobReader.ReadUInt32("PassIndex");
            result.SamplerStateIndex = blobReader.ReadUInt32("SamplerStateIndex");
            result.AssignmentIndex   = blobReader.ReadUInt32("AssignmentIndex");
            result.BlobType          = blobReader.ReadEnum32 <StateBlobType>("BlobType");
            if (result.BlobType == StateBlobType.Shader)
            {
                result.ShaderSize = blobReader.ReadUInt32("BlobSize");
                var startPosition = blobReader._reader.BaseStream.Position;
                var shaderReader  = blobReader.CopyAtCurrentPosition("ShaderReader", blobReader);
                result.Shader = DebugShaderModel.Parse(shaderReader);
                blobReader._reader.BaseStream.Position = startPosition + result.ShaderSize;
            }
            if (result.BlobType == StateBlobType.Variable)
            {
                result.VariableName = blobReader.TryReadString("VariableName");
            }
            else if (result.BlobType == StateBlobType.IndexShader)
            {
                result.ShaderSize = blobReader.ReadUInt32("BlobSize");
                var startPosition = blobReader._reader.BaseStream.Position;
                var variableSize  = blobReader.ReadUInt32("VariableNameSize");
                var variableData  = blobReader.ReadBytes("VariableData", (int)variableSize);
                result.VariableName = Encoding.UTF8.GetString(variableData, 0, variableData.Length - 1);
                var shaderReader = blobReader.CopyAtCurrentPosition("ShaderReader", blobReader);
                result.Shader = DebugShaderModel.Parse(shaderReader);
                blobReader._reader.BaseStream.Position = startPosition + result.ShaderSize;
            }
            return(result);
        }
예제 #3
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.
        }
예제 #4
0
        public static DebugBinaryData Parse(DebugBytecodeReader reader, DebugBytecodeReader blobReader)
        {
            var result = new DebugBinaryData();

            result.Index = blobReader.ReadUInt32("Index");
            result.Size  = blobReader.ReadUInt32("Size");
            var startPosition = blobReader._reader.BaseStream.Position;
            var header        = blobReader.PeakUint32();
            var shaderType    = (ShaderType)(header >> 16);
            var paddedSize    = result.Size + (result.Size % 4 == 0 ? 0 : 4 - result.Size % 4);

            if (shaderType == ShaderType.Pixel || shaderType == ShaderType.Vertex || shaderType == ShaderType.Expression)
            {
                var shaderReader = blobReader.CopyAtCurrentPosition("ShaderReader", blobReader);
                result.Shader = DebugShaderModel.Parse(shaderReader);
            }
            else if (result.Size > 0)
            {
                blobReader.ReadBytes("Value", (int)paddedSize);
            }
            blobReader._reader.BaseStream.Position = startPosition + paddedSize;
            return(result);
        }
예제 #5
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);
                        }
                    }
                }
            }
        }