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>
This commit is contained in:
parent
b8de72de8f
commit
f1d1670b0b
60 changed files with 2336 additions and 277 deletions
|
@ -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>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue