Geometry shader emulation for macOS (#5551)
* Implement vertex and geometry shader conversion to compute * Call InitializeReservedCounts for compute too * PR feedback * Set clip distance mask for geometry and tessellation shaders too * Transform feedback emulation only for vertex
This commit is contained in:
parent
93d78f9ac4
commit
f09bba82b9
65 changed files with 3912 additions and 593 deletions
|
@ -9,56 +9,21 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||
/// <summary>
|
||||
/// Support buffer data updater.
|
||||
/// </summary>
|
||||
class SupportBufferUpdater : IDisposable
|
||||
class SupportBufferUpdater : BufferUpdater
|
||||
{
|
||||
private SupportBuffer _data;
|
||||
private BufferHandle _handle;
|
||||
|
||||
private readonly IRenderer _renderer;
|
||||
private int _startOffset = -1;
|
||||
private int _endOffset = -1;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the support buffer updater.
|
||||
/// </summary>
|
||||
/// <param name="renderer">Renderer that the support buffer will be used with</param>
|
||||
public SupportBufferUpdater(IRenderer renderer)
|
||||
public SupportBufferUpdater(IRenderer renderer) : base(renderer)
|
||||
{
|
||||
_renderer = renderer;
|
||||
|
||||
var defaultScale = new Vector4<float> { X = 1f, Y = 0f, Z = 0f, W = 0f };
|
||||
_data.RenderScale.AsSpan().Fill(defaultScale);
|
||||
DirtyRenderScale(0, SupportBuffer.RenderScaleMaxCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Mark a region of the support buffer as modified and needing to be sent to the GPU.
|
||||
/// </summary>
|
||||
/// <param name="startOffset">Start offset of the region in bytes</param>
|
||||
/// <param name="byteSize">Size of the region in bytes</param>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Marks the fragment render scale count as being modified.
|
||||
/// </summary>
|
||||
|
@ -220,40 +185,40 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Submits all pending buffer updates to the GPU.
|
||||
/// Sets offset for the misaligned portion of a transform feedback buffer, and the buffer size, for transform feedback emulation.
|
||||
/// </summary>
|
||||
public void Commit()
|
||||
/// <param name="bufferIndex">Index of the transform feedback buffer</param>
|
||||
/// <param name="offset">Misaligned offset of the buffer</param>
|
||||
public void SetTfeOffset(int bufferIndex, int offset)
|
||||
{
|
||||
if (_startOffset != -1)
|
||||
ref int currentOffset = ref GetElementRef(ref _data.TfeOffset, bufferIndex);
|
||||
|
||||
if (currentOffset != offset)
|
||||
{
|
||||
if (_handle == BufferHandle.Null)
|
||||
{
|
||||
_handle = _renderer.CreateBuffer(SupportBuffer.RequiredSize, BufferAccess.Stream);
|
||||
_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<byte> data = MemoryMarshal.Cast<SupportBuffer, byte>(MemoryMarshal.CreateSpan(ref _data, 1));
|
||||
|
||||
_renderer.SetBufferData(_handle, _startOffset, data[_startOffset.._endOffset]);
|
||||
|
||||
_startOffset = -1;
|
||||
_endOffset = -1;
|
||||
currentOffset = offset;
|
||||
MarkDirty(SupportBuffer.TfeOffsetOffset + bufferIndex * sizeof(int), sizeof(int));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destroys the support buffer.
|
||||
/// Sets the vertex count used for transform feedback emulation with instanced draws.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
/// <param name="vertexCount">Vertex count of the instanced draw</param>
|
||||
public void SetTfeVertexCount(int vertexCount)
|
||||
{
|
||||
if (_handle != BufferHandle.Null)
|
||||
if (_data.TfeVertexCount.X != vertexCount)
|
||||
{
|
||||
_renderer.DeleteBuffer(_handle);
|
||||
_handle = BufferHandle.Null;
|
||||
_data.TfeVertexCount.X = vertexCount;
|
||||
MarkDirty(SupportBuffer.TfeVertexCountOffset, sizeof(int));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Submits all pending buffer updates to the GPU.
|
||||
/// </summary>
|
||||
public void Commit()
|
||||
{
|
||||
Commit(MemoryMarshal.Cast<SupportBuffer, byte>(MemoryMarshal.CreateSpan(ref _data, 1)), SupportBuffer.Binding);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue