diff --git a/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs b/Ryujinx.Graphics.Gpu/Shader/DiskCache/DiskCacheHostStorage.cs index 3eb8bfde0..1357c1aae 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 = 5; + private const uint CodeGenVersion = 6; private const string SharedTocFileName = "shared.toc"; private const string SharedDataFileName = "shared.data"; diff --git a/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs b/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs index d160671ca..c0ab48236 100644 --- a/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs +++ b/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs @@ -893,24 +893,56 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv var i2 = context.ShiftRightArithmetic(context.TypeS32(), src2, context.Constant(context.TypeS32(), 2)); var i3 = context.BitwiseAnd(context.TypeS32(), src2, context.Constant(context.TypeS32(), 3)); - SpvInstruction elemPointer; + SpvInstruction value = null; - if (context.UniformBuffersArray != null) + if (context.Config.GpuAccessor.QueryHostHasVectorIndexingBug()) { - var ubVariable = context.UniformBuffersArray; - var i0 = context.Get(AggregateType.S32, src1); + // Test for each component individually. + for (int i = 0; i < 4; i++) + { + var component = context.Constant(context.TypeS32(), i); - elemPointer = context.AccessChain(context.TypePointer(StorageClass.Uniform, context.TypeFP32()), ubVariable, i0, i1, i2, i3); + SpvInstruction elemPointer; + if (context.UniformBuffersArray != null) + { + var ubVariable = context.UniformBuffersArray; + var i0 = context.Get(AggregateType.S32, src1); + + elemPointer = context.AccessChain(context.TypePointer(StorageClass.Uniform, context.TypeFP32()), ubVariable, i0, i1, i2, component); + } + else + { + var ubVariable = context.UniformBuffers[((AstOperand)src1).Value]; + + elemPointer = context.AccessChain(context.TypePointer(StorageClass.Uniform, context.TypeFP32()), ubVariable, i1, i2, component); + } + + SpvInstruction newValue = context.Load(context.TypeFP32(), elemPointer); + + value = value != null ? context.Select(context.TypeFP32(), context.IEqual(context.TypeBool(), i3, component), newValue, value) : newValue; + } } else { - var ubVariable = context.UniformBuffers[((AstOperand)src1).Value]; + SpvInstruction elemPointer; - elemPointer = context.AccessChain(context.TypePointer(StorageClass.Uniform, context.TypeFP32()), ubVariable, i1, i2, i3); + if (context.UniformBuffersArray != null) + { + var ubVariable = context.UniformBuffersArray; + var i0 = context.Get(AggregateType.S32, src1); + + elemPointer = context.AccessChain(context.TypePointer(StorageClass.Uniform, context.TypeFP32()), ubVariable, i0, i1, i2, i3); + } + else + { + var ubVariable = context.UniformBuffers[((AstOperand)src1).Value]; + + elemPointer = context.AccessChain(context.TypePointer(StorageClass.Uniform, context.TypeFP32()), ubVariable, i1, i2, i3); + } + + value = context.Load(context.TypeFP32(), elemPointer); } - var value = context.Load(context.TypeFP32(), elemPointer); - return new OperationResult(AggregateType.FP32, value); } diff --git a/Ryujinx.Graphics.Vulkan/Vendor.cs b/Ryujinx.Graphics.Vulkan/Vendor.cs index b9d9849ec..d55a8b3db 100644 --- a/Ryujinx.Graphics.Vulkan/Vendor.cs +++ b/Ryujinx.Graphics.Vulkan/Vendor.cs @@ -5,6 +5,7 @@ namespace Ryujinx.Graphics.Vulkan Amd, Intel, Nvidia, + Qualcomm, Unknown } } diff --git a/Ryujinx.Graphics.Vulkan/VulkanGraphicsDevice.cs b/Ryujinx.Graphics.Vulkan/VulkanGraphicsDevice.cs index 7fd515b04..c61ef6aca 100644 --- a/Ryujinx.Graphics.Vulkan/VulkanGraphicsDevice.cs +++ b/Ryujinx.Graphics.Vulkan/VulkanGraphicsDevice.cs @@ -310,7 +310,7 @@ namespace Ryujinx.Graphics.Vulkan api: TargetApi.Vulkan, GpuVendor, hasFrontFacingBug: IsIntelWindows, - hasVectorIndexingBug: false, + hasVectorIndexingBug: Vendor == Vendor.Qualcomm, supportsAstcCompression: features.TextureCompressionAstcLdr, supports3DTextureCompression: true, supportsBgraFormat: true, @@ -386,6 +386,7 @@ namespace Ryujinx.Graphics.Vulkan 0x1002 => Vendor.Amd, 0x10DE => Vendor.Nvidia, 0x8086 => Vendor.Intel, + 0x5143 => Vendor.Qualcomm, _ => Vendor.Unknown };