diff --git a/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs b/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs index 96eb6f04c..ffe2d33ad 100644 --- a/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs +++ b/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs @@ -1,3 +1,4 @@ +using Ryujinx.Common.Logging; using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Gpu.Engine.Types; using Ryujinx.Graphics.Shader; @@ -119,19 +120,24 @@ namespace Ryujinx.Graphics.Gpu.Image /// Type of the sampler pool indexing used for bound samplers public void SetSamplerPool(ulong gpuVa, int maximumId, SamplerIndex samplerIndex) { - ulong address = _channel.MemoryManager.Translate(gpuVa); - - if (_samplerPool != null) + if (gpuVa != 0) { - if (_samplerPool.Address == address && _samplerPool.MaximumId >= maximumId) + ulong address = _channel.MemoryManager.Translate(gpuVa); + + if (_samplerPool != null && _samplerPool.Address == address && _samplerPool.MaximumId >= maximumId) { return; } - _samplerPool.Dispose(); + _samplerPool?.Dispose(); + _samplerPool = new SamplerPool(_context, _channel.MemoryManager.Physical, address, maximumId); + } + else + { + _samplerPool?.Dispose(); + _samplerPool = null; } - _samplerPool = new SamplerPool(_context, _channel.MemoryManager.Physical, address, maximumId); _samplerIndex = samplerIndex; } @@ -142,10 +148,18 @@ namespace Ryujinx.Graphics.Gpu.Image /// Maximum ID of the pool (total count minus one) public void SetTexturePool(ulong gpuVa, int maximumId) { - ulong address = _channel.MemoryManager.Translate(gpuVa); + if (gpuVa != 0) + { + ulong address = _channel.MemoryManager.Translate(gpuVa); - _texturePoolAddress = address; - _texturePoolMaximumId = maximumId; + _texturePoolAddress = address; + _texturePoolMaximumId = maximumId; + } + else + { + _texturePoolAddress = 0; + _texturePoolMaximumId = 0; + } } /// @@ -227,10 +241,11 @@ namespace Ryujinx.Graphics.Gpu.Image /// public void CommitBindings() { - TexturePool texturePool = _texturePoolCache.FindOrCreate( - _channel, - _texturePoolAddress, - _texturePoolMaximumId); + ulong texturePoolAddress = _texturePoolAddress; + + TexturePool texturePool = texturePoolAddress != 0 + ? _texturePoolCache.FindOrCreate(_channel, texturePoolAddress, _texturePoolMaximumId) + : null; if (_isCompute) { @@ -264,11 +279,25 @@ namespace Ryujinx.Graphics.Gpu.Image /// The stage number of the specified shader stage private void CommitTextureBindings(TexturePool pool, ShaderStage stage, int stageIndex) { - if (_textureBindings[stageIndex] == null) + if (_textureBindings[stageIndex] == null || _textureBindings[stageIndex].Length == 0) { return; } + var samplerPool = _samplerPool; + + if (pool == null) + { + Logger.Error?.Print(LogClass.Gpu, $"Shader stage \"{stage}\" uses textures, but texture pool was not set."); + return; + } + + if (samplerPool == null) + { + Logger.Error?.Print(LogClass.Gpu, $"Shader stage \"{stage}\" uses textures, but sampler pool was not set."); + return; + } + for (int index = 0; index < _textureBindings[stageIndex].Length; index++) { TextureBindingInfo bindingInfo = _textureBindings[stageIndex][index]; @@ -324,7 +353,7 @@ namespace Ryujinx.Graphics.Gpu.Image _channel.BufferManager.SetBufferTextureStorage(hostTexture, texture.Range.GetSubRange(0).Address, texture.Size, bindingInfo, bindingInfo.Format, false); } - Sampler sampler = _samplerPool.Get(samplerId); + Sampler sampler = samplerPool.Get(samplerId); ISampler hostSampler = sampler?.HostSampler; @@ -351,6 +380,12 @@ namespace Ryujinx.Graphics.Gpu.Image return; } + if (pool == null && _imageBindings[stageIndex].Length != 0) + { + Logger.Error?.Print(LogClass.Gpu, $"Shader stage \"{stage}\" uses images, but texture pool was not set."); + return; + } + // Scales for images appear after the texture ones. int baseScaleIndex = _textureBindings[stageIndex]?.Length ?? 0;