diff options
| author | gdk <gab.dark.100@gmail.com> | 2019-11-14 15:26:40 -0300 |
|---|---|---|
| committer | Thog <thog@protonmail.com> | 2020-01-09 02:13:00 +0100 |
| commit | 6e399061ceefb532561c4c5a5cd2681228e1231e (patch) | |
| tree | 18d2248f10c975939e4f9c8af787d677c36b0250 /Ryujinx.Graphics.Gpu/Engine | |
| parent | f0a59f345c633b757ebd2a22fca23d7dab0f9f99 (diff) | |
Invalidate shaders when they are modified
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Engine')
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Engine/Compute.cs | 5 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Engine/ComputeShader.cs | 18 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Engine/GraphicsShader.cs | 17 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Engine/Methods.cs | 7 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Engine/ShaderAddresses.cs | 34 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Engine/ShaderCache.cs | 249 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Engine/ShaderDumper.cs | 108 |
7 files changed, 7 insertions, 431 deletions
diff --git a/Ryujinx.Graphics.Gpu/Engine/Compute.cs b/Ryujinx.Graphics.Gpu/Engine/Compute.cs index 588825d0..108cc197 100644 --- a/Ryujinx.Graphics.Gpu/Engine/Compute.cs +++ b/Ryujinx.Graphics.Gpu/Engine/Compute.cs @@ -1,5 +1,6 @@ using Ryujinx.Graphics.GAL.Texture; using Ryujinx.Graphics.Gpu.Image; +using Ryujinx.Graphics.Gpu.Shader; using Ryujinx.Graphics.Gpu.State; using Ryujinx.Graphics.Shader; using System; @@ -25,7 +26,7 @@ namespace Ryujinx.Graphics.Gpu.Engine dispatchParams.UnpackBlockSizeY(), dispatchParams.UnpackBlockSizeZ()); - _context.Renderer.Pipeline.BindProgram(cs.Interface); + _context.Renderer.Pipeline.BindProgram(cs.HostProgram); var samplerPool = _context.State.Get<PoolState>(MethodOffset.SamplerPoolState); @@ -37,7 +38,7 @@ namespace Ryujinx.Graphics.Gpu.Engine _textureManager.SetComputeTextureBufferIndex(_context.State.Get<int>(MethodOffset.TextureBufferIndex)); - ShaderProgramInfo info = cs.Shader.Info; + ShaderProgramInfo info = cs.Shader.Program.Info; var textureBindings = new TextureBindingInfo[info.Textures.Count]; diff --git a/Ryujinx.Graphics.Gpu/Engine/ComputeShader.cs b/Ryujinx.Graphics.Gpu/Engine/ComputeShader.cs deleted file mode 100644 index cc7d4d99..00000000 --- a/Ryujinx.Graphics.Gpu/Engine/ComputeShader.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Ryujinx.Graphics.GAL; -using Ryujinx.Graphics.Shader; - -namespace Ryujinx.Graphics.Gpu.Engine -{ - class ComputeShader - { - public IProgram Interface { get; set; } - - public ShaderProgram Shader { get; } - - public ComputeShader(IProgram program, ShaderProgram shader) - { - Interface = program; - Shader = shader; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics.Gpu/Engine/GraphicsShader.cs b/Ryujinx.Graphics.Gpu/Engine/GraphicsShader.cs deleted file mode 100644 index a8ccc05a..00000000 --- a/Ryujinx.Graphics.Gpu/Engine/GraphicsShader.cs +++ /dev/null @@ -1,17 +0,0 @@ -using Ryujinx.Graphics.GAL; -using Ryujinx.Graphics.Shader; - -namespace Ryujinx.Graphics.Gpu.Engine -{ - class GraphicsShader - { - public IProgram Interface { get; set; } - - public ShaderProgram[] Shader { get; } - - public GraphicsShader() - { - Shader = new ShaderProgram[5]; - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics.Gpu/Engine/Methods.cs b/Ryujinx.Graphics.Gpu/Engine/Methods.cs index b1326ec5..f48d0a7f 100644 --- a/Ryujinx.Graphics.Gpu/Engine/Methods.cs +++ b/Ryujinx.Graphics.Gpu/Engine/Methods.cs @@ -5,6 +5,7 @@ using Ryujinx.Graphics.GAL.InputAssembler; using Ryujinx.Graphics.GAL.Texture; using Ryujinx.Graphics.Gpu.Image; using Ryujinx.Graphics.Gpu.Memory; +using Ryujinx.Graphics.Gpu.Shader; using Ryujinx.Graphics.Gpu.State; using Ryujinx.Graphics.Shader; using System; @@ -609,11 +610,11 @@ namespace Ryujinx.Graphics.Gpu.Engine GraphicsShader gs = _shaderCache.GetGraphicsShader(addresses); - _vsUsesInstanceId = gs.Shader[0].Info.UsesInstanceId; + _vsUsesInstanceId = gs.Shader[0].Program.Info.UsesInstanceId; for (int stage = 0; stage < Constants.TotalShaderStages; stage++) { - ShaderProgramInfo info = gs.Shader[stage]?.Info; + ShaderProgramInfo info = gs.Shader[stage].Program?.Info; _currentProgramInfo[stage] = info; @@ -665,7 +666,7 @@ namespace Ryujinx.Graphics.Gpu.Engine _bufferManager.SetGraphicsUniformBufferEnableMask(stage, ubEnableMask); } - _context.Renderer.Pipeline.BindProgram(gs.Interface); + _context.Renderer.Pipeline.BindProgram(gs.HostProgram); } private static Target GetTarget(SamplerType type) diff --git a/Ryujinx.Graphics.Gpu/Engine/ShaderAddresses.cs b/Ryujinx.Graphics.Gpu/Engine/ShaderAddresses.cs deleted file mode 100644 index 368b5a17..00000000 --- a/Ryujinx.Graphics.Gpu/Engine/ShaderAddresses.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; - -namespace Ryujinx.Graphics.Gpu.Engine -{ - struct ShaderAddresses : IEquatable<ShaderAddresses> - { - public ulong VertexA; - public ulong Vertex; - public ulong TessControl; - public ulong TessEvaluation; - public ulong Geometry; - public ulong Fragment; - - public override bool Equals(object other) - { - return other is ShaderAddresses addresses && Equals(addresses); - } - - public bool Equals(ShaderAddresses other) - { - return VertexA == other.VertexA && - Vertex == other.Vertex && - TessControl == other.TessControl && - TessEvaluation == other.TessEvaluation && - Geometry == other.Geometry && - Fragment == other.Fragment; - } - - public override int GetHashCode() - { - return HashCode.Combine(VertexA, Vertex, TessControl, TessEvaluation, Geometry, Fragment); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics.Gpu/Engine/ShaderCache.cs b/Ryujinx.Graphics.Gpu/Engine/ShaderCache.cs deleted file mode 100644 index 922f4a44..00000000 --- a/Ryujinx.Graphics.Gpu/Engine/ShaderCache.cs +++ /dev/null @@ -1,249 +0,0 @@ -using Ryujinx.Graphics.GAL; -using Ryujinx.Graphics.Gpu.State; -using Ryujinx.Graphics.Shader; -using Ryujinx.Graphics.Shader.Translation; -using System; -using System.Collections.Generic; -using System.Globalization; - -namespace Ryujinx.Graphics.Gpu.Engine -{ - class ShaderCache - { - private const int MaxProgramSize = 0x100000; - - private GpuContext _context; - - private ShaderDumper _dumper; - - private Dictionary<ulong, ComputeShader> _cpPrograms; - - private Dictionary<ShaderAddresses, GraphicsShader> _gpPrograms; - - public ShaderCache(GpuContext context) - { - _context = context; - - _dumper = new ShaderDumper(context); - - _cpPrograms = new Dictionary<ulong, ComputeShader>(); - - _gpPrograms = new Dictionary<ShaderAddresses, GraphicsShader>(); - } - - public ComputeShader GetComputeShader(ulong gpuVa, int localSizeX, int localSizeY, int localSizeZ) - { - if (!_cpPrograms.TryGetValue(gpuVa, out ComputeShader cpShader)) - { - ShaderProgram shader = TranslateComputeShader(gpuVa); - - shader.Replace(DefineNames.LocalSizeX, localSizeX.ToString(CultureInfo.InvariantCulture)); - shader.Replace(DefineNames.LocalSizeY, localSizeY.ToString(CultureInfo.InvariantCulture)); - shader.Replace(DefineNames.LocalSizeZ, localSizeZ.ToString(CultureInfo.InvariantCulture)); - - IShader hostShader = _context.Renderer.CompileShader(shader); - - IProgram program = _context.Renderer.CreateProgram(new IShader[] { hostShader }); - - cpShader = new ComputeShader(program, shader); - - _cpPrograms.Add(gpuVa, cpShader); - } - - return cpShader; - } - - public GraphicsShader GetGraphicsShader(ShaderAddresses addresses) - { - if (!_gpPrograms.TryGetValue(addresses, out GraphicsShader gpShader)) - { - gpShader = new GraphicsShader(); - - if (addresses.VertexA != 0) - { - gpShader.Shader[0] = TranslateGraphicsShader(addresses.Vertex, addresses.VertexA); - } - else - { - gpShader.Shader[0] = TranslateGraphicsShader(addresses.Vertex); - } - - gpShader.Shader[1] = TranslateGraphicsShader(addresses.TessControl); - gpShader.Shader[2] = TranslateGraphicsShader(addresses.TessEvaluation); - gpShader.Shader[3] = TranslateGraphicsShader(addresses.Geometry); - gpShader.Shader[4] = TranslateGraphicsShader(addresses.Fragment); - - BackpropQualifiers(gpShader); - - List<IShader> shaders = new List<IShader>(); - - for (int stage = 0; stage < gpShader.Shader.Length; stage++) - { - if (gpShader.Shader[stage] == null) - { - continue; - } - - IShader shader = _context.Renderer.CompileShader(gpShader.Shader[stage]); - - shaders.Add(shader); - } - - gpShader.Interface = _context.Renderer.CreateProgram(shaders.ToArray()); - - _gpPrograms.Add(addresses, gpShader); - } - - return gpShader; - } - - private ShaderProgram TranslateComputeShader(ulong gpuVa) - { - if (gpuVa == 0) - { - return null; - } - - ShaderProgram program; - - const TranslationFlags flags = - TranslationFlags.Compute | - TranslationFlags.DebugMode | - TranslationFlags.Unspecialized; - - TranslationConfig translationConfig = new TranslationConfig(0x10000, _dumper.CurrentDumpIndex, flags); - - Span<byte> code = _context.MemoryAccessor.Read(gpuVa, MaxProgramSize); - - program = Translator.Translate(code, translationConfig); - - _dumper.Dump(code, compute : true, out string fullPath, out string codePath); - - if (fullPath != null && codePath != null) - { - program.Prepend("// " + codePath); - program.Prepend("// " + fullPath); - } - - return program; - } - - private ShaderProgram TranslateGraphicsShader(ulong gpuVa, ulong gpuVaA = 0) - { - if (gpuVa == 0) - { - return null; - } - - ShaderProgram program; - - const TranslationFlags flags = - TranslationFlags.DebugMode | - TranslationFlags.Unspecialized; - - TranslationConfig translationConfig = new TranslationConfig(0x10000, _dumper.CurrentDumpIndex, flags); - - if (gpuVaA != 0) - { - Span<byte> codeA = _context.MemoryAccessor.Read(gpuVaA, MaxProgramSize); - Span<byte> codeB = _context.MemoryAccessor.Read(gpuVa, MaxProgramSize); - - program = Translator.Translate(codeA, codeB, translationConfig); - - _dumper.Dump(codeA, compute: false, out string fullPathA, out string codePathA); - _dumper.Dump(codeB, compute: false, out string fullPathB, out string codePathB); - - if (fullPathA != null && fullPathB != null && codePathA != null && codePathB != null) - { - program.Prepend("// " + codePathB); - program.Prepend("// " + fullPathB); - program.Prepend("// " + codePathA); - program.Prepend("// " + fullPathA); - } - } - else - { - Span<byte> code = _context.MemoryAccessor.Read(gpuVa, MaxProgramSize); - - program = Translator.Translate(code, translationConfig); - - _dumper.Dump(code, compute: false, out string fullPath, out string codePath); - - if (fullPath != null && codePath != null) - { - program.Prepend("// " + codePath); - program.Prepend("// " + fullPath); - } - } - - if (program.Stage == ShaderStage.Geometry) - { - PrimitiveType primitiveType = _context.Methods.PrimitiveType; - - string inPrimitive = "points"; - - switch (primitiveType) - { - case PrimitiveType.Points: - inPrimitive = "points"; - break; - case PrimitiveType.Lines: - case PrimitiveType.LineLoop: - case PrimitiveType.LineStrip: - inPrimitive = "lines"; - break; - case PrimitiveType.LinesAdjacency: - case PrimitiveType.LineStripAdjacency: - inPrimitive = "lines_adjacency"; - break; - case PrimitiveType.Triangles: - case PrimitiveType.TriangleStrip: - case PrimitiveType.TriangleFan: - inPrimitive = "triangles"; - break; - case PrimitiveType.TrianglesAdjacency: - case PrimitiveType.TriangleStripAdjacency: - inPrimitive = "triangles_adjacency"; - break; - } - - program.Replace(DefineNames.InputTopologyName, inPrimitive); - } - - return program; - } - - private void BackpropQualifiers(GraphicsShader program) - { - ShaderProgram fragmentShader = program.Shader[4]; - - bool isFirst = true; - - for (int stage = 3; stage >= 0; stage--) - { - if (program.Shader[stage] == null) - { - continue; - } - - // We need to iterate backwards, since we do name replacement, - // and it would otherwise replace a subset of the longer names. - for (int attr = 31; attr >= 0; attr--) - { - string iq = fragmentShader?.Info.InterpolationQualifiers[attr].ToGlslQualifier() ?? string.Empty; - - if (isFirst && iq != string.Empty) - { - program.Shader[stage].Replace($"{DefineNames.OutQualifierPrefixName}{attr}", iq); - } - else - { - program.Shader[stage].Replace($"{DefineNames.OutQualifierPrefixName}{attr} ", string.Empty); - } - } - - isFirst = false; - } - } - } -}
\ No newline at end of file diff --git a/Ryujinx.Graphics.Gpu/Engine/ShaderDumper.cs b/Ryujinx.Graphics.Gpu/Engine/ShaderDumper.cs deleted file mode 100644 index b2eb0f33..00000000 --- a/Ryujinx.Graphics.Gpu/Engine/ShaderDumper.cs +++ /dev/null @@ -1,108 +0,0 @@ -using Ryujinx.Graphics.Shader.Translation; -using System; -using System.IO; - -namespace Ryujinx.Graphics.Gpu.Engine -{ - class ShaderDumper - { - private GpuContext _context; - - private string _runtimeDir; - private string _dumpPath; - private int _dumpIndex; - - public int CurrentDumpIndex => _dumpIndex; - - public ShaderDumper(GpuContext context) - { - _context = context; - - _dumpIndex = 1; - } - - public void Dump(Span<byte> code, bool compute, out string fullPath, out string codePath) - { - _dumpPath = GraphicsConfig.ShadersDumpPath; - - if (string.IsNullOrWhiteSpace(_dumpPath)) - { - fullPath = null; - codePath = null; - - return; - } - - string fileName = "Shader" + _dumpIndex.ToString("d4") + ".bin"; - - fullPath = Path.Combine(FullDir(), fileName); - codePath = Path.Combine(CodeDir(), fileName); - - _dumpIndex++; - - code = Translator.ExtractCode(code, compute, out int headerSize); - - using (MemoryStream stream = new MemoryStream(code.ToArray())) - { - BinaryReader codeReader = new BinaryReader(stream); - - using (FileStream fullFile = File.Create(fullPath)) - using (FileStream codeFile = File.Create(codePath)) - { - BinaryWriter fullWriter = new BinaryWriter(fullFile); - BinaryWriter codeWriter = new BinaryWriter(codeFile); - - fullWriter.Write(codeReader.ReadBytes(headerSize)); - - byte[] temp = codeReader.ReadBytes(code.Length - headerSize); - - fullWriter.Write(temp); - codeWriter.Write(temp); - - // Align to meet nvdisasm requirements. - while (codeFile.Length % 0x20 != 0) - { - codeWriter.Write(0); - } - } - } - } - - private string FullDir() - { - return CreateAndReturn(Path.Combine(DumpDir(), "Full")); - } - - private string CodeDir() - { - return CreateAndReturn(Path.Combine(DumpDir(), "Code")); - } - - private string DumpDir() - { - if (string.IsNullOrEmpty(_runtimeDir)) - { - int index = 1; - - do - { - _runtimeDir = Path.Combine(_dumpPath, "Dumps" + index.ToString("d2")); - - index++; - } - while (Directory.Exists(_runtimeDir)); - - Directory.CreateDirectory(_runtimeDir); - } - - return _runtimeDir; - } - - private static string CreateAndReturn(string dir) - { - Directory.CreateDirectory(dir); - - return dir; - } - } -}
\ No newline at end of file |
