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:
gdkchan 2022-11-16 14:53:04 -03:00 committed by GitHub
parent b8de72de8f
commit f1d1670b0b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
60 changed files with 2336 additions and 277 deletions

View file

@ -1,5 +1,4 @@
using Silk.NET.Vulkan;
using System;
namespace Ryujinx.Graphics.Vulkan
{
@ -68,17 +67,18 @@ namespace Ryujinx.Graphics.Vulkan
}
}
public void BindConvertedIndexBuffer(VulkanRenderer gd, CommandBufferScoped cbs, int firstIndex, int indexCount, int convertedCount, IndexBufferPattern pattern)
public void BindConvertedIndexBuffer(
VulkanRenderer gd,
CommandBufferScoped cbs,
int firstIndex,
int indexCount,
int convertedCount,
IndexBufferPattern pattern)
{
Auto<DisposableBuffer> autoBuffer;
// Convert the index buffer using the given pattern.
int indexSize = _type switch
{
IndexType.Uint32 => 4,
IndexType.Uint16 => 2,
_ => 1,
};
int indexSize = GetIndexSize();
int firstIndexOffset = firstIndex * indexSize;
@ -94,6 +94,54 @@ namespace Ryujinx.Graphics.Vulkan
}
}
public Auto<DisposableBuffer> BindConvertedIndexBufferIndirect(
VulkanRenderer gd,
CommandBufferScoped cbs,
GAL.BufferRange indirectBuffer,
GAL.BufferRange drawCountBuffer,
IndexBufferPattern pattern,
bool hasDrawCount,
int maxDrawCount,
int indirectDataStride)
{
// Convert the index buffer using the given pattern.
int indexSize = GetIndexSize();
(var indexBufferAuto, var indirectBufferAuto) = gd.BufferManager.GetBufferTopologyConversionIndirect(
gd,
cbs,
new GAL.BufferRange(_handle, _offset, _size),
indirectBuffer,
drawCountBuffer,
pattern,
indexSize,
hasDrawCount,
maxDrawCount,
indirectDataStride);
int convertedCount = pattern.GetConvertedCount(_size / indexSize);
int size = convertedCount * 4;
_buffer = indexBufferAuto;
if (indexBufferAuto != null)
{
gd.Api.CmdBindIndexBuffer(cbs.CommandBuffer, indexBufferAuto.Get(cbs, 0, size).Value, 0, IndexType.Uint32);
}
return indirectBufferAuto;
}
private int GetIndexSize()
{
return _type switch
{
IndexType.Uint32 => 4,
IndexType.Uint16 => 2,
_ => 1,
};
}
public bool BoundEquals(Auto<DisposableBuffer> buffer)
{
return _buffer == buffer;