From 182c95a588686bae1b57852b1570143e026f1f28 Mon Sep 17 00:00:00 2001 From: riperiperi Date: Sat, 7 May 2022 16:04:55 +0100 Subject: [PATCH] Vulkan/SPIR-V support for viewport inverse --- .../Shader/DiskCache/DiskCacheHostStorage.cs | 2 +- .../CodeGen/Spirv/CodeGenContext.cs | 11 ++++++++++- Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs | 11 +++++++---- .../CodeGen/Spirv/ScalingHelpers.cs | 8 ++++---- Ryujinx.Graphics.Shader/Translation/AttributeInfo.cs | 4 ++++ 5 files changed, 26 insertions(+), 10 deletions(-) diff --git a/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs b/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs index 0b36bea3f..0deb8faa7 100644 --- a/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs +++ b/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs @@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache private const ushort FileFormatVersionMajor = 1; private const ushort FileFormatVersionMinor = 2; private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor; - private const uint CodeGenVersion = 3; + private const uint CodeGenVersion = 4; private const string SharedTocFileName = "shared.toc"; private const string SharedDataFileName = "shared.data"; diff --git a/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs b/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs index 17291a1f5..187fd2d32 100644 --- a/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs +++ b/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs @@ -268,6 +268,15 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv } } + bool isViewportInverse = attr == AttributeConsts.SupportBlockViewInverseX || attr == AttributeConsts.SupportBlockViewInverseY; + + if (isViewportInverse) + { + elemType = AggregateType.FP32; + elemIndex = Constant(TypeU32(), (attr - AttributeConsts.SupportBlockViewInverseX) >> 2); + return AccessChain(TypePointer(StorageClass.Uniform, TypeFP32()), SupportBuffer, Constant(TypeU32(), 2), elemIndex); + } + elemType = attrInfo.Type & AggregateType.ElementTypeMask; if (isUserAttr && Config.TransformFeedbackEnabled && @@ -331,7 +340,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv if (attr == AttributeConsts.PositionX || attr == AttributeConsts.PositionY) { var pointerType = TypePointer(StorageClass.Uniform, TypeFP32()); - var fieldIndex = Constant(TypeU32(), 3); + var fieldIndex = Constant(TypeU32(), 4); var scaleIndex = Constant(TypeU32(), 0); var scaleElemPointer = AccessChain(pointerType, SupportBuffer, fieldIndex, scaleIndex); diff --git a/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs b/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs index 911137649..afe2e5326 100644 --- a/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs +++ b/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs @@ -135,7 +135,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv private static void DeclareSupportBuffer(CodeGenContext context) { - if (!context.Config.Stage.SupportsRenderScale()) + if (!context.Config.Stage.SupportsRenderScale() && !(context.Config.LastInVertexPipeline && context.Config.GpuAccessor.QueryViewportTransformDisable())) { return; } @@ -146,12 +146,13 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv context.Decorate(isBgraArrayType, Decoration.ArrayStride, (LiteralInteger)SupportBuffer.FieldSize); context.Decorate(renderScaleArrayType, Decoration.ArrayStride, (LiteralInteger)SupportBuffer.FieldSize); - var supportBufferStructType = context.TypeStruct(false, context.TypeU32(), isBgraArrayType, context.TypeS32(), renderScaleArrayType); + var supportBufferStructType = context.TypeStruct(false, context.TypeU32(), isBgraArrayType, context.GetType(AggregateType.FP32 | AggregateType.Vector), context.TypeS32(), renderScaleArrayType); context.MemberDecorate(supportBufferStructType, 0, Decoration.Offset, (LiteralInteger)SupportBuffer.FragmentAlphaTestOffset); context.MemberDecorate(supportBufferStructType, 1, Decoration.Offset, (LiteralInteger)SupportBuffer.FragmentIsBgraOffset); - context.MemberDecorate(supportBufferStructType, 2, Decoration.Offset, (LiteralInteger)SupportBuffer.FragmentRenderScaleCountOffset); - context.MemberDecorate(supportBufferStructType, 3, Decoration.Offset, (LiteralInteger)SupportBuffer.GraphicsRenderScaleOffset); + context.MemberDecorate(supportBufferStructType, 2, Decoration.Offset, (LiteralInteger)SupportBuffer.ViewportInverseOffset); + context.MemberDecorate(supportBufferStructType, 3, Decoration.Offset, (LiteralInteger)SupportBuffer.FragmentRenderScaleCountOffset); + context.MemberDecorate(supportBufferStructType, 4, Decoration.Offset, (LiteralInteger)SupportBuffer.GraphicsRenderScaleOffset); context.Decorate(supportBufferStructType, Decoration.Block); var supportBufferPointerType = context.TypePointer(StorageClass.Uniform, supportBufferStructType); @@ -698,6 +699,8 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv AttributeConsts.GtMask => BuiltIn.SubgroupGtMask, AttributeConsts.LeMask => BuiltIn.SubgroupLeMask, AttributeConsts.LtMask => BuiltIn.SubgroupLtMask, + AttributeConsts.SupportBlockViewInverseX => BuiltIn.Position, + AttributeConsts.SupportBlockViewInverseY => BuiltIn.Position, _ => throw new ArgumentException($"Invalid attribute number 0x{attr:X}.") }; } diff --git a/Ryujinx.Graphics.Shader/CodeGen/Spirv/ScalingHelpers.cs b/Ryujinx.Graphics.Shader/CodeGen/Spirv/ScalingHelpers.cs index 5c9e36413..8503771c3 100644 --- a/Ryujinx.Graphics.Shader/CodeGen/Spirv/ScalingHelpers.cs +++ b/Ryujinx.Graphics.Shader/CodeGen/Spirv/ScalingHelpers.cs @@ -57,13 +57,13 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv private static SpvInstruction ApplyScaling2D(CodeGenContext context, SpvInstruction vector, int index) { var pointerType = context.TypePointer(StorageClass.Uniform, context.TypeFP32()); - var fieldIndex = context.Constant(context.TypeU32(), 3); + var fieldIndex = context.Constant(context.TypeU32(), 4); var scaleIndex = context.Constant(context.TypeU32(), index); if (context.Config.Stage == ShaderStage.Vertex) { var scaleCountPointerType = context.TypePointer(StorageClass.Uniform, context.TypeS32()); - var scaleCountElemPointer = context.AccessChain(scaleCountPointerType, context.SupportBuffer, context.Constant(context.TypeU32(), 2)); + var scaleCountElemPointer = context.AccessChain(scaleCountPointerType, context.SupportBuffer, context.Constant(context.TypeU32(), 3)); var scaleCount = context.Load(context.TypeS32(), scaleCountElemPointer); scaleIndex = context.IAdd(context.TypeU32(), scaleIndex, scaleCount); @@ -195,13 +195,13 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv int index = context.Config.FindTextureDescriptorIndex(texOp); var pointerType = context.TypePointer(StorageClass.Uniform, context.TypeFP32()); - var fieldIndex = context.Constant(context.TypeU32(), 3); + var fieldIndex = context.Constant(context.TypeU32(), 4); var scaleIndex = context.Constant(context.TypeU32(), index); if (context.Config.Stage == ShaderStage.Vertex) { var scaleCountPointerType = context.TypePointer(StorageClass.Uniform, context.TypeS32()); - var scaleCountElemPointer = context.AccessChain(scaleCountPointerType, context.SupportBuffer, context.Constant(context.TypeU32(), 2)); + var scaleCountElemPointer = context.AccessChain(scaleCountPointerType, context.SupportBuffer, context.Constant(context.TypeU32(), 3)); var scaleCount = context.Load(context.TypeS32(), scaleCountElemPointer); scaleIndex = context.IAdd(context.TypeU32(), scaleIndex, scaleCount); diff --git a/Ryujinx.Graphics.Shader/Translation/AttributeInfo.cs b/Ryujinx.Graphics.Shader/Translation/AttributeInfo.cs index ffe9d9e75..22b9ba9b0 100644 --- a/Ryujinx.Graphics.Shader/Translation/AttributeInfo.cs +++ b/Ryujinx.Graphics.Shader/Translation/AttributeInfo.cs @@ -111,6 +111,10 @@ namespace Ryujinx.Graphics.Shader.Translation { return new AttributeInfo(value & ~0xf, (value >> 2) & 3, 4, AggregateType.Vector | AggregateType.FP32, false); } + else if (value == AttributeConsts.SupportBlockViewInverseX || value == AttributeConsts.SupportBlockViewInverseY) + { + return new AttributeInfo(value, 0, 1, AggregateType.FP32); + } else if (BuiltInAttributes.TryGetValue(value, out AttributeInfo info)) { return info;