diff --git a/src/Ryujinx.Graphics.GAL/IPipeline.cs b/src/Ryujinx.Graphics.GAL/IPipeline.cs index 0a362081c..f5978cefa 100644 --- a/src/Ryujinx.Graphics.GAL/IPipeline.cs +++ b/src/Ryujinx.Graphics.GAL/IPipeline.cs @@ -79,7 +79,6 @@ namespace Ryujinx.Graphics.GAL void SetRasterizerDiscard(bool discard); - void SetRenderTargetScale(float scale); void SetRenderTargetColorMasks(ReadOnlySpan componentMask); void SetRenderTargets(ITexture[] colors, ITexture depthStencil); @@ -99,7 +98,7 @@ namespace Ryujinx.Graphics.GAL void SetVertexAttribs(ReadOnlySpan vertexAttribs); void SetVertexBuffers(ReadOnlySpan vertexBuffers); - void SetViewports(ReadOnlySpan viewports, bool disableTransform); + void SetViewports(ReadOnlySpan viewports); void TextureBarrier(); void TextureBarrierTiled(); @@ -107,7 +106,5 @@ namespace Ryujinx.Graphics.GAL bool TryHostConditionalRendering(ICounterEvent value, ulong compare, bool isEqual); bool TryHostConditionalRendering(ICounterEvent value, ICounterEvent compare, bool isEqual); void EndHostConditionalRendering(); - - void UpdateRenderScale(ReadOnlySpan scales, int totalCount, int fragmentCount); } } diff --git a/src/Ryujinx.Graphics.GAL/IRenderer.cs b/src/Ryujinx.Graphics.GAL/IRenderer.cs index b668d56ec..1dabbdaef 100644 --- a/src/Ryujinx.Graphics.GAL/IRenderer.cs +++ b/src/Ryujinx.Graphics.GAL/IRenderer.cs @@ -17,7 +17,6 @@ namespace Ryujinx.Graphics.GAL void BackgroundContextAction(Action action, bool alwaysBackground = false); BufferHandle CreateBuffer(int size, BufferHandle storageHint); - BufferHandle CreateBuffer(int size) { return CreateBuffer(size, BufferHandle.Null); @@ -28,7 +27,7 @@ namespace Ryujinx.Graphics.GAL IProgram CreateProgram(ShaderSource[] shaders, ShaderInfo info); ISampler CreateSampler(SamplerCreateInfo info); - ITexture CreateTexture(TextureCreateInfo info, float scale); + ITexture CreateTexture(TextureCreateInfo info); bool PrepareHostMapping(nint address, ulong size); void CreateSync(ulong id, bool strict); @@ -49,7 +48,7 @@ namespace Ryujinx.Graphics.GAL void PreFrame(); - ICounterEvent ReportCounter(CounterType type, EventHandler resultHandler, bool hostReserved); + ICounterEvent ReportCounter(CounterType type, EventHandler resultHandler, float divisor, bool hostReserved); void ResetCounter(CounterType type); diff --git a/src/Ryujinx.Graphics.GAL/ITexture.cs b/src/Ryujinx.Graphics.GAL/ITexture.cs index d39b59499..5a4623a66 100644 --- a/src/Ryujinx.Graphics.GAL/ITexture.cs +++ b/src/Ryujinx.Graphics.GAL/ITexture.cs @@ -6,7 +6,6 @@ namespace Ryujinx.Graphics.GAL { int Width { get; } int Height { get; } - float ScaleFactor { get; } void CopyTo(ITexture destination, int firstLayer, int firstLevel); void CopyTo(ITexture destination, int srcLayer, int dstLayer, int srcLevel, int dstLevel); diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/CommandHelper.cs b/src/Ryujinx.Graphics.GAL/Multithreading/CommandHelper.cs index 12c5245a5..6cd6f1599 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/CommandHelper.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/CommandHelper.cs @@ -125,7 +125,6 @@ namespace Ryujinx.Graphics.GAL.Multithreading Register(CommandType.SetProgram); Register(CommandType.SetRasterizerDiscard); Register(CommandType.SetRenderTargetColorMasks); - Register(CommandType.SetRenderTargetScale); Register(CommandType.SetRenderTargets); Register(CommandType.SetScissor); Register(CommandType.SetStencilTest); @@ -138,7 +137,6 @@ namespace Ryujinx.Graphics.GAL.Multithreading Register(CommandType.TextureBarrierTiled); Register(CommandType.TryHostConditionalRendering); Register(CommandType.TryHostConditionalRenderingFlush); - Register(CommandType.UpdateRenderScale); return maxCommandSize; } diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/CommandType.cs b/src/Ryujinx.Graphics.GAL/Multithreading/CommandType.cs index 1e73fba62..c24a934aa 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/CommandType.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/CommandType.cs @@ -87,7 +87,6 @@ SetProgram, SetRasterizerDiscard, SetRenderTargetColorMasks, - SetRenderTargetScale, SetRenderTargets, SetScissor, SetStencilTest, @@ -100,6 +99,5 @@ TextureBarrierTiled, TryHostConditionalRendering, TryHostConditionalRenderingFlush, - UpdateRenderScale, } } diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateTextureCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateTextureCommand.cs index f52db30ae..6ec0daae8 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateTextureCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/CreateTextureCommand.cs @@ -8,18 +8,16 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer public readonly CommandType CommandType => CommandType.CreateTexture; private TableRef _texture; private TextureCreateInfo _info; - private float _scale; - public void Set(TableRef texture, TextureCreateInfo info, float scale) + public void Set(TableRef texture, TextureCreateInfo info) { _texture = texture; _info = info; - _scale = scale; } public static void Run(ref CreateTextureCommand command, ThreadedRenderer threaded, IRenderer renderer) { - command._texture.Get(threaded).Base = renderer.CreateTexture(command._info, command._scale); + command._texture.Get(threaded).Base = renderer.CreateTexture(command._info); } } } diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/ReportCounterCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/ReportCounterCommand.cs index 2a373f5b7..659cf4753 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/ReportCounterCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/Renderer/ReportCounterCommand.cs @@ -10,13 +10,15 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer private TableRef _event; private CounterType _type; private TableRef> _resultHandler; + private float _divisor; private bool _hostReserved; - public void Set(TableRef evt, CounterType type, TableRef> resultHandler, bool hostReserved) + public void Set(TableRef evt, CounterType type, TableRef> resultHandler, float divisor, bool hostReserved) { _event = evt; _type = type; _resultHandler = resultHandler; + _divisor = divisor; _hostReserved = hostReserved; } @@ -24,7 +26,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer { ThreadedCounterEvent evt = command._event.Get(threaded); - evt.Create(renderer, command._type, command._resultHandler.Get(threaded), command._hostReserved); + evt.Create(renderer, command._type, command._resultHandler.Get(threaded), command._divisor, command._hostReserved); } } } diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetRenderTargetScaleCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetRenderTargetScaleCommand.cs deleted file mode 100644 index 7207fd9da..000000000 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetRenderTargetScaleCommand.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Ryujinx.Graphics.GAL.Multithreading.Commands -{ - struct SetRenderTargetScaleCommand : IGALCommand, IGALCommand - { - public readonly CommandType CommandType => CommandType.SetRenderTargetScale; - private float _scale; - - public void Set(float scale) - { - _scale = scale; - } - - public static void Run(ref SetRenderTargetScaleCommand command, ThreadedRenderer threaded, IRenderer renderer) - { - renderer.Pipeline.SetRenderTargetScale(command._scale); - } - } -} diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetViewportsCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetViewportsCommand.cs index a0ad026a0..4ad264780 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetViewportsCommand.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/SetViewportsCommand.cs @@ -7,18 +7,16 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands { public readonly CommandType CommandType => CommandType.SetViewports; private SpanRef _viewports; - private bool _disableTransform; - public void Set(SpanRef viewports, bool disableTransform) + public void Set(SpanRef viewports) { _viewports = viewports; - _disableTransform = disableTransform; } public static void Run(ref SetViewportsCommand command, ThreadedRenderer threaded, IRenderer renderer) { ReadOnlySpan viewports = command._viewports.Get(threaded); - renderer.Pipeline.SetViewports(viewports, command._disableTransform); + renderer.Pipeline.SetViewports(viewports); command._viewports.Dispose(threaded); } } diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/UpdateRenderScaleCommand.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Commands/UpdateRenderScaleCommand.cs deleted file mode 100644 index c3c240455..000000000 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Commands/UpdateRenderScaleCommand.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Ryujinx.Graphics.GAL.Multithreading.Model; - -namespace Ryujinx.Graphics.GAL.Multithreading.Commands -{ - struct UpdateRenderScaleCommand : IGALCommand, IGALCommand - { - public readonly CommandType CommandType => CommandType.UpdateRenderScale; - private SpanRef _scales; - private int _totalCount; - private int _fragmentCount; - - public void Set(SpanRef scales, int totalCount, int fragmentCount) - { - _scales = scales; - _totalCount = totalCount; - _fragmentCount = fragmentCount; - } - - public static void Run(ref UpdateRenderScaleCommand command, ThreadedRenderer threaded, IRenderer renderer) - { - renderer.Pipeline.UpdateRenderScale(command._scales.Get(threaded), command._totalCount, command._fragmentCount); - command._scales.Dispose(threaded); - } - } -} diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedCounterEvent.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedCounterEvent.cs index e4e197ebf..2992b4a8c 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedCounterEvent.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedCounterEvent.cs @@ -70,10 +70,10 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Resources } } - public void Create(IRenderer renderer, CounterType type, System.EventHandler eventHandler, bool hostReserved) + public void Create(IRenderer renderer, CounterType type, System.EventHandler eventHandler, float divisor, bool hostReserved) { ThreadedHelpers.SpinUntilExchange(ref _createLock, 1, 0); - Base = renderer.ReportCounter(type, eventHandler, hostReserved || _reserved); + Base = renderer.ReportCounter(type, eventHandler, divisor, hostReserved || _reserved); Volatile.Write(ref _createLock, 0); } } diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedTexture.cs b/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedTexture.cs index b82e286ad..68f258539 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedTexture.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/Resources/ThreadedTexture.cs @@ -17,13 +17,10 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Resources public int Height => _info.Height; - public float ScaleFactor { get; } - - public ThreadedTexture(ThreadedRenderer renderer, TextureCreateInfo info, float scale) + public ThreadedTexture(ThreadedRenderer renderer, TextureCreateInfo info) { _renderer = renderer; _info = info; - ScaleFactor = scale; } private TableRef Ref(T reference) @@ -64,7 +61,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Resources public ITexture CreateView(TextureCreateInfo info, int firstLayer, int firstLevel) { - ThreadedTexture newTex = new(_renderer, info, ScaleFactor); + ThreadedTexture newTex = new(_renderer, info); _renderer.New().Set(Ref(this), Ref(newTex), info, firstLayer, firstLevel); _renderer.QueueCommand(); diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs b/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs index de6ba18d5..69c67d642 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs @@ -261,12 +261,6 @@ namespace Ryujinx.Graphics.GAL.Multithreading _renderer.QueueCommand(); } - public void SetRenderTargetScale(float scale) - { - _renderer.New().Set(scale); - _renderer.QueueCommand(); - } - public void SetScissors(ReadOnlySpan> scissors) { _renderer.New().Set(_renderer.CopySpan(scissors)); @@ -321,9 +315,9 @@ namespace Ryujinx.Graphics.GAL.Multithreading _renderer.QueueCommand(); } - public void SetViewports(ReadOnlySpan viewports, bool disableTransform) + public void SetViewports(ReadOnlySpan viewports) { - _renderer.New().Set(_renderer.CopySpan(viewports), disableTransform); + _renderer.New().Set(_renderer.CopySpan(viewports)); _renderer.QueueCommand(); } @@ -368,11 +362,5 @@ namespace Ryujinx.Graphics.GAL.Multithreading _renderer.QueueCommand(); return false; } - - public void UpdateRenderScale(ReadOnlySpan scales, int totalCount, int fragmentCount) - { - _renderer.New().Set(_renderer.CopySpan(scales[..totalCount]), totalCount, fragmentCount); - _renderer.QueueCommand(); - } } } diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedRenderer.cs b/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedRenderer.cs index dc7aab36c..e59a3928b 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedRenderer.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedRenderer.cs @@ -320,21 +320,21 @@ namespace Ryujinx.Graphics.GAL.Multithreading QueueCommand(); } - public ITexture CreateTexture(TextureCreateInfo info, float scale) + public ITexture CreateTexture(TextureCreateInfo info) { if (IsGpuThread()) { - var texture = new ThreadedTexture(this, info, scale); - New().Set(Ref(texture), info, scale); + var texture = new ThreadedTexture(this, info); + New().Set(Ref(texture), info); QueueCommand(); return texture; } else { - var texture = new ThreadedTexture(this, info, scale) + var texture = new ThreadedTexture(this, info) { - Base = _baseRenderer.CreateTexture(info, scale), + Base = _baseRenderer.CreateTexture(info), }; return texture; @@ -410,10 +410,10 @@ namespace Ryujinx.Graphics.GAL.Multithreading QueueCommand(); } - public ICounterEvent ReportCounter(CounterType type, EventHandler resultHandler, bool hostReserved) + public ICounterEvent ReportCounter(CounterType type, EventHandler resultHandler, float divisor, bool hostReserved) { - ThreadedCounterEvent evt = new(this, type, _lastSampleCounterClear); - New().Set(Ref(evt), type, Ref(resultHandler), hostReserved); + ThreadedCounterEvent evt = new ThreadedCounterEvent(this, type, _lastSampleCounterClear); + New().Set(Ref(evt), type, Ref(resultHandler), divisor, hostReserved); QueueCommand(); if (type == CounterType.SamplesPassed) diff --git a/src/Ryujinx.Graphics.GAL/SupportBufferUpdater.cs b/src/Ryujinx.Graphics.GAL/SupportBufferUpdater.cs deleted file mode 100644 index 84936e547..000000000 --- a/src/Ryujinx.Graphics.GAL/SupportBufferUpdater.cs +++ /dev/null @@ -1,102 +0,0 @@ -using Ryujinx.Graphics.Shader; -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace Ryujinx.Graphics.GAL -{ - public class SupportBufferUpdater : IDisposable - { - public SupportBuffer Data; - public BufferHandle Handle; - - private readonly IRenderer _renderer; - private int _startOffset = -1; - private int _endOffset = -1; - - public SupportBufferUpdater(IRenderer renderer) - { - _renderer = renderer; - Handle = renderer.CreateBuffer(SupportBuffer.RequiredSize); - renderer.Pipeline.ClearBuffer(Handle, 0, SupportBuffer.RequiredSize, 0); - } - - private void MarkDirty(int startOffset, int byteSize) - { - int endOffset = startOffset + byteSize; - - if (_startOffset == -1) - { - _startOffset = startOffset; - _endOffset = endOffset; - } - else - { - if (startOffset < _startOffset) - { - _startOffset = startOffset; - } - - if (endOffset > _endOffset) - { - _endOffset = endOffset; - } - } - } - - public void UpdateFragmentRenderScaleCount(int count) - { - if (Data.FragmentRenderScaleCount.X != count) - { - Data.FragmentRenderScaleCount.X = count; - - MarkDirty(SupportBuffer.FragmentRenderScaleCountOffset, sizeof(int)); - } - } - - private void UpdateGenericField(int baseOffset, ReadOnlySpan data, Span target, int offset, int count) where T : unmanaged - { - data[..count].CopyTo(target[offset..]); - - int elemSize = Unsafe.SizeOf(); - - MarkDirty(baseOffset + offset * elemSize, count * elemSize); - } - - public void UpdateRenderScale(ReadOnlySpan> data, int offset, int count) - { - UpdateGenericField(SupportBuffer.GraphicsRenderScaleOffset, data, Data.RenderScale.AsSpan(), offset, count); - } - - public void UpdateFragmentIsBgra(ReadOnlySpan> data, int offset, int count) - { - UpdateGenericField(SupportBuffer.FragmentIsBgraOffset, data, Data.FragmentIsBgra.AsSpan(), offset, count); - } - - public void UpdateViewportInverse(Vector4 data) - { - Data.ViewportInverse = data; - - MarkDirty(SupportBuffer.ViewportInverseOffset, SupportBuffer.FieldSize); - } - - public void Commit() - { - if (_startOffset != -1) - { - ReadOnlySpan data = MemoryMarshal.Cast(MemoryMarshal.CreateSpan(ref Data, 1)); - - _renderer.SetBufferData(Handle, _startOffset, data[_startOffset.._endOffset]); - - _startOffset = -1; - _endOffset = -1; - } - } - - public void Dispose() - { - GC.SuppressFinalize(this); - _renderer.DeleteBuffer(Handle); - } - } -} diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Threed/SemaphoreUpdater.cs b/src/Ryujinx.Graphics.Gpu/Engine/Threed/SemaphoreUpdater.cs index 0a813ee55..247752caf 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Threed/SemaphoreUpdater.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Threed/SemaphoreUpdater.cs @@ -177,13 +177,15 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed resultHandler(null, (ulong)_state.State.SemaphorePayload); break; case ReportCounterType.SamplesPassed: - counter = _context.Renderer.ReportCounter(CounterType.SamplesPassed, resultHandler, false); + float scale = _channel.TextureManager.RenderTargetScale; + float divisor = scale * scale; + counter = _context.Renderer.ReportCounter(CounterType.SamplesPassed, resultHandler, divisor, false); break; case ReportCounterType.PrimitivesGenerated: - counter = _context.Renderer.ReportCounter(CounterType.PrimitivesGenerated, resultHandler, false); + counter = _context.Renderer.ReportCounter(CounterType.PrimitivesGenerated, resultHandler, 1f, false); break; case ReportCounterType.TransformFeedbackPrimitivesWritten: - counter = _context.Renderer.ReportCounter(CounterType.TransformFeedbackPrimitivesWritten, resultHandler, false); + counter = _context.Renderer.ReportCounter(CounterType.TransformFeedbackPrimitivesWritten, resultHandler, 1f, false); break; } diff --git a/src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs b/src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs index 34439657e..b4f56245e 100644 --- a/src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs +++ b/src/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs @@ -495,6 +495,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed { clipRegionHeight = color.Height / samplesInY; } + + if (!_context.Capabilities.SupportsBgraFormat) + { + _context.SupportBufferUpdater.SetRenderTargetIsBgra(index, color.Format.IsBgr()); + } } } @@ -539,7 +544,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed if (oldScale != _channel.TextureManager.RenderTargetScale) { - _context.Renderer.Pipeline.SetRenderTargetScale(_channel.TextureManager.RenderTargetScale); + _context.SupportBufferUpdater.SetRenderTargetScale(_channel.TextureManager.RenderTargetScale); UpdateViewportTransform(); UpdateScissorState(); @@ -758,9 +763,15 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed } _context.Renderer.Pipeline.SetDepthMode(GetDepthMode()); - _context.Renderer.Pipeline.SetViewports(viewports, disableTransform); + _context.Renderer.Pipeline.SetViewports(viewports); - _currentSpecState.SetViewportTransformDisable(_state.State.ViewportTransformEnable == 0); + _context.SupportBufferUpdater.SetViewportTransformDisable( + viewports[0].Region.Width, + viewports[0].Region.Height, + _channel.TextureManager.RenderTargetScale, + disableTransform); + + _currentSpecState.SetViewportTransformDisable(disableTransform); _currentSpecState.SetDepthMode(GetDepthMode() == DepthMode.MinusOneToOne); } diff --git a/src/Ryujinx.Graphics.Gpu/GpuContext.cs b/src/Ryujinx.Graphics.Gpu/GpuContext.cs index a5fe8f4c1..a50852b05 100644 --- a/src/Ryujinx.Graphics.Gpu/GpuContext.cs +++ b/src/Ryujinx.Graphics.Gpu/GpuContext.cs @@ -85,6 +85,11 @@ namespace Ryujinx.Graphics.Gpu /// internal ConcurrentDictionary PhysicalMemoryRegistry { get; } + /// + /// Support buffer updater. + /// + internal SupportBufferUpdater SupportBufferUpdater { get; } + /// /// Host hardware capabilities. /// @@ -125,6 +130,8 @@ namespace Ryujinx.Graphics.Gpu PhysicalMemoryRegistry = new ConcurrentDictionary(); + SupportBufferUpdater = new SupportBufferUpdater(renderer); + _firstTimestamp = ConvertNanosecondsToTicks((ulong)PerformanceCounter.ElapsedNanoseconds); } @@ -399,6 +406,8 @@ namespace Ryujinx.Graphics.Gpu physicalMemory.Dispose(); } + SupportBufferUpdater.Dispose(); + PhysicalMemoryRegistry.Clear(); RunDeferredActions(); diff --git a/src/Ryujinx.Graphics.Gpu/Image/Texture.cs b/src/Ryujinx.Graphics.Gpu/Image/Texture.cs index c0d45cbd1..0fce4debb 100644 --- a/src/Ryujinx.Graphics.Gpu/Image/Texture.cs +++ b/src/Ryujinx.Graphics.Gpu/Image/Texture.cs @@ -278,7 +278,7 @@ namespace Ryujinx.Graphics.Gpu.Image Debug.Assert(!isView); TextureCreateInfo createInfo = TextureCache.GetCreateInfo(Info, _context.Capabilities, ScaleFactor); - HostTexture = _context.Renderer.CreateTexture(createInfo, ScaleFactor); + HostTexture = _context.Renderer.CreateTexture(createInfo); SynchronizeMemory(); // Load the data. if (ScaleMode == TextureScaleMode.Scaled) @@ -302,7 +302,7 @@ namespace Ryujinx.Graphics.Gpu.Image } TextureCreateInfo createInfo = TextureCache.GetCreateInfo(Info, _context.Capabilities, ScaleFactor); - HostTexture = _context.Renderer.CreateTexture(createInfo, ScaleFactor); + HostTexture = _context.Renderer.CreateTexture(createInfo); } } } @@ -490,7 +490,7 @@ namespace Ryujinx.Graphics.Gpu.Image if (storage == null) { TextureCreateInfo createInfo = TextureCache.GetCreateInfo(Info, _context.Capabilities, scale); - storage = _context.Renderer.CreateTexture(createInfo, scale); + storage = _context.Renderer.CreateTexture(createInfo); } if (copy) diff --git a/src/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs b/src/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs index e5df17760..d1454fc9a 100644 --- a/src/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs +++ b/src/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs @@ -302,7 +302,7 @@ namespace Ryujinx.Graphics.Gpu.Image _lastFragmentTotal = fragmentTotal; - _context.Renderer.Pipeline.UpdateRenderScale(_scales, total, fragmentTotal); + _context.SupportBufferUpdater.UpdateRenderScale(_scales, total, fragmentTotal); _scaleChanged = false; } diff --git a/src/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs b/src/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs index 4cd3710b9..10224a6d4 100644 --- a/src/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs +++ b/src/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs @@ -478,6 +478,8 @@ namespace Ryujinx.Graphics.Gpu.Memory // Force rebind after doing compute work. Rebind(); + + _context.SupportBufferUpdater.Commit(); } /// @@ -686,6 +688,8 @@ namespace Ryujinx.Graphics.Gpu.Memory CommitBufferTextureBindings(); _rebind = false; + + _context.SupportBufferUpdater.Commit(); } /// diff --git a/src/Ryujinx.Graphics.Gpu/Memory/SupportBufferUpdater.cs b/src/Ryujinx.Graphics.Gpu/Memory/SupportBufferUpdater.cs new file mode 100644 index 000000000..3ea37c55a --- /dev/null +++ b/src/Ryujinx.Graphics.Gpu/Memory/SupportBufferUpdater.cs @@ -0,0 +1,232 @@ +using Ryujinx.Graphics.GAL; +using Ryujinx.Graphics.Shader; +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace Ryujinx.Graphics.Gpu.Memory +{ + /// + /// Support buffer data updater. + /// + class SupportBufferUpdater : IDisposable + { + private SupportBuffer _data; + private BufferHandle _handle; + + private readonly IRenderer _renderer; + private int _startOffset = -1; + private int _endOffset = -1; + + /// + /// Creates a new instance of the support buffer updater. + /// + /// Renderer that the support buffer will be used with + public SupportBufferUpdater(IRenderer renderer) + { + _renderer = renderer; + + var defaultScale = new Vector4 { X = 1f, Y = 0f, Z = 0f, W = 0f }; + _data.RenderScale.AsSpan().Fill(defaultScale); + DirtyRenderScale(0, SupportBuffer.RenderScaleMaxCount); + } + + /// + /// Mark a region of the support buffer as modified and needing to be sent to the GPU. + /// + /// Start offset of the region in bytes + /// Size of the region in bytes + private void MarkDirty(int startOffset, int byteSize) + { + int endOffset = startOffset + byteSize; + + if (_startOffset == -1) + { + _startOffset = startOffset; + _endOffset = endOffset; + } + else + { + if (startOffset < _startOffset) + { + _startOffset = startOffset; + } + + if (endOffset > _endOffset) + { + _endOffset = endOffset; + } + } + } + + /// + /// Marks the fragment render scale count as being modified. + /// + private void DirtyFragmentRenderScaleCount() + { + MarkDirty(SupportBuffer.FragmentRenderScaleCountOffset, sizeof(int)); + } + + /// + /// Marks data of a given type as being modified. + /// + /// Type of the data + /// Base offset of the data in bytes + /// Index of the data, in elements + /// Number of elements + private void DirtyGenericField(int baseOffset, int offset, int count) where T : unmanaged + { + int elemSize = Unsafe.SizeOf(); + + MarkDirty(baseOffset + offset * elemSize, count * elemSize); + } + + /// + /// Marks render scales as being modified. + /// + /// Index of the first scale that was modified + /// Number of modified scales + private void DirtyRenderScale(int offset, int count) + { + DirtyGenericField>(SupportBuffer.GraphicsRenderScaleOffset, offset, count); + } + + /// + /// Marks render target BGRA format state as modified. + /// + /// Index of the first render target that had its BGRA format modified + /// Number of render targets + private void DirtyFragmentIsBgra(int offset, int count) + { + DirtyGenericField>(SupportBuffer.FragmentIsBgraOffset, offset, count); + } + + /// + /// Updates the inverse viewport vector. + /// + /// Inverse viewport vector + private void UpdateViewportInverse(Vector4 data) + { + _data.ViewportInverse = data; + + MarkDirty(SupportBuffer.ViewportInverseOffset, SupportBuffer.FieldSize); + } + + /// + /// Sets the scale of all output render targets (they should all have the same scale). + /// + /// Scale value + public void SetRenderTargetScale(float scale) + { + _data.RenderScale[0].X = scale; + DirtyRenderScale(0, 1); // Just the first element. + } + + /// + /// Updates the render scales for shader input textures or images. + /// + /// Scale values + /// Total number of scales across all stages + /// Total number of scales on the fragment shader stage + public void UpdateRenderScale(ReadOnlySpan scales, int totalCount, int fragmentCount) + { + bool changed = false; + + for (int index = 0; index < totalCount; index++) + { + if (_data.RenderScale[1 + index].X != scales[index]) + { + _data.RenderScale[1 + index].X = scales[index]; + changed = true; + } + } + + // Only update fragment count if there are scales after it for the vertex stage. + if (fragmentCount != totalCount && fragmentCount != _data.FragmentRenderScaleCount.X) + { + _data.FragmentRenderScaleCount.X = fragmentCount; + DirtyFragmentRenderScaleCount(); + } + + if (changed) + { + DirtyRenderScale(0, 1 + totalCount); + } + } + + /// + /// Sets whether the format of a given render target is a BGRA format. + /// + /// Render target index + /// True if the format is BGRA< false otherwise + public void SetRenderTargetIsBgra(int index, bool isBgra) + { + bool isBgraChanged = (_data.FragmentIsBgra[index].X != 0) != isBgra; + + if (isBgraChanged) + { + _data.FragmentIsBgra[index].X = isBgra ? 1 : 0; + DirtyFragmentIsBgra(index, 1); + } + } + + /// + /// Sets whether a viewport has transform disabled. + /// + /// Value used as viewport width + /// Value used as viewport height + /// Render target scale + /// True if transform is disabled, false otherwise + public void SetViewportTransformDisable(float viewportWidth, float viewportHeight, float scale, bool disableTransform) + { + float disableTransformF = disableTransform ? 1.0f : 0.0f; + if (_data.ViewportInverse.W != disableTransformF || disableTransform) + { + UpdateViewportInverse(new Vector4 + { + X = scale * 2f / viewportWidth, + Y = scale * 2f / viewportHeight, + Z = 1, + W = disableTransformF + }); + } + } + + /// + /// Submits all pending buffer updates to the GPU. + /// + public void Commit() + { + if (_startOffset != -1) + { + if (_handle == BufferHandle.Null) + { + _handle = _renderer.CreateBuffer(SupportBuffer.RequiredSize); + _renderer.Pipeline.ClearBuffer(_handle, 0, SupportBuffer.RequiredSize, 0); + + var range = new BufferRange(_handle, 0, SupportBuffer.RequiredSize); + _renderer.Pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, range) }); + } + + ReadOnlySpan data = MemoryMarshal.Cast(MemoryMarshal.CreateSpan(ref _data, 1)); + + _renderer.SetBufferData(_handle, _startOffset, data.Slice(_startOffset, _endOffset - _startOffset)); + + _startOffset = -1; + _endOffset = -1; + } + } + + /// + /// Destroys the support buffer. + /// + public void Dispose() + { + if (_handle != BufferHandle.Null) + { + _renderer.DeleteBuffer(_handle); + _handle = BufferHandle.Null; + } + } + } +} diff --git a/src/Ryujinx.Graphics.Gpu/Shader/ShaderInfoBuilder.cs b/src/Ryujinx.Graphics.Gpu/Shader/ShaderInfoBuilder.cs index 7356410ca..af1e1ee3f 100644 --- a/src/Ryujinx.Graphics.Gpu/Shader/ShaderInfoBuilder.cs +++ b/src/Ryujinx.Graphics.Gpu/Shader/ShaderInfoBuilder.cs @@ -58,6 +58,7 @@ namespace Ryujinx.Graphics.Gpu.Shader } AddDescriptor(SupportBufferStages, ResourceType.UniformBuffer, UniformSetIndex, 0, 1); + AddUsage(SupportBufferStages, ResourceType.UniformBuffer, ResourceAccess.Read, UniformSetIndex, 0, 1); _reservedConstantBuffers = 1; // For the support buffer. diff --git a/src/Ryujinx.Graphics.Gpu/Window.cs b/src/Ryujinx.Graphics.Gpu/Window.cs index 5da472b3e..89addc8a8 100644 --- a/src/Ryujinx.Graphics.Gpu/Window.cs +++ b/src/Ryujinx.Graphics.Gpu/Window.cs @@ -208,7 +208,16 @@ namespace Ryujinx.Graphics.Gpu texture.SynchronizeMemory(); - ImageCrop crop = pt.Crop; + ImageCrop crop = new ImageCrop( + (int)(pt.Crop.Left * texture.ScaleFactor), + (int)MathF.Ceiling(pt.Crop.Right * texture.ScaleFactor), + (int)(pt.Crop.Top * texture.ScaleFactor), + (int)MathF.Ceiling(pt.Crop.Bottom * texture.ScaleFactor), + pt.Crop.FlipX, + pt.Crop.FlipY, + pt.Crop.IsStretched, + pt.Crop.AspectRatioX, + pt.Crop.AspectRatioY); if (texture.Info.Width > pt.Info.Width || texture.Info.Height > pt.Info.Height) { diff --git a/src/Ryujinx.Graphics.OpenGL/Effects/FsrScalingFilter.cs b/src/Ryujinx.Graphics.OpenGL/Effects/FsrScalingFilter.cs index 5daaf8c45..1a130bebb 100644 --- a/src/Ryujinx.Graphics.OpenGL/Effects/FsrScalingFilter.cs +++ b/src/Ryujinx.Graphics.OpenGL/Effects/FsrScalingFilter.cs @@ -114,7 +114,7 @@ namespace Ryujinx.Graphics.OpenGL.Effects originalInfo.SwizzleB, originalInfo.SwizzleA); - _intermediaryTexture = new TextureStorage(_renderer, info, view.ScaleFactor); + _intermediaryTexture = new TextureStorage(_renderer, info); _intermediaryTexture.CreateDefaultView(); } diff --git a/src/Ryujinx.Graphics.OpenGL/Effects/FxaaPostProcessingEffect.cs b/src/Ryujinx.Graphics.OpenGL/Effects/FxaaPostProcessingEffect.cs index c8f170846..93654ac70 100644 --- a/src/Ryujinx.Graphics.OpenGL/Effects/FxaaPostProcessingEffect.cs +++ b/src/Ryujinx.Graphics.OpenGL/Effects/FxaaPostProcessingEffect.cs @@ -43,7 +43,7 @@ namespace Ryujinx.Graphics.OpenGL.Effects if (_textureStorage == null || _textureStorage.Info.Width != view.Width || _textureStorage.Info.Height != view.Height) { _textureStorage?.Dispose(); - _textureStorage = new TextureStorage(_renderer, view.Info, view.ScaleFactor); + _textureStorage = new TextureStorage(_renderer, view.Info); _textureStorage.CreateDefaultView(); } diff --git a/src/Ryujinx.Graphics.OpenGL/Effects/SmaaPostProcessingEffect.cs b/src/Ryujinx.Graphics.OpenGL/Effects/SmaaPostProcessingEffect.cs index eede852f7..b3f6cb1e5 100644 --- a/src/Ryujinx.Graphics.OpenGL/Effects/SmaaPostProcessingEffect.cs +++ b/src/Ryujinx.Graphics.OpenGL/Effects/SmaaPostProcessingEffect.cs @@ -147,8 +147,8 @@ namespace Ryujinx.Graphics.OpenGL.Effects.Smaa SwizzleComponent.Blue, SwizzleComponent.Alpha); - _areaTexture = new TextureStorage(_renderer, areaInfo, 1); - _searchTexture = new TextureStorage(_renderer, searchInfo, 1); + _areaTexture = new TextureStorage(_renderer, areaInfo); + _searchTexture = new TextureStorage(_renderer, searchInfo); var areaTexture = EmbeddedResources.Read("Ryujinx.Graphics.OpenGL/Effects/Textures/SmaaAreaTexture.bin"); var searchTexture = EmbeddedResources.Read("Ryujinx.Graphics.OpenGL/Effects/Textures/SmaaSearchTexture.bin"); @@ -165,11 +165,11 @@ namespace Ryujinx.Graphics.OpenGL.Effects.Smaa if (_outputTexture == null || _outputTexture.Info.Width != view.Width || _outputTexture.Info.Height != view.Height) { _outputTexture?.Dispose(); - _outputTexture = new TextureStorage(_renderer, view.Info, view.ScaleFactor); + _outputTexture = new TextureStorage(_renderer, view.Info); _outputTexture.CreateDefaultView(); - _edgeOutputTexture = new TextureStorage(_renderer, view.Info, view.ScaleFactor); + _edgeOutputTexture = new TextureStorage(_renderer, view.Info); _edgeOutputTexture.CreateDefaultView(); - _blendOutputTexture = new TextureStorage(_renderer, view.Info, view.ScaleFactor); + _blendOutputTexture = new TextureStorage(_renderer, view.Info); _blendOutputTexture.CreateDefaultView(); DeleteShaders(); diff --git a/src/Ryujinx.Graphics.OpenGL/Image/IntermmediatePool.cs b/src/Ryujinx.Graphics.OpenGL/Image/IntermmediatePool.cs index 1a08f973a..64ee73fbe 100644 --- a/src/Ryujinx.Graphics.OpenGL/Image/IntermmediatePool.cs +++ b/src/Ryujinx.Graphics.OpenGL/Image/IntermmediatePool.cs @@ -87,7 +87,7 @@ namespace Ryujinx.Graphics.OpenGL.Image SwizzleComponent.Red, SwizzleComponent.Green, SwizzleComponent.Blue, - SwizzleComponent.Alpha), 1f); + SwizzleComponent.Alpha)); } public void Dispose() diff --git a/src/Ryujinx.Graphics.OpenGL/Image/TextureBase.cs b/src/Ryujinx.Graphics.OpenGL/Image/TextureBase.cs index 2ab9dffbc..070a36b5e 100644 --- a/src/Ryujinx.Graphics.OpenGL/Image/TextureBase.cs +++ b/src/Ryujinx.Graphics.OpenGL/Image/TextureBase.cs @@ -11,15 +11,13 @@ namespace Ryujinx.Graphics.OpenGL.Image public int Width => Info.Width; public int Height => Info.Height; - public float ScaleFactor { get; } public Target Target => Info.Target; public Format Format => Info.Format; - public TextureBase(TextureCreateInfo info, float scaleFactor = 1f) + public TextureBase(TextureCreateInfo info) { Info = info; - ScaleFactor = scaleFactor; Handle = GL.GenTexture(); } diff --git a/src/Ryujinx.Graphics.OpenGL/Image/TextureCopy.cs b/src/Ryujinx.Graphics.OpenGL/Image/TextureCopy.cs index bb1911e8b..e33940cb1 100644 --- a/src/Ryujinx.Graphics.OpenGL/Image/TextureCopy.cs +++ b/src/Ryujinx.Graphics.OpenGL/Image/TextureCopy.cs @@ -349,7 +349,7 @@ namespace Ryujinx.Graphics.OpenGL.Image public TextureView BgraSwap(TextureView from) { - TextureView to = (TextureView)_renderer.CreateTexture(from.Info, from.ScaleFactor); + TextureView to = (TextureView)_renderer.CreateTexture(from.Info); EnsurePbo(from); diff --git a/src/Ryujinx.Graphics.OpenGL/Image/TextureStorage.cs b/src/Ryujinx.Graphics.OpenGL/Image/TextureStorage.cs index d714caf38..79c6cb685 100644 --- a/src/Ryujinx.Graphics.OpenGL/Image/TextureStorage.cs +++ b/src/Ryujinx.Graphics.OpenGL/Image/TextureStorage.cs @@ -8,7 +8,6 @@ namespace Ryujinx.Graphics.OpenGL.Image { public ITextureInfo Storage => this; public int Handle { get; private set; } - public float ScaleFactor { get; private set; } public TextureCreateInfo Info { get; } @@ -18,13 +17,12 @@ namespace Ryujinx.Graphics.OpenGL.Image internal ITexture DefaultView { get; private set; } - public TextureStorage(OpenGLRenderer renderer, TextureCreateInfo info, float scaleFactor) + public TextureStorage(OpenGLRenderer renderer, TextureCreateInfo info) { _renderer = renderer; Info = info; Handle = GL.GenTexture(); - ScaleFactor = scaleFactor; CreateImmutableStorage(); } diff --git a/src/Ryujinx.Graphics.OpenGL/Image/TextureView.cs b/src/Ryujinx.Graphics.OpenGL/Image/TextureView.cs index 21d8e449c..f4b1e0dad 100644 --- a/src/Ryujinx.Graphics.OpenGL/Image/TextureView.cs +++ b/src/Ryujinx.Graphics.OpenGL/Image/TextureView.cs @@ -23,7 +23,7 @@ namespace Ryujinx.Graphics.OpenGL.Image TextureStorage parent, TextureCreateInfo info, int firstLayer, - int firstLevel) : base(info, parent.ScaleFactor) + int firstLevel) : base(info) { _renderer = renderer; _parent = parent; diff --git a/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs b/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs index b4c567a81..1ad927ea6 100644 --- a/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs +++ b/src/Ryujinx.Graphics.OpenGL/OpenGLRenderer.cs @@ -95,7 +95,7 @@ namespace Ryujinx.Graphics.OpenGL return new Sampler(info); } - public ITexture CreateTexture(TextureCreateInfo info, float scaleFactor) + public ITexture CreateTexture(TextureCreateInfo info) { if (info.Target == Target.TextureBuffer) { @@ -103,7 +103,7 @@ namespace Ryujinx.Graphics.OpenGL } else { - return ResourcePool.GetTextureOrNull(info, scaleFactor) ?? new TextureStorage(this, info, scaleFactor).CreateDefaultView(); + return ResourcePool.GetTextureOrNull(info) ?? new TextureStorage(this, info).CreateDefaultView(); } } @@ -194,9 +194,9 @@ namespace Ryujinx.Graphics.OpenGL ResourcePool.Tick(); } - public ICounterEvent ReportCounter(CounterType type, EventHandler resultHandler, bool hostReserved) + public ICounterEvent ReportCounter(CounterType type, EventHandler resultHandler, float divisor, bool hostReserved) { - return _counters.QueueReport(type, resultHandler, _pipeline.DrawCount, hostReserved); + return _counters.QueueReport(type, resultHandler, divisor, _pipeline.DrawCount, hostReserved); } public void Initialize(GraphicsDebugLevel glLogLevel) @@ -210,7 +210,6 @@ namespace Ryujinx.Graphics.OpenGL GL.Arb.MaxShaderCompilerThreads(Math.Min(Environment.ProcessorCount, 8)); } - _pipeline.Initialize(this); _counters.Initialize(_pipeline); // This is required to disable [0, 1] clamping for SNorm outputs on compatibility profiles. diff --git a/src/Ryujinx.Graphics.OpenGL/Pipeline.cs b/src/Ryujinx.Graphics.OpenGL/Pipeline.cs index df618d5bc..85f5b1139 100644 --- a/src/Ryujinx.Graphics.OpenGL/Pipeline.cs +++ b/src/Ryujinx.Graphics.OpenGL/Pipeline.cs @@ -44,9 +44,7 @@ namespace Ryujinx.Graphics.OpenGL private CounterQueueEvent _activeConditionalRender; - private readonly Vector4[] _fpIsBgra = new Vector4[SupportBuffer.FragmentIsBgraCount]; - private readonly Vector4[] _renderScale = new Vector4[73]; - private int _fragmentScaleCount; + private Vector4[] _fpIsBgra = new Vector4[SupportBuffer.FragmentIsBgraCount]; private readonly (TextureBase, Format)[] _images; private TextureBase _unit0Texture; @@ -66,7 +64,6 @@ namespace Ryujinx.Graphics.OpenGL private bool _tfEnabled; private TransformFeedbackPrimitiveType _tfTopology; - private SupportBufferUpdater _supportBuffer; private readonly BufferHandle[] _tfbs; private readonly BufferRange[] _tfbTargets; @@ -84,22 +81,10 @@ namespace Ryujinx.Graphics.OpenGL _images = new (TextureBase, Format)[SavedImages]; - var defaultScale = new Vector4 { X = 1f, Y = 0f, Z = 0f, W = 0f }; - new Span>(_renderScale).Fill(defaultScale); - _tfbs = new BufferHandle[Constants.MaxTransformFeedbackBuffers]; _tfbTargets = new BufferRange[Constants.MaxTransformFeedbackBuffers]; } - public void Initialize(OpenGLRenderer renderer) - { - _supportBuffer = new SupportBufferUpdater(renderer); - GL.BindBufferBase(BufferRangeTarget.UniformBuffer, 0, Unsafe.As(ref _supportBuffer.Handle)); - - _supportBuffer.UpdateFragmentIsBgra(_fpIsBgra, 0, SupportBuffer.FragmentIsBgraCount); - _supportBuffer.UpdateRenderScale(_renderScale, 0, SupportBuffer.RenderScaleMaxCount); - } - public void Barrier() { GL.MemoryBarrier(MemoryBarrierFlags.AllBarrierBits); @@ -684,8 +669,6 @@ namespace Ryujinx.Graphics.OpenGL { if (texture is TextureView view && sampler is Sampler samp) { - _supportBuffer.Commit(); - if (HwCapabilities.SupportsDrawTexture) { GL.NV.DrawTexture( @@ -777,16 +760,6 @@ namespace Ryujinx.Graphics.OpenGL _tfEnabled = false; } - public double GetCounterDivisor(CounterType type) - { - if (type == CounterType.SamplesPassed) - { - return _renderScale[0].X * _renderScale[0].X; - } - - return 1; - } - public void SetAlphaTest(bool enable, float reference, CompareOp op) { if (!enable) @@ -1172,12 +1145,6 @@ namespace Ryujinx.Graphics.OpenGL _rasterizerDiscard = discard; } - public void SetRenderTargetScale(float scale) - { - _renderScale[0].X = scale; - _supportBuffer.UpdateRenderScale(_renderScale, 0, 1); // Just the first element. - } - public void SetRenderTargetColorMasks(ReadOnlySpan componentMasks) { _componentMasks = 0; @@ -1194,8 +1161,6 @@ namespace Ryujinx.Graphics.OpenGL { EnsureFramebuffer(); - bool isBgraChanged = false; - for (int index = 0; index < colors.Length; index++) { TextureView color = (TextureView)colors[index]; @@ -1209,18 +1174,12 @@ namespace Ryujinx.Graphics.OpenGL if (_fpIsBgra[index].X != isBgra) { _fpIsBgra[index].X = isBgra; - isBgraChanged = true; RestoreComponentMask(index); } } } - if (isBgraChanged) - { - _supportBuffer.UpdateFragmentIsBgra(_fpIsBgra, 0, SupportBuffer.FragmentIsBgraCount); - } - TextureView depthStencilView = (TextureView)depthStencil; _framebuffer.AttachDepthStencil(depthStencilView); @@ -1411,7 +1370,7 @@ namespace Ryujinx.Graphics.OpenGL _vertexArray.SetVertexBuffers(vertexBuffers); } - public void SetViewports(ReadOnlySpan viewports, bool disableTransform) + public void SetViewports(ReadOnlySpan viewports) { Array.Resize(ref _viewportArray, viewports.Length * 4); Array.Resize(ref _depthRangeArray, viewports.Length * 2); @@ -1450,19 +1409,6 @@ namespace Ryujinx.Graphics.OpenGL GL.ViewportArray(0, viewports.Length, viewportArray); GL.DepthRangeArray(0, viewports.Length, depthRangeArray); - - float disableTransformF = disableTransform ? 1.0f : 0.0f; - if (_supportBuffer.Data.ViewportInverse.W != disableTransformF || disableTransform) - { - float scale = _renderScale[0].X; - _supportBuffer.UpdateViewportInverse(new Vector4 - { - X = scale * 2f / viewports[0].Region.Width, - Y = scale * 2f / viewports[0].Region.Height, - Z = 1, - W = disableTransformF - }); - } } public void TextureBarrier() @@ -1552,36 +1498,9 @@ namespace Ryujinx.Graphics.OpenGL return (_boundDrawFramebuffer, _boundReadFramebuffer); } - public void UpdateRenderScale(ReadOnlySpan scales, int totalCount, int fragmentCount) - { - bool changed = false; - - for (int index = 0; index < totalCount; index++) - { - if (_renderScale[1 + index].X != scales[index]) - { - _renderScale[1 + index].X = scales[index]; - changed = true; - } - } - - // Only update fragment count if there are scales after it for the vertex stage. - if (fragmentCount != totalCount && fragmentCount != _fragmentScaleCount) - { - _fragmentScaleCount = fragmentCount; - _supportBuffer.UpdateFragmentRenderScaleCount(_fragmentScaleCount); - } - - if (changed) - { - _supportBuffer.UpdateRenderScale(_renderScale, 0, 1 + totalCount); - } - } - private void PrepareForDispatch() { _unit0Texture?.Bind(0); - _supportBuffer.Commit(); } private void PreDraw(int vertexCount) @@ -1601,7 +1520,6 @@ namespace Ryujinx.Graphics.OpenGL DrawCount++; _unit0Texture?.Bind(0); - _supportBuffer.Commit(); } private void PostDraw() @@ -1752,8 +1670,6 @@ namespace Ryujinx.Graphics.OpenGL public void Dispose() { - _supportBuffer?.Dispose(); - for (int i = 0; i < Constants.MaxTransformFeedbackBuffers; i++) { if (_tfbs[i] != BufferHandle.Null) diff --git a/src/Ryujinx.Graphics.OpenGL/Queries/CounterQueue.cs b/src/Ryujinx.Graphics.OpenGL/Queries/CounterQueue.cs index ff7e9a3ee..1724616ea 100644 --- a/src/Ryujinx.Graphics.OpenGL/Queries/CounterQueue.cs +++ b/src/Ryujinx.Graphics.OpenGL/Queries/CounterQueue.cs @@ -107,7 +107,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries } } - public CounterQueueEvent QueueReport(EventHandler resultHandler, ulong lastDrawIndex, bool hostReserved) + public CounterQueueEvent QueueReport(EventHandler resultHandler, float divisor, ulong lastDrawIndex, bool hostReserved) { CounterQueueEvent result; ulong draws = lastDrawIndex - _current.DrawIndex; @@ -123,7 +123,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries _current.ReserveForHostAccess(); } - _current.Complete(draws > 0, _pipeline.GetCounterDivisor(Type)); + _current.Complete(draws > 0, divisor); _events.Enqueue(_current); _current.OnResult += resultHandler; diff --git a/src/Ryujinx.Graphics.OpenGL/Queries/Counters.cs b/src/Ryujinx.Graphics.OpenGL/Queries/Counters.cs index 91554ebad..88e8bf917 100644 --- a/src/Ryujinx.Graphics.OpenGL/Queries/Counters.cs +++ b/src/Ryujinx.Graphics.OpenGL/Queries/Counters.cs @@ -23,9 +23,9 @@ namespace Ryujinx.Graphics.OpenGL.Queries } } - public CounterQueueEvent QueueReport(CounterType type, EventHandler resultHandler, ulong lastDrawIndex, bool hostReserved) + public CounterQueueEvent QueueReport(CounterType type, EventHandler resultHandler, float divisor, ulong lastDrawIndex, bool hostReserved) { - return _counterQueues[(int)type].QueueReport(resultHandler, lastDrawIndex, hostReserved); + return _counterQueues[(int)type].QueueReport(resultHandler, divisor, lastDrawIndex, hostReserved); } public void QueueReset(CounterType type) diff --git a/src/Ryujinx.Graphics.OpenGL/ResourcePool.cs b/src/Ryujinx.Graphics.OpenGL/ResourcePool.cs index bba5c5cb7..43410c99b 100644 --- a/src/Ryujinx.Graphics.OpenGL/ResourcePool.cs +++ b/src/Ryujinx.Graphics.OpenGL/ResourcePool.cs @@ -9,7 +9,6 @@ namespace Ryujinx.Graphics.OpenGL { public TextureCreateInfo Info; public TextureView View; - public float ScaleFactor; public int RemainingFrames; } @@ -42,7 +41,6 @@ namespace Ryujinx.Graphics.OpenGL { Info = view.Info, View = view, - ScaleFactor = view.ScaleFactor, RemainingFrames = DisposedLiveFrames }); } @@ -52,9 +50,8 @@ namespace Ryujinx.Graphics.OpenGL /// Attempt to obtain a texture from the resource cache with the desired parameters. /// /// The creation info for the desired texture - /// The scale factor for the desired texture /// A TextureView with the description specified, or null if one was not found. - public TextureView GetTextureOrNull(TextureCreateInfo info, float scaleFactor) + public TextureView GetTextureOrNull(TextureCreateInfo info) { lock (_lock) { @@ -65,11 +62,8 @@ namespace Ryujinx.Graphics.OpenGL foreach (DisposedTexture texture in list) { - if (scaleFactor == texture.ScaleFactor) - { - list.Remove(texture); - return texture.View; - } + list.Remove(texture); + return texture.View; } return null; diff --git a/src/Ryujinx.Graphics.OpenGL/Window.cs b/src/Ryujinx.Graphics.OpenGL/Window.cs index a928772fd..a8e6031b6 100644 --- a/src/Ryujinx.Graphics.OpenGL/Window.cs +++ b/src/Ryujinx.Graphics.OpenGL/Window.cs @@ -111,12 +111,11 @@ namespace Ryujinx.Graphics.OpenGL GL.Clear(ClearBufferMask.ColorBufferBit); int srcX0, srcX1, srcY0, srcY1; - float scale = viewConverted.ScaleFactor; if (crop.Left == 0 && crop.Right == 0) { srcX0 = 0; - srcX1 = (int)(viewConverted.Width / scale); + srcX1 = viewConverted.Width; } else { @@ -127,7 +126,7 @@ namespace Ryujinx.Graphics.OpenGL if (crop.Top == 0 && crop.Bottom == 0) { srcY0 = 0; - srcY1 = (int)(viewConverted.Height / scale); + srcY1 = viewConverted.Height; } else { @@ -135,14 +134,6 @@ namespace Ryujinx.Graphics.OpenGL srcY1 = crop.Bottom; } - if (scale != 1f) - { - srcX0 = (int)(srcX0 * scale); - srcY0 = (int)(srcY0 * scale); - srcX1 = (int)Math.Ceiling(srcX1 * scale); - srcY1 = (int)Math.Ceiling(srcY1 * scale); - } - float ratioX = crop.IsStretched ? 1.0f : MathF.Min(1.0f, _height * crop.AspectRatioX / (_width * crop.AspectRatioY)); float ratioY = crop.IsStretched ? 1.0f : MathF.Min(1.0f, _width * crop.AspectRatioY / (_height * crop.AspectRatioX)); @@ -408,7 +399,7 @@ namespace Ryujinx.Graphics.OpenGL SwizzleComponent.Alpha); _isBgra = forceBgra; - _upscaledTexture = _renderer.CreateTexture(info, 1) as TextureView; + _upscaledTexture = _renderer.CreateTexture(info) as TextureView; } public void SetScalingFilterLevel(float level) diff --git a/src/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs b/src/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs index 087d90fb8..894710911 100644 --- a/src/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs +++ b/src/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs @@ -35,7 +35,6 @@ namespace Ryujinx.Graphics.Vulkan private readonly bool[] _uniformSet; private readonly bool[] _storageSet; - private Buffer _cachedSupportBuffer; [Flags] private enum DirtyFlags @@ -115,7 +114,7 @@ namespace Ryujinx.Graphics.Vulkan SwizzleComponent.Red, SwizzleComponent.Green, SwizzleComponent.Blue, - SwizzleComponent.Alpha), 1f); + SwizzleComponent.Alpha)); _dummySampler = (SamplerHolder)gd.CreateSampler(new SamplerCreateInfo( MinFilter.Nearest, @@ -392,26 +391,6 @@ namespace Ryujinx.Graphics.Vulkan { Initialize(cbs, setIndex, dsc); } - - if (setIndex == PipelineBase.UniformSetIndex) - { - Span uniformBuffer = stackalloc DescriptorBufferInfo[1]; - - if (!_uniformSet[0]) - { - _cachedSupportBuffer = _gd.BufferManager.GetBuffer(cbs.CommandBuffer, _pipeline.SupportBufferUpdater.Handle, false).Get(cbs, 0, SupportBuffer.RequiredSize).Value; - _uniformSet[0] = true; - } - - uniformBuffer[0] = new DescriptorBufferInfo - { - Offset = 0, - Range = (ulong)SupportBuffer.RequiredSize, - Buffer = _cachedSupportBuffer, - }; - - dsc.UpdateBuffers(0, 0, uniformBuffer, DescriptorType.UniformBuffer); - } } foreach (ResourceBindingSegment segment in bindingSegments) @@ -553,22 +532,6 @@ namespace Ryujinx.Graphics.Vulkan [MethodImpl(MethodImplOptions.AggressiveInlining)] private void UpdateAndBindUniformBufferPd(CommandBufferScoped cbs, PipelineBindPoint pbp) { - if (!_uniformSet[0]) - { - Span uniformBuffer = stackalloc DescriptorBufferInfo[1]; - - uniformBuffer[0] = new DescriptorBufferInfo - { - Offset = 0, - Range = (ulong)SupportBuffer.RequiredSize, - Buffer = _gd.BufferManager.GetBuffer(cbs.CommandBuffer, _pipeline.SupportBufferUpdater.Handle, false).Get(cbs, 0, SupportBuffer.RequiredSize).Value, - }; - - _uniformSet[0] = true; - - UpdateBuffers(cbs, pbp, 0, uniformBuffer, DescriptorType.UniformBuffer); - } - var bindingSegments = _program.BindingSegments[PipelineBase.UniformSetIndex]; var dummyBuffer = _dummyBuffer?.GetBuffer(); diff --git a/src/Ryujinx.Graphics.Vulkan/Effects/FsrScalingFilter.cs b/src/Ryujinx.Graphics.Vulkan/Effects/FsrScalingFilter.cs index 89a43b12c..23acdcf8f 100644 --- a/src/Ryujinx.Graphics.Vulkan/Effects/FsrScalingFilter.cs +++ b/src/Ryujinx.Graphics.Vulkan/Effects/FsrScalingFilter.cs @@ -115,7 +115,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects originalInfo.SwizzleB, originalInfo.SwizzleA); _intermediaryTexture?.Dispose(); - _intermediaryTexture = _renderer.CreateTexture(info, view.ScaleFactor) as TextureView; + _intermediaryTexture = _renderer.CreateTexture(info) as TextureView; } _pipeline.SetCommandBuffer(cbs); diff --git a/src/Ryujinx.Graphics.Vulkan/Effects/FxaaPostProcessingEffect.cs b/src/Ryujinx.Graphics.Vulkan/Effects/FxaaPostProcessingEffect.cs index 2dd991802..7729934f2 100644 --- a/src/Ryujinx.Graphics.Vulkan/Effects/FxaaPostProcessingEffect.cs +++ b/src/Ryujinx.Graphics.Vulkan/Effects/FxaaPostProcessingEffect.cs @@ -57,7 +57,7 @@ namespace Ryujinx.Graphics.Vulkan.Effects if (_texture == null || _texture.Width != view.Width || _texture.Height != view.Height) { _texture?.Dispose(); - _texture = _renderer.CreateTexture(view.Info, view.ScaleFactor) as TextureView; + _texture = _renderer.CreateTexture(view.Info) as TextureView; } _pipeline.SetCommandBuffer(cbs); diff --git a/src/Ryujinx.Graphics.Vulkan/Effects/SmaaPostProcessingEffect.cs b/src/Ryujinx.Graphics.Vulkan/Effects/SmaaPostProcessingEffect.cs index 40ab245ee..c521f2273 100644 --- a/src/Ryujinx.Graphics.Vulkan/Effects/SmaaPostProcessingEffect.cs +++ b/src/Ryujinx.Graphics.Vulkan/Effects/SmaaPostProcessingEffect.cs @@ -177,8 +177,8 @@ namespace Ryujinx.Graphics.Vulkan.Effects var areaTexture = EmbeddedResources.Read("Ryujinx.Graphics.Vulkan/Effects/Textures/SmaaAreaTexture.bin"); var searchTexture = EmbeddedResources.Read("Ryujinx.Graphics.Vulkan/Effects/Textures/SmaaSearchTexture.bin"); - _areaTexture = _renderer.CreateTexture(areaInfo, 1) as TextureView; - _searchTexture = _renderer.CreateTexture(searchInfo, 1) as TextureView; + _areaTexture = _renderer.CreateTexture(areaInfo) as TextureView; + _searchTexture = _renderer.CreateTexture(searchInfo) as TextureView; _areaTexture.SetData(areaTexture); _searchTexture.SetData(searchTexture); @@ -193,9 +193,9 @@ namespace Ryujinx.Graphics.Vulkan.Effects _edgeOutputTexture?.Dispose(); _blendOutputTexture?.Dispose(); - _outputTexture = _renderer.CreateTexture(view.Info, view.ScaleFactor) as TextureView; - _edgeOutputTexture = _renderer.CreateTexture(view.Info, view.ScaleFactor) as TextureView; - _blendOutputTexture = _renderer.CreateTexture(view.Info, view.ScaleFactor) as TextureView; + _outputTexture = _renderer.CreateTexture(view.Info) as TextureView; + _edgeOutputTexture = _renderer.CreateTexture(view.Info) as TextureView; + _blendOutputTexture = _renderer.CreateTexture(view.Info) as TextureView; } _pipeline.SetCommandBuffer(cbs); diff --git a/src/Ryujinx.Graphics.Vulkan/HelperShader.cs b/src/Ryujinx.Graphics.Vulkan/HelperShader.cs index 648afcd6a..b19a4f704 100644 --- a/src/Ryujinx.Graphics.Vulkan/HelperShader.cs +++ b/src/Ryujinx.Graphics.Vulkan/HelperShader.cs @@ -470,7 +470,7 @@ namespace Ryujinx.Graphics.Vulkan _pipeline.ClearRenderTargetColor(0, 0, 1, new ColorF(0f, 0f, 0f, 1f)); } - _pipeline.SetViewports(viewports, false); + _pipeline.SetViewports(viewports); _pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip); _pipeline.Draw(4, 1, 0, 0); @@ -546,7 +546,7 @@ namespace Ryujinx.Graphics.Vulkan _pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight, (uint)dstSamples, true, dstFormat); _pipeline.SetScissors(scissors); - _pipeline.SetViewports(viewports, false); + _pipeline.SetViewports(viewports); _pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip); var aspectFlags = src.Info.Format.ConvertAspectFlags(); @@ -710,7 +710,7 @@ namespace Ryujinx.Graphics.Vulkan _pipeline.SetProgram(program); _pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight, false, dstFormat); _pipeline.SetRenderTargetColorMasks(new[] { componentMask }); - _pipeline.SetViewports(viewports, false); + _pipeline.SetViewports(viewports); _pipeline.SetScissors(scissors); _pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip); _pipeline.Draw(4, 1, 0, 0); @@ -774,7 +774,7 @@ namespace Ryujinx.Graphics.Vulkan Span> scissors = stackalloc Rectangle[1]; pipeline.SetProgram(_programColorBlit); - pipeline.SetViewports(viewports, false); + pipeline.SetViewports(viewports); pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip); pipeline.Draw(4, 1, 0, 0); @@ -1117,7 +1117,7 @@ namespace Ryujinx.Graphics.Vulkan scissors[0] = new Rectangle(0, 0, dst.Width, dst.Height); _pipeline.SetScissors(scissors); - _pipeline.SetViewports(viewports, false); + _pipeline.SetViewports(viewports); _pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip); for (int z = 0; z < depth; z++) @@ -1250,7 +1250,7 @@ namespace Ryujinx.Graphics.Vulkan _pipeline.SetRenderTargetColorMasks(new uint[] { 0xf }); _pipeline.SetScissors(scissors); - _pipeline.SetViewports(viewports, false); + _pipeline.SetViewports(viewports); _pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip); _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, new BufferRange(bufferHandle, 0, ParamsBufferSize)) }); diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs index 7f175d93c..b76e482b5 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs @@ -50,9 +50,6 @@ namespace Ryujinx.Graphics.Vulkan private ShaderCollection _program; - private readonly Vector4[] _renderScale = new Vector4[73]; - private int _fragmentScaleCount; - protected FramebufferParams FramebufferParams; private Auto _framebuffer; private Auto _renderPass; @@ -74,7 +71,6 @@ namespace Ryujinx.Graphics.Vulkan private readonly VertexBufferUpdater _vertexBufferUpdater; - public SupportBufferUpdater SupportBufferUpdater; public IndexBufferPattern QuadsToTrisPattern; public IndexBufferPattern TriFanToTrisPattern; @@ -119,9 +115,6 @@ namespace Ryujinx.Graphics.Vulkan ClearScissor = new Rectangle(0, 0, 0xffff, 0xffff); - var defaultScale = new Vector4 { X = 1f, Y = 0f, Z = 0f, W = 0f }; - new Span>(_renderScale).Fill(defaultScale); - _storedBlend = new PipelineColorBlendAttachmentState[Constants.MaxRenderTargets]; _newState.Initialize(); @@ -131,9 +124,6 @@ namespace Ryujinx.Graphics.Vulkan { _descriptorSetUpdater.Initialize(); - SupportBufferUpdater = new SupportBufferUpdater(Gd); - SupportBufferUpdater.UpdateRenderScale(_renderScale, 0, SupportBuffer.RenderScaleMaxCount); - QuadsToTrisPattern = new IndexBufferPattern(Gd, 4, 6, 0, new[] { 0, 1, 2, 0, 2, 3 }, 4, false); TriFanToTrisPattern = new IndexBufferPattern(Gd, 3, 3, 2, new[] { int.MinValue, -1, 0 }, 1, true); } @@ -666,8 +656,6 @@ namespace Ryujinx.Graphics.Vulkan { if (texture is TextureView srcTexture) { - SupportBufferUpdater.Commit(); - var oldCullMode = _newState.CullMode; var oldStencilTestEnable = _newState.StencilTestEnable; var oldDepthTestEnable = _newState.DepthTestEnable; @@ -709,16 +697,6 @@ namespace Ryujinx.Graphics.Vulkan _tfEnabled = false; } - public double GetCounterDivisor(CounterType type) - { - if (type == CounterType.SamplesPassed) - { - return _renderScale[0].X * _renderScale[0].X; - } - - return 1; - } - public bool IsCommandBufferActive(CommandBuffer cb) { return CommandBuffer.Handle == cb.Handle; @@ -1050,12 +1028,6 @@ namespace Ryujinx.Graphics.Vulkan SetRenderTargetsInternal(colors, depthStencil, Gd.IsTBDR); } - public void SetRenderTargetScale(float scale) - { - _renderScale[0].X = scale; - SupportBufferUpdater.UpdateRenderScale(_renderScale, 0, 1); // Just the first element. - } - public void SetScissors(ReadOnlySpan> regions) { int maxScissors = Gd.Capabilities.SupportsMultiView ? Constants.MaxViewports : 1; @@ -1303,7 +1275,7 @@ namespace Ryujinx.Graphics.Vulkan SignalStateChange(); } - public void SetViewports(ReadOnlySpan viewports, bool disableTransform) + public void SetViewports(ReadOnlySpan viewports) { int maxViewports = Gd.Capabilities.SupportsMultiView ? Constants.MaxViewports : 1; int count = Math.Min(maxViewports, viewports.Length); @@ -1328,19 +1300,6 @@ namespace Ryujinx.Graphics.Vulkan Clamp(viewport.DepthFar))); } - float disableTransformF = disableTransform ? 1.0f : 0.0f; - if (SupportBufferUpdater.Data.ViewportInverse.W != disableTransformF || disableTransform) - { - float scale = _renderScale[0].X; - SupportBufferUpdater.UpdateViewportInverse(new Vector4 - { - X = scale * 2f / viewports[0].Region.Width, - Y = scale * 2f / viewports[0].Region.Height, - Z = 1, - W = disableTransformF, - }); - } - _newState.ViewportsCount = (uint)count; SignalStateChange(); } @@ -1391,32 +1350,6 @@ namespace Ryujinx.Graphics.Vulkan TextureBarrier(); } - public void UpdateRenderScale(ReadOnlySpan scales, int totalCount, int fragmentCount) - { - bool changed = false; - - for (int index = 0; index < totalCount; index++) - { - if (_renderScale[1 + index].X != scales[index]) - { - _renderScale[1 + index].X = scales[index]; - changed = true; - } - } - - // Only update fragment count if there are scales after it for the vertex stage. - if (fragmentCount != totalCount && fragmentCount != _fragmentScaleCount) - { - _fragmentScaleCount = fragmentCount; - SupportBufferUpdater.UpdateFragmentRenderScaleCount(_fragmentScaleCount); - } - - if (changed) - { - SupportBufferUpdater.UpdateRenderScale(_renderScale, 0, 1 + totalCount); - } - } - protected void SignalCommandBufferChange() { _needsIndexBufferRebind = true; @@ -1614,9 +1547,6 @@ namespace Ryujinx.Graphics.Vulkan DynamicState.ReplayIfDirty(Gd.Api, CommandBuffer); - // Commit changes to the support buffer before drawing. - SupportBufferUpdater.Commit(); - if (_needsIndexBufferRebind && _indexBufferPattern == null) { _indexBuffer.BindIndexBuffer(Gd, Cbs); @@ -1777,8 +1707,6 @@ namespace Ryujinx.Graphics.Vulkan { Gd.Api.DestroyPipelineCache(Device, PipelineCache, null); } - - SupportBufferUpdater.Dispose(); } } diff --git a/src/Ryujinx.Graphics.Vulkan/Queries/CounterQueue.cs b/src/Ryujinx.Graphics.Vulkan/Queries/CounterQueue.cs index 724588d57..9c450cb78 100644 --- a/src/Ryujinx.Graphics.Vulkan/Queries/CounterQueue.cs +++ b/src/Ryujinx.Graphics.Vulkan/Queries/CounterQueue.cs @@ -130,7 +130,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries } } - public CounterQueueEvent QueueReport(EventHandler resultHandler, ulong lastDrawIndex, bool hostReserved) + public CounterQueueEvent QueueReport(EventHandler resultHandler, float divisor, ulong lastDrawIndex, bool hostReserved) { CounterQueueEvent result; ulong draws = lastDrawIndex - _current.DrawIndex; @@ -146,7 +146,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries _current.ReserveForHostAccess(); } - _current.Complete(draws > 0 && Type != CounterType.TransformFeedbackPrimitivesWritten, _pipeline.GetCounterDivisor(Type)); + _current.Complete(draws > 0 && Type != CounterType.TransformFeedbackPrimitivesWritten, divisor); _events.Enqueue(_current); _current.OnResult += resultHandler; diff --git a/src/Ryujinx.Graphics.Vulkan/Queries/Counters.cs b/src/Ryujinx.Graphics.Vulkan/Queries/Counters.cs index d9d65062f..518ede5f3 100644 --- a/src/Ryujinx.Graphics.Vulkan/Queries/Counters.cs +++ b/src/Ryujinx.Graphics.Vulkan/Queries/Counters.cs @@ -37,9 +37,9 @@ namespace Ryujinx.Graphics.Vulkan.Queries _counterQueues[(int)CounterType.SamplesPassed].ResetFutureCounters(cmd, count); } - public CounterQueueEvent QueueReport(CounterType type, EventHandler resultHandler, bool hostReserved) + public CounterQueueEvent QueueReport(CounterType type, EventHandler resultHandler, float divisor, bool hostReserved) { - return _counterQueues[(int)type].QueueReport(resultHandler, _pipeline.DrawCount, hostReserved); + return _counterQueues[(int)type].QueueReport(resultHandler, divisor, _pipeline.DrawCount, hostReserved); } public void QueueReset(CounterType type) diff --git a/src/Ryujinx.Graphics.Vulkan/TextureBuffer.cs b/src/Ryujinx.Graphics.Vulkan/TextureBuffer.cs index e7d24a007..ddcf51f69 100644 --- a/src/Ryujinx.Graphics.Vulkan/TextureBuffer.cs +++ b/src/Ryujinx.Graphics.Vulkan/TextureBuffer.cs @@ -25,15 +25,12 @@ namespace Ryujinx.Graphics.Vulkan public VkFormat VkFormat { get; } - public float ScaleFactor { get; } - - public TextureBuffer(VulkanRenderer gd, TextureCreateInfo info, float scale) + public TextureBuffer(VulkanRenderer gd, TextureCreateInfo info) { _gd = gd; Width = info.Width; Height = info.Height; VkFormat = FormatTable.GetFormat(info.Format); - ScaleFactor = scale; gd.Textures.Add(this); } diff --git a/src/Ryujinx.Graphics.Vulkan/TextureStorage.cs b/src/Ryujinx.Graphics.Vulkan/TextureStorage.cs index 2a51c132a..5ecd99073 100644 --- a/src/Ryujinx.Graphics.Vulkan/TextureStorage.cs +++ b/src/Ryujinx.Graphics.Vulkan/TextureStorage.cs @@ -54,19 +54,16 @@ namespace Ryujinx.Graphics.Vulkan private readonly ulong _size; public VkFormat VkFormat { get; } - public float ScaleFactor { get; } public unsafe TextureStorage( VulkanRenderer gd, Device device, TextureCreateInfo info, - float scaleFactor, Auto foreignAllocation = null) { _gd = gd; _device = device; _info = info; - ScaleFactor = scaleFactor; var format = _gd.FormatCapabilities.ConvertToVkFormat(info.Format); var levels = (uint)info.Levels; @@ -175,7 +172,7 @@ namespace Ryujinx.Graphics.Vulkan var info = NewCreateInfoWith(ref _info, format, _info.BytesPerPixel); - storage = new TextureStorage(_gd, _device, info, ScaleFactor, _allocationAuto); + storage = new TextureStorage(_gd, _device, info, _allocationAuto); _aliasedStorages.Add(format, storage); } diff --git a/src/Ryujinx.Graphics.Vulkan/TextureView.cs b/src/Ryujinx.Graphics.Vulkan/TextureView.cs index 6151d5a9e..bb14ea611 100644 --- a/src/Ryujinx.Graphics.Vulkan/TextureView.cs +++ b/src/Ryujinx.Graphics.Vulkan/TextureView.cs @@ -32,7 +32,6 @@ namespace Ryujinx.Graphics.Vulkan public int Layers => Info.GetDepthOrLayers(); public int FirstLayer { get; } public int FirstLevel { get; } - public float ScaleFactor => Storage.ScaleFactor; public VkFormat VkFormat { get; } public bool Valid { get; private set; } diff --git a/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs b/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs index b9b1ba911..11c3bfe4e 100644 --- a/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs +++ b/src/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs @@ -432,26 +432,26 @@ namespace Ryujinx.Graphics.Vulkan return new SamplerHolder(this, _device, info); } - public ITexture CreateTexture(TextureCreateInfo info, float scale) + public ITexture CreateTexture(TextureCreateInfo info) { if (info.Target == Target.TextureBuffer) { - return new TextureBuffer(this, info, scale); + return new TextureBuffer(this, info); } - return CreateTextureView(info, scale); + return CreateTextureView(info); } - internal TextureView CreateTextureView(TextureCreateInfo info, float scale) + internal TextureView CreateTextureView(TextureCreateInfo info) { // This should be disposed when all views are destroyed. - var storage = CreateTextureStorage(info, scale); + var storage = CreateTextureStorage(info); return storage.CreateView(info, 0, 0); } - internal TextureStorage CreateTextureStorage(TextureCreateInfo info, float scale) + internal TextureStorage CreateTextureStorage(TextureCreateInfo info) { - return new TextureStorage(this, _device, info, scale); + return new TextureStorage(this, _device, info); } public void DeleteBuffer(BufferHandle buffer) @@ -753,9 +753,9 @@ namespace Ryujinx.Graphics.Vulkan SyncManager.Cleanup(); } - public ICounterEvent ReportCounter(CounterType type, EventHandler resultHandler, bool hostReserved) + public ICounterEvent ReportCounter(CounterType type, EventHandler resultHandler, float divisor, bool hostReserved) { - return _counters.QueueReport(type, resultHandler, hostReserved); + return _counters.QueueReport(type, resultHandler, divisor, hostReserved); } public void ResetCounter(CounterType type) diff --git a/src/Ryujinx.Graphics.Vulkan/Window.cs b/src/Ryujinx.Graphics.Vulkan/Window.cs index 0a41e98df..6027962cf 100644 --- a/src/Ryujinx.Graphics.Vulkan/Window.cs +++ b/src/Ryujinx.Graphics.Vulkan/Window.cs @@ -294,12 +294,11 @@ namespace Ryujinx.Graphics.Vulkan } int srcX0, srcX1, srcY0, srcY1; - float scale = view.ScaleFactor; if (crop.Left == 0 && crop.Right == 0) { srcX0 = 0; - srcX1 = (int)(view.Width / scale); + srcX1 = view.Width; } else { @@ -310,7 +309,7 @@ namespace Ryujinx.Graphics.Vulkan if (crop.Top == 0 && crop.Bottom == 0) { srcY0 = 0; - srcY1 = (int)(view.Height / scale); + srcY1 = view.Height; } else { @@ -318,14 +317,6 @@ namespace Ryujinx.Graphics.Vulkan srcY1 = crop.Bottom; } - if (scale != 1f) - { - srcX0 = (int)(srcX0 * scale); - srcY0 = (int)(srcY0 * scale); - srcX1 = (int)Math.Ceiling(srcX1 * scale); - srcY1 = (int)Math.Ceiling(srcY1 * scale); - } - if (ScreenCaptureRequested) { if (_effect != null)