Example #1
0
        public static void Dump(IGalMemory Memory, long Position, GalShaderType Type, string ExtSuffix = "")
        {
            if (!IsDumpEnabled())
            {
                return;
            }

            string FileName = "Shader" + DumpIndex.ToString("d4") + "." + ShaderExtension(Type) + ExtSuffix + ".bin";

            string FullPath = Path.Combine(FullDir(), FileName);
            string CodePath = Path.Combine(CodeDir(), FileName);

            DumpIndex++;

            using (FileStream FullFile = File.Create(FullPath))
                using (FileStream CodeFile = File.Create(CodePath))
                {
                    BinaryWriter FullWriter = new BinaryWriter(FullFile);
                    BinaryWriter CodeWriter = new BinaryWriter(CodeFile);

                    for (long i = 0; i < 0x50; i += 4)
                    {
                        FullWriter.Write(Memory.ReadInt32(Position + i));
                    }

                    long Offset = 0;

                    ulong Instruction = 0;

                    //Dump until a NOP instruction is found
                    while ((Instruction >> 48 & 0xfff8) != 0x50b0)
                    {
                        uint Word0 = (uint)Memory.ReadInt32(Position + 0x50 + Offset + 0);
                        uint Word1 = (uint)Memory.ReadInt32(Position + 0x50 + Offset + 4);

                        Instruction = Word0 | (ulong)Word1 << 32;

                        //Zero instructions (other kind of NOP) stop immediatly,
                        //this is to avoid two rows of zeroes
                        if (Instruction == 0)
                        {
                            break;
                        }

                        FullWriter.Write(Instruction);
                        CodeWriter.Write(Instruction);

                        Offset += 8;
                    }

                    //Align to meet nvdisasm requeriments
                    while (Offset % 0x20 != 0)
                    {
                        FullWriter.Write(0);
                        CodeWriter.Write(0);

                        Offset += 4;
                    }
                }
        }
Example #2
0
        public ShaderHeader(IGalMemory Memory, long Position)
        {
            uint CommonWord0 = (uint)Memory.ReadInt32(Position + 0);
            uint CommonWord1 = (uint)Memory.ReadInt32(Position + 4);
            uint CommonWord2 = (uint)Memory.ReadInt32(Position + 8);
            uint CommonWord3 = (uint)Memory.ReadInt32(Position + 12);
            uint CommonWord4 = (uint)Memory.ReadInt32(Position + 16);

            SphType         = ReadBits(CommonWord0, 0, 5);
            Version         = ReadBits(CommonWord0, 5, 5);
            ShaderType      = ReadBits(CommonWord0, 10, 4);
            MrtEnable       = ReadBits(CommonWord0, 14, 1) != 0;
            KillsPixels     = ReadBits(CommonWord0, 15, 1) != 0;
            DoesGlobalStore = ReadBits(CommonWord0, 16, 1) != 0;
            SassVersion     = ReadBits(CommonWord0, 17, 4);
            DoesLoadOrStore = ReadBits(CommonWord0, 26, 1) != 0;
            DoesFp64        = ReadBits(CommonWord0, 27, 1) != 0;
            StreamOutMask   = ReadBits(CommonWord0, 28, 4);

            ShaderLocalMemoryLowSize = ReadBits(CommonWord1, 0, 24);
            PerPatchAttributeCount   = ReadBits(CommonWord1, 24, 8);

            ShaderLocalMemoryHighSize = ReadBits(CommonWord2, 0, 24);
            ThreadsPerInputPrimitive  = ReadBits(CommonWord2, 24, 8);

            ShaderLocalMemoryCrsSize = ReadBits(CommonWord3, 0, 24);
            OutputTopology           = ReadBits(CommonWord3, 24, 4);

            MaxOutputVertexCount = ReadBits(CommonWord4, 0, 12);
            StoreReqStart        = ReadBits(CommonWord4, 12, 8);
            StoreReqEnd          = ReadBits(CommonWord4, 24, 8);
        }
Example #3
0
        public static void Dump(IGalMemory memory, long position, GalShaderType type, string extSuffix = "")
        {
            if (!IsDumpEnabled())
            {
                return;
            }

            string fileName = "Shader" + DumpIndex.ToString("d4") + "." + ShaderExtension(type) + extSuffix + ".bin";

            string fullPath = Path.Combine(FullDir(), fileName);
            string codePath = Path.Combine(CodeDir(), fileName);

            DumpIndex++;

            using (FileStream fullFile = File.Create(fullPath))
                using (FileStream codeFile = File.Create(codePath))
                {
                    BinaryWriter fullWriter = new BinaryWriter(fullFile);
                    BinaryWriter codeWriter = new BinaryWriter(codeFile);

                    for (long i = 0; i < 0x50; i += 4)
                    {
                        fullWriter.Write(memory.ReadInt32(position + i));
                    }

                    long offset = 0;

                    ulong instruction = 0;

                    //Dump until a NOP instruction is found
                    while ((instruction >> 48 & 0xfff8) != 0x50b0)
                    {
                        uint word0 = (uint)memory.ReadInt32(position + 0x50 + offset + 0);
                        uint word1 = (uint)memory.ReadInt32(position + 0x50 + offset + 4);

                        instruction = word0 | (ulong)word1 << 32;

                        //Zero instructions (other kind of NOP) stop immediatly,
                        //this is to avoid two rows of zeroes
                        if (instruction == 0)
                        {
                            break;
                        }

                        fullWriter.Write(instruction);
                        codeWriter.Write(instruction);

                        offset += 8;
                    }

                    //Align to meet nvdisasm requeriments
                    while (offset % 0x20 != 0)
                    {
                        fullWriter.Write(0);
                        codeWriter.Write(0);

                        offset += 4;
                    }
                }
        }
Example #4
0
        private static void FillBlock(IGalMemory Memory, ShaderIrBlock Block, long Beginning)
        {
            long Position = Block.Position;

            do
            {
                //Ignore scheduling instructions, which are written every 32 bytes.
                if (((Position - Beginning) & 0x1f) == 0)
                {
                    Position += 8;

                    continue;
                }

                uint Word0 = (uint)Memory.ReadInt32(Position + 0);
                uint Word1 = (uint)Memory.ReadInt32(Position + 4);

                Position += 8;

                long OpCode = Word0 | (long)Word1 << 32;

                ShaderDecodeFunc Decode = ShaderOpCodeTable.GetDecoder(OpCode);

                if (AddDbgComments)
                {
                    string DbgOpCode = $"0x{(Position - Beginning - 8):x16}: 0x{OpCode:x16} ";

                    DbgOpCode += (Decode?.Method.Name ?? "???");

                    if (Decode == ShaderDecode.Bra)
                    {
                        int Offset = ((int)(OpCode >> 20) << 8) >> 8;

                        long Target = Position + Offset;

                        DbgOpCode += " (0x" + Target.ToString("x16") + ")";
                    }

                    Block.AddNode(new ShaderIrCmnt(DbgOpCode));
                }

                if (Decode == null)
                {
                    continue;
                }

                Decode(Block, OpCode);
            }while (!IsFlowChange(Block.GetLastNode()));

            Block.EndPosition = Position;
        }
Example #5
0
        private static void FillBlock(IGalMemory memory, ShaderIrBlock block, long beginning)
        {
            int position = block.Position;

            do
            {
                //Ignore scheduling instructions, which are written every 32 bytes.
                if ((position & 0x1f) == 0)
                {
                    position += 8;

                    continue;
                }

                uint word0 = (uint)memory.ReadInt32(position + beginning + 0);
                uint word1 = (uint)memory.ReadInt32(position + beginning + 4);

                position += 8;

                long opCode = word0 | (long)word1 << 32;

                ShaderDecodeFunc decode = ShaderOpCodeTable.GetDecoder(opCode);

                if (AddDbgComments)
                {
                    string dbgOpCode = $"0x{(position - 8):x16}: 0x{opCode:x16} ";

                    dbgOpCode += (decode?.Method.Name ?? "???");

                    if (decode == ShaderDecode.Bra || decode == ShaderDecode.Ssy)
                    {
                        int offset = ((int)(opCode >> 20) << 8) >> 8;

                        long target = position + offset;

                        dbgOpCode += " (0x" + target.ToString("x16") + ")";
                    }

                    block.AddNode(new ShaderIrCmnt(dbgOpCode));
                }

                if (decode == null)
                {
                    continue;
                }

                decode(block, opCode, position);
            }while (!IsFlowChange(block.GetLastNode()));

            block.EndPosition = position;
        }
Example #6
0
        private static void FillBlock(
            IGalMemory memory,
            Block block,
            ulong limitAddress,
            ulong startAddress)
        {
            ulong address = block.Address;

            do
            {
                if (address >= limitAddress)
                {
                    break;
                }

                //Ignore scheduling instructions, which are written every 32 bytes.
                if (((address - startAddress) & 0x1f) == 0)
                {
                    address += 8;

                    continue;
                }

                uint word0 = (uint)memory.ReadInt32((long)(address + 0));
                uint word1 = (uint)memory.ReadInt32((long)(address + 4));

                ulong opAddress = address;

                address += 8;

                long opCode = word0 | (long)word1 << 32;

                (InstEmitter emitter, Type opCodeType) = OpCodeTable.GetEmitter(opCode);

                if (emitter == null)
                {
                    //TODO: Warning, illegal encoding.
                    continue;
                }

                OpCode op = MakeOpCode(opCodeType, emitter, opAddress, opCode);

                block.OpCodes.Add(op);
            }while (!IsBranch(block.GetLastOp()));

            block.EndAddress = address;

            block.UpdateSsyOpCodes();
        }
