static void Main(string[] args) { if (args.Length == 2) { GlslDecompiler Decompiler = new GlslDecompiler(); GalShaderType ShaderType = GalShaderType.Vertex; switch (args[0].ToLower()) { case "v": ShaderType = GalShaderType.Vertex; break; case "tc": ShaderType = GalShaderType.TessControl; break; case "te": ShaderType = GalShaderType.TessEvaluation; break; case "g": ShaderType = GalShaderType.Geometry; break; case "f": ShaderType = GalShaderType.Fragment; break; } byte[] Binary = File.ReadAllBytes(args[1]); GlslProgram Program = Decompiler.Decompile(Binary, ShaderType); Console.WriteLine(Program.Code); } else { Console.WriteLine("Usage: Ryujinx.ShaderTools [v|tc|te|g|f] shader.bin"); } }
static void Main(string[] args) { if (args.Length == 2) { GalShaderType type = GalShaderType.Vertex; switch (args[0].ToLower()) { case "v": type = GalShaderType.Vertex; break; case "tc": type = GalShaderType.TessControl; break; case "te": type = GalShaderType.TessEvaluation; break; case "g": type = GalShaderType.Geometry; break; case "f": type = GalShaderType.Fragment; break; } using (FileStream fs = new FileStream(args[1], FileMode.Open, FileAccess.Read)) { Memory mem = new Memory(fs); ShaderConfig config = new ShaderConfig(type, 65536); string code = Translator.Translate(mem, 0, config).Code; Console.WriteLine(code); } } else { Console.WriteLine("Usage: Ryujinx.ShaderTools [v|tc|te|g|f] shader.bin"); } }
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 GlslProgram Decompile(int[] Code, GalShaderType ShaderType) { ShaderIrBlock Block = ShaderDecoder.DecodeBasicBlock(Code, 0); ShaderIrNode[] Nodes = Block.GetNodes(); Decl = new GlslDecl(Nodes, ShaderType); SB = new StringBuilder(); SB.AppendLine("#version 410 core"); PrintDeclTextures(); PrintDeclUniforms(); PrintDeclInAttributes(); PrintDeclOutAttributes(); PrintDeclGprs(); PrintDeclPreds(); PrintBlockScope("void main()", 1, Nodes); string GlslCode = SB.ToString(); return(new GlslProgram( GlslCode, Decl.Textures.Values, Decl.Uniforms.Values)); }
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 GlslDecl(ShaderIrNode[] Nodes, GalShaderType ShaderType) { this.ShaderType = ShaderType; StagePrefix = StagePrefixes[(int)ShaderType] + "_"; m_Uniforms = new Dictionary <int, ShaderDeclInfo>(); m_Textures = new Dictionary <int, ShaderDeclInfo>(); m_InAttributes = new Dictionary <int, ShaderDeclInfo>(); m_OutAttributes = new Dictionary <int, ShaderDeclInfo>(); m_Gprs = new Dictionary <int, ShaderDeclInfo>(); m_Preds = new Dictionary <int, ShaderDeclInfo>(); if (ShaderType == GalShaderType.Fragment) { m_Gprs.Add(0, new ShaderDeclInfo(FragmentOutputName, 0, 0, 4)); m_InAttributes.Add(7, new ShaderDeclInfo(PositionOutAttrName, -1, 0, 4)); } else { m_OutAttributes.Add(7, new ShaderDeclInfo("gl_Position", -1, 0, 4)); } foreach (ShaderIrNode Node in Nodes) { Traverse(null, Node); } }
static void Main(string[] args) { if (args.Length == 2) { GlslDecompiler Decompiler = new GlslDecompiler(MaxUboSize); GalShaderType ShaderType = GalShaderType.Vertex; switch (args[0].ToLower()) { case "v": ShaderType = GalShaderType.Vertex; break; case "tc": ShaderType = GalShaderType.TessControl; break; case "te": ShaderType = GalShaderType.TessEvaluation; break; case "g": ShaderType = GalShaderType.Geometry; break; case "f": ShaderType = GalShaderType.Fragment; break; } using (FileStream FS = new FileStream(args[1], FileMode.Open, FileAccess.Read)) { Memory Mem = new Memory(FS); GlslProgram Program = Decompiler.Decompile(Mem, 0, ShaderType); Console.WriteLine(Program.Code); } } else { Console.WriteLine("Usage: Ryujinx.ShaderTools [v|tc|te|g|f] shader.bin"); } }
public static void Dump(byte[] Binary, GalShaderType Type, string ExtSuffix = "") { if (string.IsNullOrWhiteSpace(GraphicsConfig.ShadersDumpPath)) { return; } string FileName = "Shader" + DumpIndex.ToString("d4") + "." + ShaderExtension(Type) + ExtSuffix + ".bin"; string FullPath = Path.Combine(FullDir(), FileName); string CodePath = Path.Combine(CodeDir(), FileName); DumpIndex++; File.WriteAllBytes(FullPath, Binary); using (FileStream CodeFile = File.Create(CodePath)) using (BinaryWriter Writer = new BinaryWriter(CodeFile)) { long Offset; for (Offset = 0; Offset + 0x50 < Binary.LongLength; Offset++) { Writer.Write(Binary[Offset + 0x50]); } //Align to meet nvdisasm requeriments while (Offset % 0x20 != 0) { Writer.Write(0); Offset += 4; } } }
public GlslProgram Decompile(IGalMemory Memory, long Position, GalShaderType ShaderType) { Blocks = ShaderDecoder.Decode(Memory, Position); Decl = new GlslDecl(Blocks, ShaderType); SB = new StringBuilder(); SB.AppendLine("#version 410 core"); PrintDeclTextures(); PrintDeclUniforms(); PrintDeclInAttributes(); PrintDeclOutAttributes(); PrintDeclGprs(); PrintDeclPreds(); PrintBlockScope(Blocks[0], null, null, "void main()", IdentationStr); string GlslCode = SB.ToString(); return(new GlslProgram( GlslCode, Decl.Textures.Values, Decl.Uniforms.Values)); }
public static ShaderIrBlock DecodeBasicBlock(int[] Code, int Offset, GalShaderType ShaderType) { ShaderIrBlock Block = new ShaderIrBlock(); while (Offset + 2 <= Code.Length) { uint Word0 = (uint)Code[Offset++]; uint Word1 = (uint)Code[Offset++]; long OpCode = Word0 | (long)Word1 << 32; ShaderDecodeFunc Decode = ShaderOpCodeTable.GetDecoder(OpCode); if (Decode == null) { continue; } Decode(Block, OpCode); if (Block.GetLastNode() is ShaderIrOp Op && IsFlowChange(Op.Inst)) { break; } } Block.RunOptimizationPasses(ShaderType); return(Block); }
private ShaderStage ShaderStageFactory( IGalMemory Memory, long Position, long PositionB, bool IsDualVp, GalShaderType Type) { GlslProgram Program; GlslDecompiler Decompiler = new GlslDecompiler(); if (IsDualVp) { ShaderDumper.Dump(Memory, Position, Type, "a"); ShaderDumper.Dump(Memory, PositionB, Type, "b"); Program = Decompiler.Decompile( Memory, Position, PositionB, Type); } else { ShaderDumper.Dump(Memory, Position, Type); Program = Decompiler.Decompile(Memory, Position, Type); } return(new ShaderStage( Type, Program.Code, Program.Textures, Program.Uniforms)); }
public static void Optimize(List <ShaderIrNode> Nodes, GalShaderType ShaderType) { Dictionary <int, RegUse> Uses = new Dictionary <int, RegUse>(); RegUse GetUse(int Key) { RegUse Use; if (!Uses.TryGetValue(Key, out Use)) { Use = new RegUse(); Uses.Add(Key, Use); } return(Use); } int GetGprKey(int GprIndex) { return(GprIndex); } int GetPredKey(int PredIndex) { return(PredIndex | 0x10000000); } RegUse GetGprUse(int GprIndex) { return(GetUse(GetGprKey(GprIndex))); } RegUse GetPredUse(int PredIndex) { return(GetUse(GetPredKey(PredIndex))); } void FindRegUses(List <(int, UseSite)> UseList, object Parent, ShaderIrNode Node, int OperIndex = 0) { if (Node is ShaderIrAsg Asg) { FindRegUses(UseList, Asg, Asg.Src); } else if (Node is ShaderIrCond Cond) { FindRegUses(UseList, Cond, Cond.Pred, 0); FindRegUses(UseList, Cond, Cond.Child, 1); } else if (Node is ShaderIrOp Op) { FindRegUses(UseList, Op, Op.OperandA, 0); FindRegUses(UseList, Op, Op.OperandB, 1); FindRegUses(UseList, Op, Op.OperandC, 2); } else if (Node is ShaderIrOperGpr Gpr && Gpr.Index != ShaderIrOperGpr.ZRIndex) { UseList.Add((GetGprKey(Gpr.Index), new UseSite(Parent, OperIndex))); }
public static string GetConstantBufferName(AstOperand cbuf, GalShaderType shaderType) { string ubName = GetUbName(shaderType, cbuf.CbufSlot); ubName += "[" + (cbuf.CbufOffset >> 2) + "]"; return(ubName + "." + GetSwizzleMask(cbuf.CbufOffset & 3)); }
public static string GetUbName(GalShaderType shaderType, int slot) { string ubName = GetShaderStagePrefix(shaderType); ubName += "_" + DefaultNames.UniformNamePrefix + slot; return(ubName + "_" + DefaultNames.UniformNameSuffix); }
public GlslProgram Decompile(IGalMemory Memory, long Position, GalShaderType ShaderType) { Blocks = ShaderDecoder.Decode(Memory, Position); BlocksB = null; Decl = new GlslDecl(Blocks, ShaderType); return(Decompile()); }
public EmitterContext(GalShaderType shaderType, ShaderHeader header) { _shaderType = shaderType; _header = header; _operations = new List <Operation>(); _labels = new Dictionary <ulong, Operand>(); }
public void CreateShader(long Tag, GalShaderType Type, byte[] Data) { if (Data == null) { throw new ArgumentNullException(nameof(Data)); } Shader.Create(Tag, Type, Data); }
public void CreateShader(IGalMemory Memory, long Tag, GalShaderType Type) { if (Memory == null) { throw new ArgumentNullException(nameof(Memory)); } Shader.Create(Memory, Tag, Type); }
private ShaderStage ShaderStageFactory(IGalMemory Memory, long Position, GalShaderType Type) { GlslProgram Program = GetGlslProgram(Memory, Position, Type); return(new ShaderStage( Type, Program.Code, Program.Textures, Program.Uniforms)); }
public ShaderConfig(GalShaderType type, int maxCBufferSize) { if (maxCBufferSize <= 0) { throw new ArgumentOutOfRangeException(nameof(maxCBufferSize)); } Type = type; MaxCBufferSize = maxCBufferSize; }
private ShaderStage ShaderStageFactory(GalShaderType Type, byte[] Data) { GlslProgram Program = GetGlslProgram(Data, Type); return(new ShaderStage( Type, Program.Code, Program.Textures, Program.Uniforms)); }
public OglShaderStage( GalShaderType type, string code, IEnumerable <CBufferDescriptor> constBufferUsage, IEnumerable <TextureDescriptor> textureUsage) { Type = type; Code = code; ConstBufferUsage = constBufferUsage; TextureUsage = textureUsage; }
public OglShaderStage( GalShaderType type, string code, IEnumerable <ShaderDeclInfo> constBufferUsage, IEnumerable <ShaderDeclInfo> textureUsage) { Type = type; Code = code; ConstBufferUsage = constBufferUsage; TextureUsage = textureUsage; }
public OGLShaderStage( GalShaderType Type, string Code, IEnumerable <ShaderDeclInfo> ConstBufferUsage, IEnumerable <ShaderDeclInfo> TextureUsage) { this.Type = Type; this.Code = Code; this.ConstBufferUsage = ConstBufferUsage; this.TextureUsage = TextureUsage; }
public ShaderStage( GalShaderType Type, string Code, IEnumerable <ShaderDeclInfo> TextureUsage, IEnumerable <ShaderDeclInfo> UniformUsage) { this.Type = Type; this.Code = Code; this.TextureUsage = TextureUsage; this.UniformUsage = UniformUsage; }
public GlslProgram Decompile(byte[] Binary, GalShaderType ShaderType) { Header = new ShaderHeader(Binary); HeaderB = null; Blocks = ShaderDecoder.Decode(Binary); BlocksB = null; Decl = new GlslDecl(Blocks, ShaderType, Header); return(Decompile()); }
public static string GetConstantBufferName(IAstNode slot, string offsetExpr, GalShaderType shaderType) { // Non-constant slots are not supported. // It is expected that upstream stages are never going to generate non-constant // slot access. AstOperand operand = (AstOperand)slot; string ubName = GetUbName(shaderType, operand.Value); string index0 = "[" + offsetExpr + " >> 4]"; string index1 = "[" + offsetExpr + " >> 2 & 3]"; return(ubName + index0 + index1); }
private GlslDecl(GalShaderType ShaderType) { this.ShaderType = ShaderType; m_Uniforms = new Dictionary <int, ShaderDeclInfo>(); m_Textures = new Dictionary <int, ShaderDeclInfo>(); m_Attributes = new Dictionary <int, ShaderDeclInfo>(); m_InAttributes = new Dictionary <int, ShaderDeclInfo>(); m_OutAttributes = new Dictionary <int, ShaderDeclInfo>(); m_Gprs = new Dictionary <int, ShaderDeclInfo>(); m_Preds = new Dictionary <int, ShaderDeclInfo>(); }
private long[] UploadShaders(AMemory Memory) { long[] Tags = new long[5]; long BasePosition = MakeInt64From2xInt32(NvGpuEngine3dReg.ShaderAddress); for (int Index = 0; Index < 6; Index++) { int Control = ReadRegister(NvGpuEngine3dReg.ShaderNControl + Index * 0x10); int Offset = ReadRegister(NvGpuEngine3dReg.ShaderNOffset + Index * 0x10); //Note: Vertex Program (B) is always enabled. bool Enable = (Control & 1) != 0 || Index == 1; if (!Enable) { continue; } long Tag = BasePosition + (uint)Offset; long Position = Gpu.GetCpuAddr(Tag); //TODO: Find a better way to calculate the size. int Size = 0x20000; byte[] Code = AMemoryHelper.ReadBytes(Memory, Position, (uint)Size); GalShaderType ShaderType = GetTypeFromProgram(Index); Tags[(int)ShaderType] = Tag; Gpu.Renderer.CreateShader(Tag, ShaderType, Code); Gpu.Renderer.BindShader(Tag); } int RawSX = ReadRegister(NvGpuEngine3dReg.ViewportScaleX); int RawSY = ReadRegister(NvGpuEngine3dReg.ViewportScaleY); float SX = BitConverter.Int32BitsToSingle(RawSX); float SY = BitConverter.Int32BitsToSingle(RawSY); float SignX = MathF.Sign(SX); float SignY = MathF.Sign(SY); Gpu.Renderer.SetUniform2F(GalConsts.FlipUniformName, SignX, SignY); return(Tags); }
public void Unbind(GalShaderType Type) { switch (Type) { case GalShaderType.Vertex: Current.Vertex = null; break; case GalShaderType.TessControl: Current.TessControl = null; break; case GalShaderType.TessEvaluation: Current.TessEvaluation = null; break; case GalShaderType.Geometry: Current.Geometry = null; break; case GalShaderType.Fragment: Current.Fragment = null; break; } }