Exemplo n.º 1
0
        public static bool ParseShader(FxcShader shader)
        {
            ShaderBytecode ByteCodeObj;
            ShaderProfile  ShaderProfile;

            try
            {
                ByteCodeObj = new ShaderBytecode(shader.ByteCode);

                ShaderProfile = ByteCodeObj.GetVersion();


                switch (ShaderProfile.Version)
                {
                case ShaderVersion.VertexShader:
                case ShaderVersion.PixelShader:
                case ShaderVersion.GeometryShader:
                    //VersionMajor = br.ReadByte();//4,5 //appears to be shader model version
                    //VersionMinor = br.ReadByte(); //perhaps shader minor version
                    break;

                default:
                    shader.VersionMajor = (byte)ShaderProfile.Major;
                    shader.VersionMinor = (byte)ShaderProfile.Minor;
                    break;
                }

                shader.Disassembly = ByteCodeObj.Disassemble();
            }
            catch (Exception ex)
            {
                shader.LastError += ex.ToString() + "\r\n";
                return(false);
            }

            return(true);
        }
Exemplo n.º 2
0
        public string Export()
        {
            var sb = new StringBuilder();

            if (m_Keywords.Length > 0)
            {
                sb.Append("Keywords { ");
                foreach (string keyword in m_Keywords)
                {
                    sb.Append($"\"{keyword}\" ");
                }
                sb.Append("}\n");
            }

            sb.Append("\"\n");
            if (m_ProgramCode.Length > 0)
            {
                switch (m_ProgramType)
                {
                case ShaderGpuProgramType.kShaderGpuProgramGLLegacy:
                case ShaderGpuProgramType.kShaderGpuProgramGLES31AEP:
                case ShaderGpuProgramType.kShaderGpuProgramGLES31:
                case ShaderGpuProgramType.kShaderGpuProgramGLES3:
                case ShaderGpuProgramType.kShaderGpuProgramGLES:
                case ShaderGpuProgramType.kShaderGpuProgramGLCore32:
                case ShaderGpuProgramType.kShaderGpuProgramGLCore41:
                case ShaderGpuProgramType.kShaderGpuProgramGLCore43:
                    sb.Append(Encoding.UTF8.GetString(m_ProgramCode));
                    break;

                case ShaderGpuProgramType.kShaderGpuProgramDX9VertexSM20:
                case ShaderGpuProgramType.kShaderGpuProgramDX9VertexSM30:
                case ShaderGpuProgramType.kShaderGpuProgramDX9PixelSM20:
                case ShaderGpuProgramType.kShaderGpuProgramDX9PixelSM30:
                {
                    var shaderBytecode = new ShaderBytecode(m_ProgramCode);
                    sb.Append(shaderBytecode.Disassemble());
                    break;
                }

                case ShaderGpuProgramType.kShaderGpuProgramDX10Level9Vertex:
                case ShaderGpuProgramType.kShaderGpuProgramDX10Level9Pixel:
                case ShaderGpuProgramType.kShaderGpuProgramDX11VertexSM40:
                case ShaderGpuProgramType.kShaderGpuProgramDX11VertexSM50:
                case ShaderGpuProgramType.kShaderGpuProgramDX11PixelSM40:
                case ShaderGpuProgramType.kShaderGpuProgramDX11PixelSM50:
                case ShaderGpuProgramType.kShaderGpuProgramDX11GeometrySM40:
                case ShaderGpuProgramType.kShaderGpuProgramDX11GeometrySM50:
                case ShaderGpuProgramType.kShaderGpuProgramDX11HullSM50:
                case ShaderGpuProgramType.kShaderGpuProgramDX11DomainSM50:
                {
                    int start = 6;
                    if (magic == 201509030)         // 5.3
                    {
                        start = 5;
                    }
                    var buff = new byte[m_ProgramCode.Length - start];
                    Buffer.BlockCopy(m_ProgramCode, start, buff, 0, buff.Length);
                    var shaderBytecode = new ShaderBytecode(buff);
                    sb.Append(shaderBytecode.Disassemble());
                    break;
                }

                case ShaderGpuProgramType.kShaderGpuProgramMetalVS:
                case ShaderGpuProgramType.kShaderGpuProgramMetalFS:
                    using (var reader = new BinaryReader(new MemoryStream(m_ProgramCode)))
                    {
                        var fourCC = reader.ReadUInt32();
                        if (fourCC == 0xf00dcafe)
                        {
                            int offset = reader.ReadInt32();
                            reader.BaseStream.Position = offset;
                        }
                        var entryName = reader.ReadStringToNull();
                        var buff      = reader.ReadBytes((int)(reader.BaseStream.Length - reader.BaseStream.Position));
                        sb.Append(Encoding.UTF8.GetString(buff));
                    }
                    break;

                default:
                    sb.Append($"/*Unsupported program data {m_ProgramType}*/");
                    break;
                }
            }
            sb.Append('"');
            return(sb.ToString());
        }
