diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs index 608107bc3..094040013 100644 --- a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs +++ b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs @@ -780,6 +780,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions } if (context.Config.Stage.SupportsRenderScale() && + (texOp.Index < 2 || (texOp.Type & SamplerType.Mask) == SamplerType.Texture3D) && !isBindless && !isIndexed) { diff --git a/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs b/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs index b663fbbf2..7c710d869 100644 --- a/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs +++ b/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs @@ -1733,8 +1733,14 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv var type = context.SamplersTypes[meta]; bool hasLod = !type.HasFlag(SamplerType.Multisample) && type != SamplerType.TextureBuffer; - int components = (type & SamplerType.Mask) == SamplerType.TextureCube ? 2 : type.GetDimensions(); - var resultType = components == 1 ? context.TypeS32() : context.TypeVector(context.TypeS32(), components); + int dimensions = (type & SamplerType.Mask) == SamplerType.TextureCube ? 2 : type.GetDimensions(); + + if (type.HasFlag(SamplerType.Array)) + { + dimensions++; + } + + var resultType = dimensions == 1 ? context.TypeS32() : context.TypeVector(context.TypeS32(), dimensions); SpvInstruction result; @@ -1749,12 +1755,15 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv result = context.ImageQuerySize(resultType, image); } - if (components != 1) + if (dimensions != 1) { result = context.CompositeExtract(context.TypeS32(), result, (SpvLiteralInteger)texOp.Index); } - result = ScalingHelpers.ApplyUnscaling(context, texOp, result, isBindless, isIndexed); + if (texOp.Index < 2 || (type & SamplerType.Mask) == SamplerType.Texture3D) + { + result = ScalingHelpers.ApplyUnscaling(context, texOp, result, isBindless, isIndexed); + } return new OperationResult(AggregateType.S32, result); } diff --git a/Ryujinx.Graphics.Shader/CodeGen/Spirv/ScalingHelpers.cs b/Ryujinx.Graphics.Shader/CodeGen/Spirv/ScalingHelpers.cs index f0e7f911c..5c9e36413 100644 --- a/Ryujinx.Graphics.Shader/CodeGen/Spirv/ScalingHelpers.cs +++ b/Ryujinx.Graphics.Shader/CodeGen/Spirv/ScalingHelpers.cs @@ -105,9 +105,20 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv context.AddLabel(mergeLabel); - var passthroughVector = context.CompositeConstruct(context.TypeVector(context.TypeBool(), 2), passthrough, passthrough); + var passthroughLabel = context.Label(); + var finalMergeLabel = context.Label(); - return context.Select(ivector2Type, passthroughVector, vector, context.Load(ivector2Type, localVector)); + context.SelectionMerge(finalMergeLabel, SelectionControlMask.MaskNone); + context.BranchConditional(passthrough, passthroughLabel, finalMergeLabel); + + context.AddLabel(passthroughLabel); + + context.Store(localVector, vector); + context.Branch(finalMergeLabel); + + context.AddLabel(finalMergeLabel); + + return context.Load(ivector2Type, localVector); } else { @@ -149,7 +160,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv var fragCoord = context.Load(context.TypeVector(context.TypeFP32(), 4), fragCoordPointer); var fragCoordXY = context.VectorShuffle(vector2Type, fragCoord, fragCoord, 0, 1); - var scaleMod = context.FMod(vector2Type, scaleVector, fragCoordXY); + var scaleMod = context.FMod(vector2Type, fragCoordXY, scaleVector); var vectorInterpolated = context.FAdd(vector2Type, vectorScaled, scaleMod); context.Store(output, context.ConvertFToS(context.TypeVector(context.TypeS32(), 2), vectorInterpolated)); @@ -199,12 +210,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv scaleIndex = context.IAdd(context.TypeU32(), scaleIndex, context.Constant(context.TypeU32(), 1)); var scaleElemPointer = context.AccessChain(pointerType, context.SupportBuffer, fieldIndex, scaleIndex); - var scale = context.Load(context.TypeFP32(), scaleElemPointer); + var scale = context.GlslFAbs(context.TypeFP32(), context.Load(context.TypeFP32(), scaleElemPointer)); var passthrough = context.FOrdEqual(context.TypeBool(), scale, context.Constant(context.TypeFP32(), 1f)); var sizeFloat = context.ConvertSToF(context.TypeFP32(), size); - var sizeUnscaled = context.FDiv(context.TypeFP32(), size, scale); + var sizeUnscaled = context.FDiv(context.TypeFP32(), sizeFloat, scale); var sizeUnscaledInt = context.ConvertFToS(context.TypeS32(), sizeUnscaled); return context.Select(context.TypeS32(), passthrough, size, sizeUnscaledInt);