diff options
author | gdkchan <gab.dark.100@gmail.com> | 2023-05-20 16:19:26 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-20 16:19:26 -0300 |
commit | 402f05b8ef013807997589ecc0a8ff50267dcd23 (patch) | |
tree | 8e3b06c2ce3e3ccd4b443a4c68365251acc668fa /src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs | |
parent | fb27042e01b0fa110184673d436ec96ec8cf20c7 (diff) |
Replace constant buffer access on shader with new Load instruction (#4646)1.1.811
Diffstat (limited to 'src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs')
-rw-r--r-- | src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs | 129 |
1 files changed, 48 insertions, 81 deletions
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs index 821da477..7c242589 100644 --- a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs +++ b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs @@ -98,8 +98,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv DeclareLocalMemory(context, localMemorySize); } - DeclareSupportBuffer(context); - DeclareUniformBuffers(context, context.Config.GetConstantBufferDescriptors()); + DeclareConstantBuffers(context, context.Config.Properties.ConstantBuffers.Values); DeclareStorageBuffers(context, context.Config.GetStorageBufferDescriptors()); DeclareSamplers(context, context.Config.GetTextureDescriptors()); DeclareImages(context, context.Config.GetImageDescriptors()); @@ -127,84 +126,63 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv return variable; } - private static void DeclareSupportBuffer(CodeGenContext context) + private static void DeclareConstantBuffers(CodeGenContext context, IEnumerable<BufferDefinition> buffers) { - if (!context.Config.Stage.SupportsRenderScale() && !(context.Config.LastInVertexPipeline && context.Config.GpuAccessor.QueryViewportTransformDisable())) - { - return; - } - - var isBgraArrayType = context.TypeArray(context.TypeU32(), context.Constant(context.TypeU32(), SupportBuffer.FragmentIsBgraCount)); - var viewportInverseVectorType = context.TypeVector(context.TypeFP32(), 4); - var renderScaleArrayType = context.TypeArray(context.TypeFP32(), context.Constant(context.TypeU32(), SupportBuffer.RenderScaleMaxCount)); - - context.Decorate(isBgraArrayType, Decoration.ArrayStride, (LiteralInteger)SupportBuffer.FieldSize); - context.Decorate(renderScaleArrayType, Decoration.ArrayStride, (LiteralInteger)SupportBuffer.FieldSize); - - var supportBufferStructType = context.TypeStruct(false, context.TypeU32(), isBgraArrayType, viewportInverseVectorType, context.TypeS32(), renderScaleArrayType); + HashSet<SpvInstruction> decoratedTypes = new HashSet<SpvInstruction>(); - 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.ViewportInverseOffset); - context.MemberDecorate(supportBufferStructType, 3, Decoration.Offset, (LiteralInteger)SupportBuffer.FragmentRenderScaleCountOffset); - context.MemberDecorate(supportBufferStructType, 4, Decoration.Offset, (LiteralInteger)SupportBuffer.GraphicsRenderScaleOffset); - context.Decorate(supportBufferStructType, Decoration.Block); + foreach (BufferDefinition buffer in buffers) + { + int alignment = buffer.Layout == BufferLayout.Std140 ? 16 : 4; + int alignmentMask = alignment - 1; + int offset = 0; - var supportBufferPointerType = context.TypePointer(StorageClass.Uniform, supportBufferStructType); - var supportBufferVariable = context.Variable(supportBufferPointerType, StorageClass.Uniform); + SpvInstruction[] structFieldTypes = new SpvInstruction[buffer.Type.Fields.Length]; + int[] structFieldOffsets = new int[buffer.Type.Fields.Length]; - context.Decorate(supportBufferVariable, Decoration.DescriptorSet, (LiteralInteger)0); - context.Decorate(supportBufferVariable, Decoration.Binding, (LiteralInteger)0); + for (int fieldIndex = 0; fieldIndex < buffer.Type.Fields.Length; fieldIndex++) + { + StructureField field = buffer.Type.Fields[fieldIndex]; + int fieldSize = (field.Type.GetSizeInBytes() + alignmentMask) & ~alignmentMask; - context.AddGlobalVariable(supportBufferVariable); + structFieldTypes[fieldIndex] = context.GetType(field.Type, field.ArrayLength); + structFieldOffsets[fieldIndex] = offset; - context.SupportBuffer = supportBufferVariable; - } + if (field.Type.HasFlag(AggregateType.Array)) + { + // We can't decorate the type more than once. + if (decoratedTypes.Add(structFieldTypes[fieldIndex])) + { + context.Decorate(structFieldTypes[fieldIndex], Decoration.ArrayStride, (LiteralInteger)fieldSize); + } - private static void DeclareUniformBuffers(CodeGenContext context, BufferDescriptor[] descriptors) - { - if (descriptors.Length == 0) - { - return; - } + offset += fieldSize * field.ArrayLength; + } + else + { + offset += fieldSize; + } + } - uint ubSize = Constants.ConstantBufferSize / 16; + var ubStructType = context.TypeStruct(false, structFieldTypes); - var ubArrayType = context.TypeArray(context.TypeVector(context.TypeFP32(), 4), context.Constant(context.TypeU32(), ubSize), true); - context.Decorate(ubArrayType, Decoration.ArrayStride, (LiteralInteger)16); - var ubStructType = context.TypeStruct(true, ubArrayType); - context.Decorate(ubStructType, Decoration.Block); - context.MemberDecorate(ubStructType, 0, Decoration.Offset, (LiteralInteger)0); + if (decoratedTypes.Add(ubStructType)) + { + context.Decorate(ubStructType, Decoration.Block); - if (context.Config.UsedFeatures.HasFlag(FeatureFlags.CbIndexing)) - { - int count = descriptors.Max(x => x.Slot) + 1; + for (int fieldIndex = 0; fieldIndex < structFieldOffsets.Length; fieldIndex++) + { + context.MemberDecorate(ubStructType, fieldIndex, Decoration.Offset, (LiteralInteger)structFieldOffsets[fieldIndex]); + } + } - var ubStructArrayType = context.TypeArray(ubStructType, context.Constant(context.TypeU32(), count)); - var ubPointerType = context.TypePointer(StorageClass.Uniform, ubStructArrayType); + var ubPointerType = context.TypePointer(StorageClass.Uniform, ubStructType); var ubVariable = context.Variable(ubPointerType, StorageClass.Uniform); - context.Name(ubVariable, $"{GetStagePrefix(context.Config.Stage)}_u"); - context.Decorate(ubVariable, Decoration.DescriptorSet, (LiteralInteger)0); - context.Decorate(ubVariable, Decoration.Binding, (LiteralInteger)context.Config.FirstConstantBufferBinding); + context.Name(ubVariable, buffer.Name); + context.Decorate(ubVariable, Decoration.DescriptorSet, (LiteralInteger)buffer.Set); + context.Decorate(ubVariable, Decoration.Binding, (LiteralInteger)buffer.Binding); context.AddGlobalVariable(ubVariable); - - context.UniformBuffersArray = ubVariable; - } - else - { - var ubPointerType = context.TypePointer(StorageClass.Uniform, ubStructType); - - foreach (var descriptor in descriptors) - { - var ubVariable = context.Variable(ubPointerType, StorageClass.Uniform); - - context.Name(ubVariable, $"{GetStagePrefix(context.Config.Stage)}_c{descriptor.Slot}"); - context.Decorate(ubVariable, Decoration.DescriptorSet, (LiteralInteger)0); - context.Decorate(ubVariable, Decoration.Binding, (LiteralInteger)descriptor.Binding); - context.AddGlobalVariable(ubVariable); - context.UniformBuffers.Add(descriptor.Slot, ubVariable); - } + context.ConstantBuffers.Add(buffer.Binding, ubVariable); } } @@ -394,25 +372,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv { foreach (var ioDefinition in info.IoDefinitions) { - var ioVariable = ioDefinition.IoVariable; - - // Those are actually from constant buffer, rather than being actual inputs or outputs, - // so we must ignore them here as they are declared as part of the support buffer. - // TODO: Delete this after we represent this properly on the IR (as a constant buffer rather than "input"). - if (ioVariable == IoVariable.FragmentOutputIsBgra || - ioVariable == IoVariable.SupportBlockRenderScale || - ioVariable == IoVariable.SupportBlockViewInverse) - { - continue; - } - - bool isOutput = ioDefinition.StorageKind.IsOutput(); - bool isPerPatch = ioDefinition.StorageKind.IsPerPatch(); - PixelImap iq = PixelImap.Unused; if (context.Config.Stage == ShaderStage.Fragment) { + var ioVariable = ioDefinition.IoVariable; if (ioVariable == IoVariable.UserDefined) { iq = context.Config.ImapTypes[ioDefinition.Location].GetFirstUsedType(); @@ -429,6 +393,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv } } + bool isOutput = ioDefinition.StorageKind.IsOutput(); + bool isPerPatch = ioDefinition.StorageKind.IsPerPatch(); + DeclareInputOrOutput(context, ioDefinition, isOutput, isPerPatch, iq); } } |