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; } } }
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); }
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; } } }
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; }
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; }
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(); }
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; }
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); }