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

@ -497,6 +497,50 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
return 0;
}
/// <summary>
/// Performs a indexed or non-indexed draw.
/// </summary>
/// <param name="topology">Primitive topology</param>
/// <param name="count">Index count for indexed draws, vertex count for non-indexed draws</param>
/// <param name="instanceCount">Instance count</param>
/// <param name="firstIndex">First index on the index buffer for indexed draws, ignored for non-indexed draws</param>
/// <param name="firstVertex">First vertex on the vertex buffer</param>
/// <param name="firstInstance">First instance</param>
/// <param name="indexed">True if the draw is indexed, false otherwise</param>
public void Draw(
PrimitiveTopology topology,
int count,
int instanceCount,
int firstIndex,
int firstVertex,
int firstInstance,
bool indexed)
{
_drawManager.Draw(this, topology, count, instanceCount, firstIndex, firstVertex, firstInstance, indexed);
}
/// <summary>
/// Performs a indirect draw, with parameters from a GPU buffer.
/// </summary>
/// <param name="topology">Primitive topology</param>
/// <param name="indirectBufferAddress">Address of the buffer with the draw parameters, such as count, first index, etc</param>
/// <param name="parameterBufferAddress">Address of the buffer with the draw count</param>
/// <param name="maxDrawCount">Maximum number of draws that can be made</param>
/// <param name="stride">Distance in bytes between each entry on the data pointed to by <paramref name="indirectBufferAddress"/></param>
/// <param name="indexCount">Maximum number of indices that the draw can consume</param>
/// <param name="drawType">Type of the indirect draw, which can be indexed or non-indexed, with or without a draw count</param>
public void DrawIndirect(
PrimitiveTopology topology,
ulong indirectBufferAddress,
ulong parameterBufferAddress,
int maxDrawCount,
int stride,
int indexCount,
IndirectDrawType drawType)
{
_drawManager.DrawIndirect(this, topology, indirectBufferAddress, parameterBufferAddress, maxDrawCount, stride, indexCount, drawType);
}
/// <summary>
/// Clears the current color and depth-stencil buffers.
/// Which buffers should be cleared can also specified with the arguments.
@ -507,25 +551,5 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
{
_drawManager.Clear(this, argument, layerCount);
}
/// <summary>
/// Performs a indirect multi-draw, with parameters from a GPU buffer.
/// </summary>
/// <param name="indexCount">Index Buffer Count</param>
/// <param name="topology">Primitive topology</param>
/// <param name="indirectBuffer">GPU buffer with the draw parameters, such as count, first index, etc</param>
/// <param name="parameterBuffer">GPU buffer with the draw count</param>
/// <param name="maxDrawCount">Maximum number of draws that can be made</param>
/// <param name="stride">Distance in bytes between each element on the <paramref name="indirectBuffer"/> array</param>
public void MultiDrawIndirectCount(
int indexCount,
PrimitiveTopology topology,
BufferRange indirectBuffer,
BufferRange parameterBuffer,
int maxDrawCount,
int stride)
{
_drawManager.MultiDrawIndirectCount(this, indexCount, topology, indirectBuffer, parameterBuffer, maxDrawCount, stride);
}
}
}