Example #7
0
        public ShaderHeader(IGalMemory Memory, long Position)
        {
            uint CommonWord0 = (uint)Memory.ReadInt32(Position + 0);
            uint CommonWord1 = (uint)Memory.ReadInt32(Position + 4);
            uint CommonWord2 = (uint)Memory.ReadInt32(Position + 8);
            uint CommonWord3 = (uint)Memory.ReadInt32(Position + 12);
            uint CommonWord4 = (uint)Memory.ReadInt32(Position + 16);

            SphType         = ReadBits(CommonWord0, 0, 5);
            Version         = ReadBits(CommonWord0, 5, 5);
            ShaderType      = ReadBits(CommonWord0, 10, 4);
            MrtEnable       = ReadBits(CommonWord0, 14, 1) != 0;
            KillsPixels     = ReadBits(CommonWord0, 15, 1) != 0;
            DoesGlobalStore = ReadBits(CommonWord0, 16, 1) != 0;
            SassVersion     = ReadBits(CommonWord0, 17, 4);
            DoesLoadOrStore = ReadBits(CommonWord0, 26, 1) != 0;
            DoesFp64        = ReadBits(CommonWord0, 27, 1) != 0;
            StreamOutMask   = ReadBits(CommonWord0, 28, 4);

            ShaderLocalMemoryLowSize = ReadBits(CommonWord1, 0, 24);
            PerPatchAttributeCount   = ReadBits(CommonWord1, 24, 8);

            ShaderLocalMemoryHighSize = ReadBits(CommonWord2, 0, 24);
            ThreadsPerInputPrimitive  = ReadBits(CommonWord2, 24, 8);

            ShaderLocalMemoryCrsSize = ReadBits(CommonWord3, 0, 24);
            OutputTopology           = ReadBits(CommonWord3, 24, 4);

            MaxOutputVertexCount = ReadBits(CommonWord4, 0, 12);
            StoreReqStart        = ReadBits(CommonWord4, 12, 8);
            StoreReqEnd          = ReadBits(CommonWord4, 24, 8);

            //Type 2 (fragment?) reading
            uint Type2OmapTarget = (uint)Memory.ReadInt32(Position + 72);
            uint Type2Omap       = (uint)Memory.ReadInt32(Position + 76);

            OmapTargets = new OmapTarget[8];

            for (int i = 0; i < OmapTargets.Length; i++)
            {
                int Offset = i * 4;

                OmapTargets[i] = new OmapTarget
                {
                    Red   = ReadBits(Type2OmapTarget, Offset + 0, 1) != 0,
                    Green = ReadBits(Type2OmapTarget, Offset + 1, 1) != 0,
                    Blue  = ReadBits(Type2OmapTarget, Offset + 2, 1) != 0,
                    Alpha = ReadBits(Type2OmapTarget, Offset + 3, 1) != 0
                };
            }

            OmapSampleMask = ReadBits(Type2Omap, 0, 1) != 0;
            OmapDepth      = ReadBits(Type2Omap, 1, 1) != 0;
        }
Example #8
0
        public ShaderHeader(IGalMemory memory, ulong address)
        {
            int commonWord0 = memory.ReadInt32((long)address + 0);
            int commonWord1 = memory.ReadInt32((long)address + 4);
            int commonWord2 = memory.ReadInt32((long)address + 8);
            int commonWord3 = memory.ReadInt32((long)address + 12);
            int commonWord4 = memory.ReadInt32((long)address + 16);

            SphType = commonWord0.Extract(0, 5);

            Version = commonWord0.Extract(5, 5);

            ShaderType = commonWord0.Extract(10, 4);

            MrtEnable = commonWord0.Extract(14);

            KillsPixels = commonWord0.Extract(15);

            DoesGlobalStore = commonWord0.Extract(16);

            SassVersion = commonWord0.Extract(17, 4);

            DoesLoadOrStore = commonWord0.Extract(26);

            DoesFp64 = commonWord0.Extract(27);

            StreamOutMask = commonWord0.Extract(28, 4);

            ShaderLocalMemoryLowSize = commonWord1.Extract(0, 24);

            PerPatchAttributeCount = commonWord1.Extract(24, 8);

            ShaderLocalMemoryHighSize = commonWord2.Extract(0, 24);

            ThreadsPerInputPrimitive = commonWord2.Extract(24, 8);

            ShaderLocalMemoryCrsSize = commonWord3.Extract(0, 24);

            OutputTopology = commonWord3.Extract(24, 4);

            MaxOutputVertexCount = commonWord4.Extract(0, 12);

            StoreReqStart = commonWord4.Extract(12, 8);
            StoreReqEnd   = commonWord4.Extract(24, 8);

            int type2OmapTarget = memory.ReadInt32((long)address + 72);
            int type2Omap       = memory.ReadInt32((long)address + 76);

            OmapTargets = new OutputMapTarget[8];

            for (int offset = 0; offset < OmapTargets.Length * 4; offset += 4)
            {
                OmapTargets[offset >> 2] = new OutputMapTarget(
                    type2OmapTarget.Extract(offset + 0),
                    type2OmapTarget.Extract(offset + 1),
                    type2OmapTarget.Extract(offset + 2),
                    type2OmapTarget.Extract(offset + 3));
            }

            OmapSampleMask = type2Omap.Extract(0);
            OmapDepth      = type2Omap.Extract(1);
        }