Initial transform feedback support (#1370)

* Initial transform feedback support

* Some nits and fixes

* Update ReportCounterType and Write method

* Can't change shader or TFB bindings while TFB is active

* Fix geometry shader input names with new naming
This commit is contained in:
gdkchan 2020-07-15 00:01:10 -03:00 committed by GitHub
parent 16dafe6316
commit 788ca6a411
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 468 additions and 68 deletions

View file

@ -346,7 +346,7 @@ namespace Ryujinx.Graphics.Gpu.State
/// <param name="offset">Register offset</param>
/// <param name="index">Index for indexed data</param>
/// <returns>The data at the specified location</returns>
public T Get<T>(MethodOffset offset, int index) where T : struct
public T Get<T>(MethodOffset offset, int index) where T : unmanaged
{
Register register = _registers[(int)offset];
@ -364,11 +364,22 @@ namespace Ryujinx.Graphics.Gpu.State
/// <typeparam name="T">Type of the data</typeparam>
/// <param name="offset">Register offset</param>
/// <returns>The data at the specified location</returns>
public T Get<T>(MethodOffset offset) where T : struct
public T Get<T>(MethodOffset offset) where T : unmanaged
{
return MemoryMarshal.Cast<int, T>(_memory.AsSpan().Slice((int)offset))[0];
}
/// <summary>
/// Gets a span of the data at a given register offset.
/// </summary>
/// <param name="offset">Register offset</param>
/// <param name="length">Length of the data in bytes</param>
/// <returns>The data at the specified location</returns>
public Span<byte> GetSpan(MethodOffset offset, int length)
{
return MemoryMarshal.Cast<int, byte>(_memory.AsSpan().Slice((int)offset)).Slice(0, length);
}
/// <summary>
/// Sets indexed data to a given register offset.
/// </summary>
@ -376,7 +387,7 @@ namespace Ryujinx.Graphics.Gpu.State
/// <param name="offset">Register offset</param>
/// <param name="index">Index for indexed data</param>
/// <param name="data">The data to set</param>
public void Set<T>(MethodOffset offset, int index, T data) where T : struct
public void Set<T>(MethodOffset offset, int index, T data) where T : unmanaged
{
Register register = _registers[(int)offset];
@ -394,7 +405,7 @@ namespace Ryujinx.Graphics.Gpu.State
/// <typeparam name="T">Type of the data</typeparam>
/// <param name="offset">Register offset</param>
/// <param name="data">The data to set</param>
public void Set<T>(MethodOffset offset, T data) where T : struct
public void Set<T>(MethodOffset offset, T data) where T : unmanaged
{
ReadOnlySpan<int> intSpan = MemoryMarshal.Cast<T, int>(MemoryMarshal.CreateReadOnlySpan(ref data, 1));
intSpan.CopyTo(_memory.AsSpan().Slice((int)offset, intSpan.Length));

View file

@ -53,32 +53,34 @@ namespace Ryujinx.Graphics.Gpu.State
/// </summary>
public static TableItem[] Table = new TableItem[]
{
new TableItem(MethodOffset.RtColorState, typeof(RtColorState), Constants.TotalRenderTargets),
new TableItem(MethodOffset.ViewportTransform, typeof(ViewportTransform), Constants.TotalViewports),
new TableItem(MethodOffset.ViewportExtents, typeof(ViewportExtents), Constants.TotalViewports),
new TableItem(MethodOffset.VertexBufferDrawState, typeof(VertexBufferDrawState), 1),
new TableItem(MethodOffset.DepthBiasState, typeof(DepthBiasState), 1),
new TableItem(MethodOffset.ScissorState, typeof(ScissorState), Constants.TotalViewports),
new TableItem(MethodOffset.StencilBackMasks, typeof(StencilBackMasks), 1),
new TableItem(MethodOffset.RtDepthStencilState, typeof(RtDepthStencilState), 1),
new TableItem(MethodOffset.VertexAttribState, typeof(VertexAttribState), 16),
new TableItem(MethodOffset.RtDepthStencilSize, typeof(Size3D), 1),
new TableItem(MethodOffset.BlendEnable, typeof(Boolean32), Constants.TotalRenderTargets),
new TableItem(MethodOffset.StencilTestState, typeof(StencilTestState), 1),
new TableItem(MethodOffset.SamplerPoolState, typeof(PoolState), 1),
new TableItem(MethodOffset.TexturePoolState, typeof(PoolState), 1),
new TableItem(MethodOffset.StencilBackTestState, typeof(StencilBackTestState), 1),
new TableItem(MethodOffset.ShaderBaseAddress, typeof(GpuVa), 1),
new TableItem(MethodOffset.PrimitiveRestartState, typeof(PrimitiveRestartState), 1),
new TableItem(MethodOffset.IndexBufferState, typeof(IndexBufferState), 1),
new TableItem(MethodOffset.VertexBufferInstanced, typeof(Boolean32), 16),
new TableItem(MethodOffset.FaceState, typeof(FaceState), 1),
new TableItem(MethodOffset.RtColorMask, typeof(RtColorMask), Constants.TotalRenderTargets),
new TableItem(MethodOffset.VertexBufferState, typeof(VertexBufferState), 16),
new TableItem(MethodOffset.BlendConstant, typeof(ColorF), 1),
new TableItem(MethodOffset.BlendState, typeof(BlendState), Constants.TotalRenderTargets),
new TableItem(MethodOffset.VertexBufferEndAddress, typeof(GpuVa), 16),
new TableItem(MethodOffset.ShaderState, typeof(ShaderState), 6),
new TableItem(MethodOffset.TfBufferState, typeof(TfBufferState), Constants.TotalTransformFeedbackBuffers),
new TableItem(MethodOffset.TfState, typeof(TfState), Constants.TotalTransformFeedbackBuffers),
new TableItem(MethodOffset.RtColorState, typeof(RtColorState), Constants.TotalRenderTargets),
new TableItem(MethodOffset.ViewportTransform, typeof(ViewportTransform), Constants.TotalViewports),
new TableItem(MethodOffset.ViewportExtents, typeof(ViewportExtents), Constants.TotalViewports),
new TableItem(MethodOffset.VertexBufferDrawState, typeof(VertexBufferDrawState), 1),
new TableItem(MethodOffset.DepthBiasState, typeof(DepthBiasState), 1),
new TableItem(MethodOffset.ScissorState, typeof(ScissorState), Constants.TotalViewports),
new TableItem(MethodOffset.StencilBackMasks, typeof(StencilBackMasks), 1),
new TableItem(MethodOffset.RtDepthStencilState, typeof(RtDepthStencilState), 1),
new TableItem(MethodOffset.VertexAttribState, typeof(VertexAttribState), Constants.TotalVertexAttribs),
new TableItem(MethodOffset.RtDepthStencilSize, typeof(Size3D), 1),
new TableItem(MethodOffset.BlendEnable, typeof(Boolean32), Constants.TotalRenderTargets),
new TableItem(MethodOffset.StencilTestState, typeof(StencilTestState), 1),
new TableItem(MethodOffset.SamplerPoolState, typeof(PoolState), 1),
new TableItem(MethodOffset.TexturePoolState, typeof(PoolState), 1),
new TableItem(MethodOffset.StencilBackTestState, typeof(StencilBackTestState), 1),
new TableItem(MethodOffset.ShaderBaseAddress, typeof(GpuVa), 1),
new TableItem(MethodOffset.PrimitiveRestartState, typeof(PrimitiveRestartState), 1),
new TableItem(MethodOffset.IndexBufferState, typeof(IndexBufferState), 1),
new TableItem(MethodOffset.VertexBufferInstanced, typeof(Boolean32), Constants.TotalVertexBuffers),
new TableItem(MethodOffset.FaceState, typeof(FaceState), 1),
new TableItem(MethodOffset.RtColorMask, typeof(RtColorMask), Constants.TotalRenderTargets),
new TableItem(MethodOffset.VertexBufferState, typeof(VertexBufferState), Constants.TotalVertexBuffers),
new TableItem(MethodOffset.BlendConstant, typeof(ColorF), 1),
new TableItem(MethodOffset.BlendState, typeof(BlendState), Constants.TotalRenderTargets),
new TableItem(MethodOffset.VertexBufferEndAddress, typeof(GpuVa), Constants.TotalVertexBuffers),
new TableItem(MethodOffset.ShaderState, typeof(ShaderState), Constants.ShaderStages + 1),
};
}
}

View file

@ -28,10 +28,13 @@ namespace Ryujinx.Graphics.Gpu.State
SyncpointAction = 0xb2,
CopyBuffer = 0xc0,
RasterizeEnable = 0xdf,
TfBufferState = 0xe0,
CopyBufferParams = 0x100,
TfState = 0x1c0,
CopyBufferSwizzle = 0x1c2,
CopyBufferDstTexture = 0x1c3,
CopyBufferSrcTexture = 0x1ca,
TfEnable = 0x1d1,
RtColorState = 0x200,
CopyTextureControl = 0x223,
CopyRegion = 0x22c,
@ -116,6 +119,7 @@ namespace Ryujinx.Graphics.Gpu.State
UniformBufferBindTessEvaluation = 0x914,
UniformBufferBindGeometry = 0x91c,
UniformBufferBindFragment = 0x924,
TextureBufferIndex = 0x982
TextureBufferIndex = 0x982,
TfVaryingLocations = 0xa00
}
}

