From f1d1670b0b1b5c08064df95dabd295f3cf5dcf7f Mon Sep 17 00:00:00 2001 From: gdkchan <gab.dark.100@gmail.com> Date: Wed, 16 Nov 2022 14:53:04 -0300 Subject: Implement HLE macro for DrawElementsIndirect (#3748) * Implement HLE macro for DrawElementsIndirect * Shader cache version bump * Use GL_ARB_shader_draw_parameters extension on OpenGL * Fix DrawIndexedIndirectCount on Vulkan when extension is not supported * Implement DrawIndex * Alignment * Fix some validation errors * Rename BaseIds to DrawParameters * Fix incorrect index buffer and vertex buffer size in some cases * Add HLE macros for DrawArraysInstanced and DrawElementsInstanced * Perform a regular draw when indirect data is not modified * Use non-indirect draw methods if indirect buffer was not GPU modified * Only check if draw parameters match if the shader actually uses them * Expose Macro HLE setting on GUI * Reset FirstVertex and FirstInstance after draw * Update shader cache version again since some people already tested this * PR feedback Co-authored-by: riperiperi <rhy3756547@hotmail.com> --- Ryujinx.Graphics.Gpu/Memory/BufferCache.cs | 40 +++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 12 deletions(-) (limited to 'Ryujinx.Graphics.Gpu/Memory/BufferCache.cs') diff --git a/Ryujinx.Graphics.Gpu/Memory/BufferCache.cs b/Ryujinx.Graphics.Gpu/Memory/BufferCache.cs index 14b177aa..894d009c 100644 --- a/Ryujinx.Graphics.Gpu/Memory/BufferCache.cs +++ b/Ryujinx.Graphics.Gpu/Memory/BufferCache.cs @@ -27,6 +27,7 @@ namespace Ryujinx.Graphics.Gpu.Memory private Buffer[] _bufferOverlaps; private readonly Dictionary<ulong, BufferCacheEntry> _dirtyCache; + private readonly Dictionary<ulong, BufferCacheEntry> _modifiedCache; public event Action NotifyBuffersModified; @@ -45,6 +46,9 @@ namespace Ryujinx.Graphics.Gpu.Memory _bufferOverlaps = new Buffer[OverlapsBufferInitialCapacity]; _dirtyCache = new Dictionary<ulong, BufferCacheEntry>(); + + // There are a lot more entries on the modified cache, so it is separate from the one for ForceDirty. + _modifiedCache = new Dictionary<ulong, BufferCacheEntry>(); } /// <summary> @@ -145,6 +149,30 @@ namespace Ryujinx.Graphics.Gpu.Memory result.Buffer.ForceDirty(result.Address, size); } + /// <summary> + /// Checks if the given buffer range has been GPU modifed. + /// </summary> + /// <param name="memoryManager">GPU memory manager where the buffer is mapped</param> + /// <param name="gpuVa">Start GPU virtual address of the buffer</param> + /// <param name="size">Size in bytes of the buffer</param> + /// <returns>True if modified, false otherwise</returns> + public bool CheckModified(MemoryManager memoryManager, ulong gpuVa, ulong size, out ulong outAddr) + { + if (!_modifiedCache.TryGetValue(gpuVa, out BufferCacheEntry result) || + result.EndGpuAddress < gpuVa + size || + result.UnmappedSequence != result.Buffer.UnmappedSequence) + { + ulong address = TranslateAndCreateBuffer(memoryManager, gpuVa, size); + result = new BufferCacheEntry(address, gpuVa, GetBuffer(address, size)); + + _modifiedCache[gpuVa] = result; + } + + outAddr = result.Address; + + return result.Buffer.IsModified(result.Address, size); + } + /// <summary> /// Creates a new buffer for the specified range, if needed. /// If a buffer where this range can be fully contained already exists, @@ -326,18 +354,6 @@ namespace Ryujinx.Graphics.Gpu.Memory buffer.SignalModified(address, size); } - /// <summary> - /// Gets a buffer sub-range for a given GPU memory range. - /// </summary> - /// <param name="memoryManager">GPU memory manager where the buffer is mapped</param> - /// <param name="gpuVa">Start GPU virtual address of the buffer</param> - /// <param name="size">Size in bytes of the buffer</param> - /// <returns>The buffer sub-range for the given range</returns> - public BufferRange GetGpuBufferRange(MemoryManager memoryManager, ulong gpuVa, ulong size) - { - return GetBufferRange(TranslateAndCreateBuffer(memoryManager, gpuVa, size), size); - } - /// <summary> /// Gets a buffer sub-range starting at a given memory address. /// </summary> -- cgit v1.2.3-70-g09d2