diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs index 158b791a5..d752b1b0f 100644 --- a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs +++ b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs @@ -36,7 +36,7 @@ namespace Ryujinx.Graphics.Gpu.Shader /// /// Version of the codegen (to be changed when codegen or guest format change). /// - private const ulong ShaderCodeGenVersion = 2298; + private const ulong ShaderCodeGenVersion = 2300; // Progress reporting helpers private volatile int _shaderCount; diff --git a/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs b/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs index 8004e3133..b193d61e7 100644 --- a/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs +++ b/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs @@ -163,6 +163,34 @@ namespace Ryujinx.Graphics.Shader.Translation Size += size; } + public void InheritFrom(ShaderConfig other) + { + ClipDistancesWritten |= other.ClipDistancesWritten; + UsedFeatures |= other.UsedFeatures; + + TextureHandlesForCache.UnionWith(other.TextureHandlesForCache); + + _usedConstantBuffers |= other._usedConstantBuffers; + _usedStorageBuffers |= other._usedStorageBuffers; + _usedStorageBuffersWrite |= other._usedStorageBuffersWrite; + + foreach (var kv in other._usedTextures) + { + if (!_usedTextures.TryAdd(kv.Key, kv.Value)) + { + _usedTextures[kv.Key] = MergeTextureMeta(kv.Value, _usedTextures[kv.Key]); + } + } + + foreach (var kv in other._usedImages) + { + if (!_usedImages.TryAdd(kv.Key, kv.Value)) + { + _usedImages[kv.Key] = MergeTextureMeta(kv.Value, _usedImages[kv.Key]); + } + } + } + public void SetClipDistanceWritten(int index) { ClipDistancesWritten |= (byte)(1 << index); @@ -269,17 +297,7 @@ namespace Ryujinx.Graphics.Shader.Translation if (dict.TryGetValue(info, out var existingMeta)) { - meta.UsageFlags |= existingMeta.UsageFlags; - - // If the texture we have has inaccurate type information, then - // we prefer the most accurate one. - if (existingMeta.AccurateType) - { - meta.AccurateType = true; - meta.Type = existingMeta.Type; - } - - dict[info] = meta; + dict[info] = MergeTextureMeta(meta, existingMeta); } else { @@ -288,6 +306,21 @@ namespace Ryujinx.Graphics.Shader.Translation } } + private static TextureMeta MergeTextureMeta(TextureMeta meta, TextureMeta existingMeta) + { + meta.UsageFlags |= existingMeta.UsageFlags; + + // If the texture we have has inaccurate type information, then + // we prefer the most accurate one. + if (existingMeta.AccurateType) + { + meta.AccurateType = true; + meta.Type = existingMeta.Type; + } + + return meta; + } + public BufferDescriptor[] GetConstantBufferDescriptors() { if (_cachedConstantBufferDescriptors != null) diff --git a/Ryujinx.Graphics.Shader/Translation/TranslatorContext.cs b/Ryujinx.Graphics.Shader/Translation/TranslatorContext.cs index 649911a23..ab74d039c 100644 --- a/Ryujinx.Graphics.Shader/Translation/TranslatorContext.cs +++ b/Ryujinx.Graphics.Shader/Translation/TranslatorContext.cs @@ -132,10 +132,9 @@ namespace Ryujinx.Graphics.Shader.Translation if (other != null) { - _config.SetUsedFeature(other._config.UsedFeatures); - TextureHandlesForCache.UnionWith(other.TextureHandlesForCache); - code = Combine(EmitShader(other._cfg, other._config), code); + + _config.InheritFrom(other._config); } return Translator.Translate(code, _config, out shaderProgramInfo);