Exemplo n.º 3
0
        public bool Read(BinaryReader br, bool exbyteflag)
        {
            Name = FxcFile.ReadString(br);

            if (Name.Length == 0)
            {
                Name       = FxcFile.ReadString(br); //why  (seems to be GS only)
                exbyteflag = true;
            }


            Params = FxcFile.ReadStringArray(br);

            byte bufferCount = br.ReadByte();
            var  buffers     = new List <FxcShaderBufferRef>();

            for (int e = 0; e < bufferCount; e++)
            {
                FxcShaderBufferRef ext = new FxcShaderBufferRef();
                ext.Name       = FxcFile.ReadString(br);
                ext.Unk0Ushort = br.ReadUInt16();
                buffers.Add(ext);
            }
            Buffers = buffers.ToArray();

            byte exbyte = 0;

            if (exbyteflag)
            {
                exbyte = br.ReadByte(); //not sure what this is used for...
                if ((exbyte != 0))
                {
                }
            }


            uint datalength = br.ReadUInt32();

            if (datalength > 0)
            {
                uint magic_dxbc = br.ReadUInt32();
                if (magic_dxbc != 1128421444) //"DXBC" - directx bytecode header
                {
                    LastError += "Unexpected data found at DXBC header...\r\n";
                    return(false);           //didn't find the DXBC header... abort!
                }
                br.BaseStream.Position -= 4; //wind back because dx needs that header

                ByteCode = br.ReadBytes((int)datalength);


                try
                {
                    ByteCodeObj = new ShaderBytecode(ByteCode);

                    ShaderProfile = ByteCodeObj.GetVersion();

                    Disassembly = ByteCodeObj.Disassemble();


                    switch (ShaderProfile.Version)
                    {
                    case ShaderVersion.VertexShader:
                    case ShaderVersion.PixelShader:
                    case ShaderVersion.GeometryShader:
                        VersionMajor = br.ReadByte();    //4,5 //appears to be shader model version
                        VersionMinor = br.ReadByte();    //perhaps shader minor version
                        break;

                    default:
                        VersionMajor = (byte)ShaderProfile.Major;
                        VersionMinor = (byte)ShaderProfile.Minor;
                        break;
                    }
                }
                catch (Exception ex)
                {
                    LastError += ex.ToString() + "\r\n";
                    return(false);
                }
            }
            else
            {
            }
            return(true);
        }
Exemplo n.º 4
0
        public static bool ValidateShaderOfType(string Type, string HlslType, string OriginalFile, string SourcePath)
        {
            var metadata = new ShaderMetadata(OriginalFile.Replace(".bin", ".txt"));

            // Grab the technique along with each #define used
            var techniqueId = metadata.GetTechnique();
            var macros      = GetCompilationMacros(Type, HlslType, metadata.GetDefines().ToList());

            //Program.LogLine("Validating shader [Technique: {0:X8}]: {1}...", techniqueId, OriginalFile);

            // Read from disk, compile, then disassemble to text
            ShaderBytecode originalBytecode = null;
            ShaderBytecode newBytecode      = null;

            try
            {
                originalBytecode = RecompileShader3DMigoto(OriginalFile, HlslType).Strip(m_StripFlags);

                //originalBytecode = ShaderBytecode.FromFile(OriginalFile).Strip(m_StripFlags);
                newBytecode = CompileShaderOfType(SourcePath, HlslType, macros).Strip(m_StripFlags);
            }
            catch (InvalidProgramException e)
            {
                Program.Log($"{OriginalFile}\n{e.Message}");
                return(false);
            }

            string[] originalDisasm = originalBytecode.Disassemble(DisassemblyFlags.None).Split('\n');
            string[] newDisasm      = newBytecode.Disassemble(DisassemblyFlags.None).Split('\n');

            // Sometimes the newly generated output will be shorter than the original code. Add some padding
            // to prevent out-of-bounds array access.
            if (originalDisasm.Length > newDisasm.Length)
            {
                string[] newArray = new string[originalDisasm.Length];

                for (int i = 0; i < newArray.Length; i++)
                {
                    newArray[i] = "\n";
                }

                newDisasm.CopyTo(newArray, 0);
                newDisasm = newArray;
            }

            try
            {
                ValidateShaderHeader(originalDisasm, newDisasm);
                ValidateShaderCode(originalDisasm, newDisasm);
            }
            catch (Exception)
            {
                //Program.LogLine("Validation failed.");

                // Dump raw disassembly to file
                File.WriteAllLines($"{Program.ShaderDiffDirectory}\\{Type}-{techniqueId:X}-{HlslType}-old.txt", originalDisasm);
                File.WriteAllLines($"{Program.ShaderDiffDirectory}\\{Type}-{techniqueId:X}-{HlslType}-new.txt", newDisasm);

                //
                // Generate the "symbolic" diff by:
                //
                // - Replacing all temporary registers with rX.xxxx
                // - Sorting all lines
                // - Eliminating all empty lines
                //
                var tempRegisterExpr = new Regex(@"r\d\.[xXyYzZwW]{1,4}", RegexOptions.Compiled);

                for (int i = 0; i < originalDisasm.Length; i++)
                {
                    originalDisasm[i] = tempRegisterExpr.Replace(originalDisasm[i], "rX.xxxx");
                    newDisasm[i]      = tempRegisterExpr.Replace(newDisasm[i], "rX.xxxx");
                }

                File.WriteAllLines($"{Program.ShaderDiffDirectory}\\{Type}-{techniqueId:X}-{HlslType}-symbolic-old.txt", originalDisasm.Where(x => !string.IsNullOrWhiteSpace(x)).OrderBy(x => x));
                File.WriteAllLines($"{Program.ShaderDiffDirectory}\\{Type}-{techniqueId:X}-{HlslType}-symbolic-new.txt", newDisasm.Where(x => !string.IsNullOrWhiteSpace(x)).OrderBy(x => x));
                return(false);
            }

            return(true);
        }