mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2025-02-22 17:10:19 +00:00
Fix transform feedback on Intel, gl_Position feedback and clears to inexistent depth buffers
This commit is contained in:
parent
0fe19f51c0
commit
52249e50dd
3 changed files with 59 additions and 27 deletions
|
@ -196,12 +196,36 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
|
||||||
context.Config.Stage != ShaderStage.Fragment &&
|
context.Config.Stage != ShaderStage.Fragment &&
|
||||||
context.Config.TransformFeedbackEnabled)
|
context.Config.TransformFeedbackEnabled)
|
||||||
{
|
{
|
||||||
var tfOutput = context.GetTransformFeedbackOutput(AttributeConsts.PositionX);
|
var tfPosition = context.GetTransformFeedbackOutput(AttributeConsts.PositionX);
|
||||||
if (tfOutput.Valid)
|
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.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[];" : ";");
|
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)
|
public static void DeclareLocals(CodeGenContext context, StructuredFunction function)
|
||||||
{
|
{
|
||||||
foreach (AstOperand decl in function.Locals)
|
foreach (AstOperand decl in function.Locals)
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
using Ryujinx.Graphics.Shader;
|
using Ryujinx.Graphics.Shader;
|
||||||
using Silk.NET.Vulkan;
|
using Silk.NET.Vulkan;
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Vulkan
|
namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
|
@ -62,6 +61,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
private bool _needsVertexBuffersRebind;
|
private bool _needsVertexBuffersRebind;
|
||||||
|
|
||||||
private bool _tfEnabled;
|
private bool _tfEnabled;
|
||||||
|
private bool _tfActive;
|
||||||
|
|
||||||
public ulong DrawCount { get; private set; }
|
public ulong DrawCount { get; private set; }
|
||||||
|
|
||||||
|
@ -128,12 +128,8 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
public void BeginTransformFeedback(GAL.PrimitiveTopology topology)
|
public void BeginTransformFeedback(GAL.PrimitiveTopology topology)
|
||||||
{
|
{
|
||||||
if (!_tfEnabled)
|
|
||||||
{
|
|
||||||
BeginTransformFeedbackInternal();
|
|
||||||
_tfEnabled = true;
|
_tfEnabled = true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void ClearBuffer(BufferHandle destination, int offset, int size, uint value)
|
public void ClearBuffer(BufferHandle destination, int offset, int size, uint value)
|
||||||
{
|
{
|
||||||
|
@ -171,7 +167,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
// TODO: Use stencilMask (fully)
|
// TODO: Use stencilMask (fully)
|
||||||
|
|
||||||
if (_framebuffer == null)
|
if (_framebuffer == null || !FramebufferParams.HasDepthStencil)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -237,6 +233,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
BeginRenderPass();
|
BeginRenderPass();
|
||||||
RecreatePipelineIfNeeded(PipelineBindPoint.Graphics);
|
RecreatePipelineIfNeeded(PipelineBindPoint.Graphics);
|
||||||
|
ResumeTransformFeedbackInternal();
|
||||||
DrawCount++;
|
DrawCount++;
|
||||||
|
|
||||||
if (_topology == GAL.PrimitiveTopology.Quads)
|
if (_topology == GAL.PrimitiveTopology.Quads)
|
||||||
|
@ -265,6 +262,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
BeginRenderPass();
|
BeginRenderPass();
|
||||||
RecreatePipelineIfNeeded(PipelineBindPoint.Graphics);
|
RecreatePipelineIfNeeded(PipelineBindPoint.Graphics);
|
||||||
|
ResumeTransformFeedbackInternal();
|
||||||
DrawCount++;
|
DrawCount++;
|
||||||
|
|
||||||
if (_topology == GAL.PrimitiveTopology.Quads)
|
if (_topology == GAL.PrimitiveTopology.Quads)
|
||||||
|
@ -334,12 +332,9 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
public void EndTransformFeedback()
|
public void EndTransformFeedback()
|
||||||
{
|
{
|
||||||
if (_tfEnabled)
|
PauseTransformFeedbackInternal();
|
||||||
{
|
|
||||||
EndTransformFeedbackInternal();
|
|
||||||
_tfEnabled = false;
|
_tfEnabled = false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void MultiDrawIndirectCount(BufferRange indirectBuffer, BufferRange parameterBuffer, int maxDrawCount, int stride)
|
public void MultiDrawIndirectCount(BufferRange indirectBuffer, BufferRange parameterBuffer, int maxDrawCount, int stride)
|
||||||
{
|
{
|
||||||
|
@ -355,6 +350,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
BeginRenderPass();
|
BeginRenderPass();
|
||||||
RecreatePipelineIfNeeded(PipelineBindPoint.Graphics);
|
RecreatePipelineIfNeeded(PipelineBindPoint.Graphics);
|
||||||
|
ResumeTransformFeedbackInternal();
|
||||||
DrawCount++;
|
DrawCount++;
|
||||||
|
|
||||||
var buffer = Gd.BufferManager.GetBuffer(CommandBuffer, indirectBuffer.Handle, true).Get(Cbs, indirectBuffer.Offset, indirectBuffer.Size).Value;
|
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,
|
(ulong)parameterBuffer.Offset,
|
||||||
(uint)maxDrawCount,
|
(uint)maxDrawCount,
|
||||||
(uint)stride);
|
(uint)stride);
|
||||||
|
|
||||||
|
PauseTransformFeedbackInternal();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void MultiDrawIndexedIndirectCount(BufferRange indirectBuffer, BufferRange parameterBuffer, int maxDrawCount, int stride)
|
public void MultiDrawIndexedIndirectCount(BufferRange indirectBuffer, BufferRange parameterBuffer, int maxDrawCount, int stride)
|
||||||
|
@ -384,6 +382,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
|
|
||||||
BeginRenderPass();
|
BeginRenderPass();
|
||||||
RecreatePipelineIfNeeded(PipelineBindPoint.Graphics);
|
RecreatePipelineIfNeeded(PipelineBindPoint.Graphics);
|
||||||
|
ResumeTransformFeedbackInternal();
|
||||||
DrawCount++;
|
DrawCount++;
|
||||||
|
|
||||||
var buffer = Gd.BufferManager.GetBuffer(CommandBuffer, indirectBuffer.Handle, true).Get(Cbs, indirectBuffer.Offset, indirectBuffer.Size).Value;
|
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,
|
(ulong)parameterBuffer.Offset,
|
||||||
(uint)maxDrawCount,
|
(uint)maxDrawCount,
|
||||||
(uint)stride);
|
(uint)stride);
|
||||||
|
|
||||||
|
PauseTransformFeedbackInternal();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetAlphaTest(bool enable, float reference, GAL.CompareOp op)
|
public void SetAlphaTest(bool enable, float reference, GAL.CompareOp op)
|
||||||
|
@ -713,8 +714,6 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_transformFeedbackBuffers[i] = BufferState.Null;
|
_transformFeedbackBuffers[i] = BufferState.Null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ResumeTransformFeedbackInternal();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetUniformBuffers(int first, ReadOnlySpan<BufferRange> buffers)
|
public void SetUniformBuffers(int first, ReadOnlySpan<BufferRange> buffers)
|
||||||
|
@ -744,7 +743,6 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
}
|
}
|
||||||
|
|
||||||
_newState.VertexAttributeDescriptionsCount = (uint)count;
|
_newState.VertexAttributeDescriptionsCount = (uint)count;
|
||||||
|
|
||||||
SignalStateChange();
|
SignalStateChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -789,7 +787,6 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
}
|
}
|
||||||
|
|
||||||
_newState.VertexBindingDescriptionsCount = (uint)validCount;
|
_newState.VertexBindingDescriptionsCount = (uint)validCount;
|
||||||
|
|
||||||
SignalStateChange();
|
SignalStateChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1067,7 +1064,6 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_transformFeedbackBuffers[i].BindTransformFeedbackBuffer(Gd, Cbs, (uint)i);
|
_transformFeedbackBuffers[i].BindTransformFeedbackBuffer(Gd, Cbs, (uint)i);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResumeTransformFeedbackInternal();
|
|
||||||
_needsTransformFeedbackBuffersRebind = false;
|
_needsTransformFeedbackBuffersRebind = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1106,6 +1102,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
// _pipeline?.Dispose();
|
// _pipeline?.Dispose();
|
||||||
Pipeline = pipeline;
|
Pipeline = pipeline;
|
||||||
|
|
||||||
|
PauseTransformFeedbackInternal();
|
||||||
Gd.Api.CmdBindPipeline(CommandBuffer, pbp, Pipeline.Get(Cbs).Value);
|
Gd.Api.CmdBindPipeline(CommandBuffer, pbp, Pipeline.Get(Cbs).Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1137,25 +1134,28 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
{
|
{
|
||||||
if (_renderPassActive)
|
if (_renderPassActive)
|
||||||
{
|
{
|
||||||
|
PauseTransformFeedbackInternal();
|
||||||
// System.Console.WriteLine("render pass ended " + caller);
|
// System.Console.WriteLine("render pass ended " + caller);
|
||||||
Gd.Api.CmdEndRenderPass(CommandBuffer);
|
Gd.Api.CmdEndRenderPass(CommandBuffer);
|
||||||
_renderPassActive = false;
|
_renderPassActive = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void PauseTransformFeedbackInternal()
|
private void PauseTransformFeedbackInternal()
|
||||||
{
|
{
|
||||||
if (_tfEnabled)
|
if (_tfEnabled && _tfActive)
|
||||||
{
|
{
|
||||||
EndTransformFeedbackInternal();
|
EndTransformFeedbackInternal();
|
||||||
|
_tfActive = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void ResumeTransformFeedbackInternal()
|
private void ResumeTransformFeedbackInternal()
|
||||||
{
|
{
|
||||||
if (_tfEnabled)
|
if (_tfEnabled && !_tfActive)
|
||||||
{
|
{
|
||||||
BeginTransformFeedbackInternal();
|
BeginTransformFeedbackInternal();
|
||||||
|
_tfActive = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -249,7 +249,6 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
// System.Console.WriteLine("flush by " + caller);
|
// System.Console.WriteLine("flush by " + caller);
|
||||||
|
|
||||||
EndRenderPass();
|
EndRenderPass();
|
||||||
PauseTransformFeedbackInternal();
|
|
||||||
|
|
||||||
foreach (var queryPool in _activeQueries)
|
foreach (var queryPool in _activeQueries)
|
||||||
{
|
{
|
||||||
|
@ -277,7 +276,6 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
Gd.Api.CmdBeginQuery(CommandBuffer, queryPool, 0, 0);
|
Gd.Api.CmdBeginQuery(CommandBuffer, queryPool, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResumeTransformFeedbackInternal();
|
|
||||||
SignalCommandBufferChange();
|
SignalCommandBufferChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue