Fix transform feedback on Intel, gl_Position feedback and clears to inexistent depth buffers

This commit is contained in:
gdk 2022-01-26 09:36:20 -03:00 committed by riperiperi
parent 0fe19f51c0
commit 52249e50dd
3 changed files with 59 additions and 27 deletions

View file

@ -196,12 +196,36 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
context.Config.Stage != ShaderStage.Fragment &&
context.Config.TransformFeedbackEnabled)
{
var tfOutput = context.GetTransformFeedbackOutput(AttributeConsts.PositionX);
if (tfOutput.Valid)
var tfPosition = context.GetTransformFeedbackOutput(AttributeConsts.PositionX);
var tfPointSize = context.GetTransformFeedbackOutput(AttributeConsts.PointSize);
var tfClipDistance = context.GetTransformFeedbackOutput(AttributeConsts.ClipDistance0);
if (tfPosition.Valid || tfPointSize.Valid || tfClipDistance.Valid)
{
context.AppendLine($"layout (xfb_buffer = {tfOutput.Buffer}, xfb_offset = {tfOutput.Offset}, xfb_stride = {tfOutput.Stride}) out gl_PerVertex");
context.AppendLine("out gl_PerVertex");
context.EnterScope();
context.AppendLine("vec4 gl_Position;");
context.AppendLine($"{GetTfLayout(tfPosition)}vec4 gl_Position;");
context.AppendLine($"{GetTfLayout(tfPointSize)}float gl_PointSize;");
if (tfClipDistance.Valid)
{
int clipDistanceCount = 1;
for (; clipDistanceCount < 8; clipDistanceCount++)
{
if (!context.GetTransformFeedbackOutput(AttributeConsts.ClipDistance0 + clipDistanceCount).Valid)
{
break;
}
}
context.AppendLine($"{GetTfLayout(tfClipDistance)}float gl_ClipDistance[{clipDistanceCount}];");
}
else
{
context.AppendLine("float gl_ClipDistance[];");
}
context.LeaveScope(context.Config.Stage == ShaderStage.TessellationControl ? " gl_out[];" : ";");
}
}
@ -311,6 +335,16 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
}
}
private static string GetTfLayout(TransformFeedbackOutput tfOutput)
{
if (tfOutput.Valid)
{
return $"layout (xfb_buffer = {tfOutput.Buffer}, xfb_offset = {tfOutput.Offset}, xfb_stride = {tfOutput.Stride}) ";
}
return string.Empty;
}
public static void DeclareLocals(CodeGenContext context, StructuredFunction function)
{
foreach (AstOperand decl in function.Locals)

View file

@ -2,7 +2,6 @@
using Ryujinx.Graphics.Shader;
using Silk.NET.Vulkan;
using System;
using System.Runtime.InteropServices;
namespace Ryujinx.Graphics.Vulkan
{
@ -62,6 +61,7 @@ namespace Ryujinx.Graphics.Vulkan
private bool _needsVertexBuffersRebind;
private bool _tfEnabled;
private bool _tfActive;
public ulong DrawCount { get; private set; }
@ -128,11 +128,7 @@ namespace Ryujinx.Graphics.Vulkan
public void BeginTransformFeedback(GAL.PrimitiveTopology topology)
{
if (!_tfEnabled)
{
BeginTransformFeedbackInternal();
_tfEnabled = true;
}
_tfEnabled = true;
}
public void ClearBuffer(BufferHandle destination, int offset, int size, uint value)
@ -171,7 +167,7 @@ namespace Ryujinx.Graphics.Vulkan
{
// TODO: Use stencilMask (fully)
if (_framebuffer == null)
if (_framebuffer == null || !FramebufferParams.HasDepthStencil)
{
return;
}
@ -237,6 +233,7 @@ namespace Ryujinx.Graphics.Vulkan
BeginRenderPass();
RecreatePipelineIfNeeded(PipelineBindPoint.Graphics);
ResumeTransformFeedbackInternal();
DrawCount++;
if (_topology == GAL.PrimitiveTopology.Quads)
@ -265,6 +262,7 @@ namespace Ryujinx.Graphics.Vulkan
BeginRenderPass();
RecreatePipelineIfNeeded(PipelineBindPoint.Graphics);
ResumeTransformFeedbackInternal();
DrawCount++;
if (_topology == GAL.PrimitiveTopology.Quads)
@ -334,11 +332,8 @@ namespace Ryujinx.Graphics.Vulkan
public void EndTransformFeedback()
{
if (_tfEnabled)
{
EndTransformFeedbackInternal();
_tfEnabled = false;
}
PauseTransformFeedbackInternal();
_tfEnabled = false;
}
public void MultiDrawIndirectCount(BufferRange indirectBuffer, BufferRange parameterBuffer, int maxDrawCount, int stride)
@ -355,6 +350,7 @@ namespace Ryujinx.Graphics.Vulkan
BeginRenderPass();
RecreatePipelineIfNeeded(PipelineBindPoint.Graphics);
ResumeTransformFeedbackInternal();
DrawCount++;
var buffer = Gd.BufferManager.GetBuffer(CommandBuffer, indirectBuffer.Handle, true).Get(Cbs, indirectBuffer.Offset, indirectBuffer.Size).Value;
@ -368,6 +364,8 @@ namespace Ryujinx.Graphics.Vulkan
(ulong)parameterBuffer.Offset,
(uint)maxDrawCount,
(uint)stride);
PauseTransformFeedbackInternal();
}
public void MultiDrawIndexedIndirectCount(BufferRange indirectBuffer, BufferRange parameterBuffer, int maxDrawCount, int stride)
@ -384,6 +382,7 @@ namespace Ryujinx.Graphics.Vulkan
BeginRenderPass();
RecreatePipelineIfNeeded(PipelineBindPoint.Graphics);
ResumeTransformFeedbackInternal();
DrawCount++;
var buffer = Gd.BufferManager.GetBuffer(CommandBuffer, indirectBuffer.Handle, true).Get(Cbs, indirectBuffer.Offset, indirectBuffer.Size).Value;
@ -397,6 +396,8 @@ namespace Ryujinx.Graphics.Vulkan
(ulong)parameterBuffer.Offset,
(uint)maxDrawCount,
(uint)stride);
PauseTransformFeedbackInternal();
}
public void SetAlphaTest(bool enable, float reference, GAL.CompareOp op)
@ -713,8 +714,6 @@ namespace Ryujinx.Graphics.Vulkan
_transformFeedbackBuffers[i] = BufferState.Null;
}
}
ResumeTransformFeedbackInternal();
}
public void SetUniformBuffers(int first, ReadOnlySpan<BufferRange> buffers)
@ -744,7 +743,6 @@ namespace Ryujinx.Graphics.Vulkan
}
_newState.VertexAttributeDescriptionsCount = (uint)count;
SignalStateChange();
}
@ -789,7 +787,6 @@ namespace Ryujinx.Graphics.Vulkan
}
_newState.VertexBindingDescriptionsCount = (uint)validCount;
SignalStateChange();
}
@ -1067,7 +1064,6 @@ namespace Ryujinx.Graphics.Vulkan
_transformFeedbackBuffers[i].BindTransformFeedbackBuffer(Gd, Cbs, (uint)i);
}
ResumeTransformFeedbackInternal();
_needsTransformFeedbackBuffersRebind = false;
}
@ -1106,6 +1102,7 @@ namespace Ryujinx.Graphics.Vulkan
// _pipeline?.Dispose();
Pipeline = pipeline;
PauseTransformFeedbackInternal();
Gd.Api.CmdBindPipeline(CommandBuffer, pbp, Pipeline.Get(Cbs).Value);
}
}
@ -1137,25 +1134,28 @@ namespace Ryujinx.Graphics.Vulkan
{
if (_renderPassActive)
{
PauseTransformFeedbackInternal();
// System.Console.WriteLine("render pass ended " + caller);
Gd.Api.CmdEndRenderPass(CommandBuffer);
_renderPassActive = false;
}
}
protected void PauseTransformFeedbackInternal()
private void PauseTransformFeedbackInternal()
{
if (_tfEnabled)
if (_tfEnabled && _tfActive)
{
EndTransformFeedbackInternal();
_tfActive = false;
}
}
protected void ResumeTransformFeedbackInternal()
private void ResumeTransformFeedbackInternal()
{
if (_tfEnabled)
if (_tfEnabled && !_tfActive)
{
BeginTransformFeedbackInternal();
_tfActive = true;
}
}

View file

@ -249,7 +249,6 @@ namespace Ryujinx.Graphics.Vulkan
// System.Console.WriteLine("flush by " + caller);
EndRenderPass();
PauseTransformFeedbackInternal();
foreach (var queryPool in _activeQueries)
{
@ -277,7 +276,6 @@ namespace Ryujinx.Graphics.Vulkan
Gd.Api.CmdBeginQuery(CommandBuffer, queryPool, 0, 0);
}
ResumeTransformFeedbackInternal();
SignalCommandBufferChange();
}