View file

@ -11,18 +11,19 @@ namespace Ryujinx.Graphics.Gpu.State
VertexShaderInvocations = 5,
GeometryShaderInvocations = 7,
GeometryShaderPrimitives = 9,
ZcullStats0 = 0xa,
TransformFeedbackPrimitivesWritten = 0xb,
ZcullStats1 = 0xc,
ZcullStats2 = 0xe,
ClipperInputPrimitives = 0xf,
ZcullStats3 = 0x10,
ClipperOutputPrimitives = 0x11,
PrimitivesGenerated = 0x12,
FragmentShaderInvocations = 0x13,
SamplesPassed = 0x15,
TransformFeedbackOffset = 0x1a,
TessControlShaderInvocations = 0x1b,
TessEvaluationShaderInvocations = 0x1d,
TessEvaluationShaderPrimitives = 0x1f,
ZcullStats0 = 0x2a,
ZcullStats1 = 0x2c,
ZcullStats2 = 0x2e,
ZcullStats3 = 0x30
TessEvaluationShaderPrimitives = 0x1f
}
}

View file

@ -0,0 +1,18 @@
namespace Ryujinx.Graphics.Gpu.State
{
/// <summary>
/// Transform feedback buffer state.
/// </summary>
struct TfBufferState
{
#pragma warning disable CS0649
public Boolean32 Enable;
public GpuVa Address;
public int Size;
public int Offset;
public uint Padding0;
public uint Padding1;
public uint Padding2;
#pragma warning restore CS0649
}
}

View file

@ -0,0 +1,15 @@
namespace Ryujinx.Graphics.Gpu.State
{
/// <summary>
/// Transform feedback state.
/// </summary>
struct TfState
{
#pragma warning disable CS0649
public int BufferIndex;
public int VaryingsCount;
public int Stride;
public uint Padding;
#pragma warning restore CS0649
}
}