diff options
Diffstat (limited to 'Ryujinx.Graphics.Shader/Translation')
5 files changed, 80 insertions, 124 deletions
diff --git a/Ryujinx.Graphics.Shader/Translation/Rewriter.cs b/Ryujinx.Graphics.Shader/Translation/Rewriter.cs index 910faf1c..e9b073ab 100644 --- a/Ryujinx.Graphics.Shader/Translation/Rewriter.cs +++ b/Ryujinx.Graphics.Shader/Translation/Rewriter.cs @@ -164,9 +164,9 @@ namespace Ryujinx.Graphics.Shader.Translation bool isBindless = (texOp.Flags & TextureFlags.Bindless) != 0; - bool isRect = !isBindless && config.GpuAccessor.QueryIsTextureRectangle(texOp.Handle, texOp.CbufSlot); + bool isCoordNormalized = !isBindless && config.GpuAccessor.QueryTextureCoordNormalized(texOp.Handle, texOp.CbufSlot); - if (!(hasInvalidOffset || isRect)) + if (!hasInvalidOffset && isCoordNormalized) { return node; } @@ -263,7 +263,7 @@ namespace Ryujinx.Graphics.Shader.Translation hasInvalidOffset &= !areAllOffsetsConstant; - if (!(hasInvalidOffset || isRect)) + if (!hasInvalidOffset && isCoordNormalized) { return node; } @@ -300,15 +300,17 @@ namespace Ryujinx.Graphics.Shader.Translation return res; } - // Emulate texture rectangle by normalizing the coordinates on the shader. - // When sampler*Rect is used, the coords are expected to the in the [0, W or H] range, + // Emulate non-normalized coordinates by normalizing the coordinates on the shader. + // Without normalization, the coordinates are expected to the in the [0, W or H] range, // and otherwise, it is expected to be in the [0, 1] range. // We normalize by dividing the coords by the texture size. - if (isRect && !intCoords) + if (!isCoordNormalized && !intCoords) { config.SetUsedFeature(FeatureFlags.IntegerSampling); - for (int index = 0; index < coordsCount; index++) + int normCoordsCount = (texOp.Type & SamplerType.Mask) == SamplerType.TextureCube ? 2 : coordsCount; + + for (int index = 0; index < normCoordsCount; index++) { Operand coordSize = Local(); diff --git a/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs b/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs index 6bb045ec..23b8b951 100644 --- a/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs +++ b/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs @@ -41,9 +41,7 @@ namespace Ryujinx.Graphics.Shader.Translation public FeatureFlags UsedFeatures { get; private set; } - public HashSet<int> TextureHandlesForCache { get; } - - private readonly TranslationCounts _counts; + public int Cb1DataSize { get; private set; } public bool NextUsesFixedFuncAttributes { get; private set; } public int UsedInputAttributes { get; private set; } @@ -109,21 +107,22 @@ namespace Ryujinx.Graphics.Shader.Translation private TextureDescriptor[] _cachedTextureDescriptors; private TextureDescriptor[] _cachedImageDescriptors; - public int FirstConstantBufferBinding { get; private set; } - public int FirstStorageBufferBinding { get; private set; } + private int _firstConstantBufferBinding; + private int _firstStorageBufferBinding; + + public int FirstConstantBufferBinding => _firstConstantBufferBinding; + public int FirstStorageBufferBinding => _firstStorageBufferBinding; - public ShaderConfig(IGpuAccessor gpuAccessor, TranslationOptions options, TranslationCounts counts) + public ShaderConfig(IGpuAccessor gpuAccessor, TranslationOptions options) { - Stage = ShaderStage.Compute; - GpuAccessor = gpuAccessor; - Options = options; - _counts = counts; - TextureHandlesForCache = new HashSet<int>(); - _usedTextures = new Dictionary<TextureInfo, TextureMeta>(); - _usedImages = new Dictionary<TextureInfo, TextureMeta>(); + Stage = ShaderStage.Compute; + GpuAccessor = gpuAccessor; + Options = options; + _usedTextures = new Dictionary<TextureInfo, TextureMeta>(); + _usedImages = new Dictionary<TextureInfo, TextureMeta>(); } - public ShaderConfig(ShaderHeader header, IGpuAccessor gpuAccessor, TranslationOptions options, TranslationCounts counts) : this(gpuAccessor, options, counts) + public ShaderConfig(ShaderHeader header, IGpuAccessor gpuAccessor, TranslationOptions options) : this(gpuAccessor, options) { Stage = header.Stage; GpPassthrough = header.Stage == ShaderStage.Geometry && header.GpPassthrough; @@ -144,6 +143,16 @@ namespace Ryujinx.Graphics.Shader.Translation return BitOperations.PopCount((uint)OmapTargets) + 1; } + public uint ConstantBuffer1Read(int offset) + { + if (Cb1DataSize < offset + 4) + { + Cb1DataSize = offset + 4; + } + + return GpuAccessor.ConstantBuffer1Read(offset); + } + public TextureFormat GetTextureFormat(int handle, int cbufSlot = -1) { // When the formatted load extension is supported, we don't need to @@ -197,8 +206,6 @@ namespace Ryujinx.Graphics.Shader.Translation ClipDistancesWritten |= other.ClipDistancesWritten; UsedFeatures |= other.UsedFeatures; - TextureHandlesForCache.UnionWith(other.TextureHandlesForCache); - UsedInputAttributes |= other.UsedInputAttributes; UsedOutputAttributes |= other.UsedOutputAttributes; _usedConstantBuffers |= other._usedConstantBuffers; @@ -391,6 +398,8 @@ namespace Ryujinx.Graphics.Shader.Translation bool intCoords = flags.HasFlag(TextureFlags.IntCoords) || inst == Instruction.TextureSize; SetUsedTextureOrImage(_usedTextures, cbufSlot, handle, type, TextureFormat.Unknown, intCoords, false, accurateType, coherent); } + + GpuAccessor.RegisterTexture(handle, cbufSlot); } private void SetUsedTextureOrImage( @@ -485,13 +494,12 @@ namespace Ryujinx.Graphics.Shader.Translation usedMask |= (int)GpuAccessor.QueryConstantBufferUse(); } - FirstConstantBufferBinding = _counts.UniformBuffersCount; - return _cachedConstantBufferDescriptors = GetBufferDescriptors( usedMask, 0, UsedFeatures.HasFlag(FeatureFlags.CbIndexing), - _counts.IncrementUniformBuffersCount); + out _firstConstantBufferBinding, + GpuAccessor.QueryBindingConstantBuffer); } public BufferDescriptor[] GetStorageBufferDescriptors() @@ -501,21 +509,23 @@ namespace Ryujinx.Graphics.Shader.Translation return _cachedStorageBufferDescriptors; } - FirstStorageBufferBinding = _counts.StorageBuffersCount; - return _cachedStorageBufferDescriptors = GetBufferDescriptors( _usedStorageBuffers, _usedStorageBuffersWrite, true, - _counts.IncrementStorageBuffersCount); + out _firstStorageBufferBinding, + GpuAccessor.QueryBindingStorageBuffer); } private static BufferDescriptor[] GetBufferDescriptors( int usedMask, int writtenMask, bool isArray, - Func<int> getBindingCallback) + out int firstBinding, + Func<int, int> getBindingCallback) { + firstBinding = 0; + bool hasFirstBinding = false; var descriptors = new BufferDescriptor[BitOperations.PopCount((uint)usedMask)]; int lastSlot = -1; @@ -529,13 +539,25 @@ namespace Ryujinx.Graphics.Shader.Translation // The next array entries also consumes bindings, even if they are unused. for (int j = lastSlot + 1; j < slot; j++) { - getBindingCallback(); + int binding = getBindingCallback(j); + + if (!hasFirstBinding) + { + firstBinding = binding; + hasFirstBinding = true; + } } } lastSlot = slot; - descriptors[i] = new BufferDescriptor(getBindingCallback(), slot); + descriptors[i] = new BufferDescriptor(getBindingCallback(slot), slot); + + if (!hasFirstBinding) + { + firstBinding = descriptors[i].Binding; + hasFirstBinding = true; + } if ((writtenMask & (1 << slot)) != 0) { @@ -550,15 +572,15 @@ namespace Ryujinx.Graphics.Shader.Translation public TextureDescriptor[] GetTextureDescriptors() { - return _cachedTextureDescriptors ??= GetTextureOrImageDescriptors(_usedTextures, _counts.IncrementTexturesCount); + return _cachedTextureDescriptors ??= GetTextureOrImageDescriptors(_usedTextures, GpuAccessor.QueryBindingTexture); } public TextureDescriptor[] GetImageDescriptors() { - return _cachedImageDescriptors ??= GetTextureOrImageDescriptors(_usedImages, _counts.IncrementImagesCount); + return _cachedImageDescriptors ??= GetTextureOrImageDescriptors(_usedImages, GpuAccessor.QueryBindingImage); } - private static TextureDescriptor[] GetTextureOrImageDescriptors(Dictionary<TextureInfo, TextureMeta> dict, Func<int> getBindingCallback) + private static TextureDescriptor[] GetTextureOrImageDescriptors(Dictionary<TextureInfo, TextureMeta> dict, Func<int, int> getBindingCallback) { var descriptors = new TextureDescriptor[dict.Count]; @@ -568,7 +590,7 @@ namespace Ryujinx.Graphics.Shader.Translation var info = kv.Key; var meta = kv.Value; - int binding = getBindingCallback(); + int binding = getBindingCallback(i); descriptors[i] = new TextureDescriptor(binding, meta.Type, info.Format, info.CbufSlot, info.Handle); descriptors[i].SetFlag(meta.UsageFlags); diff --git a/Ryujinx.Graphics.Shader/Translation/TranslationCounts.cs b/Ryujinx.Graphics.Shader/Translation/TranslationCounts.cs deleted file mode 100644 index 6751d7ea..00000000 --- a/Ryujinx.Graphics.Shader/Translation/TranslationCounts.cs +++ /dev/null @@ -1,36 +0,0 @@ -namespace Ryujinx.Graphics.Shader.Translation -{ - public class TranslationCounts - { - public int UniformBuffersCount { get; private set; } - public int StorageBuffersCount { get; private set; } - public int TexturesCount { get; private set; } - public int ImagesCount { get; private set; } - - public TranslationCounts() - { - // The first binding is reserved for the support buffer. - UniformBuffersCount = 1; - } - - internal int IncrementUniformBuffersCount() - { - return UniformBuffersCount++; - } - - internal int IncrementStorageBuffersCount() - { - return StorageBuffersCount++; - } - - internal int IncrementTexturesCount() - { - return TexturesCount++; - } - - internal int IncrementImagesCount() - { - return ImagesCount++; - } - } -} diff --git a/Ryujinx.Graphics.Shader/Translation/Translator.cs b/Ryujinx.Graphics.Shader/Translation/Translator.cs index 5119dfb6..e1614e66 100644 --- a/Ryujinx.Graphics.Shader/Translation/Translator.cs +++ b/Ryujinx.Graphics.Shader/Translation/Translator.cs @@ -25,18 +25,12 @@ namespace Ryujinx.Graphics.Shader.Translation } } - public static TranslatorContext CreateContext( - ulong address, - IGpuAccessor gpuAccessor, - TranslationOptions options, - TranslationCounts counts = null) + public static TranslatorContext CreateContext(ulong address, IGpuAccessor gpuAccessor, TranslationOptions options) { - counts ??= new TranslationCounts(); - - return DecodeShader(address, gpuAccessor, options, counts); + return DecodeShader(address, gpuAccessor, options); } - internal static ShaderProgram Translate(FunctionCode[] functions, ShaderConfig config, out ShaderProgramInfo shaderProgramInfo) + internal static ShaderProgram Translate(FunctionCode[] functions, ShaderConfig config) { var cfgs = new ControlFlowGraph[functions.Length]; var frus = new RegisterUsage.FunctionRegisterUsage[functions.Length]; @@ -87,31 +81,25 @@ namespace Ryujinx.Graphics.Shader.Translation StructuredProgramInfo sInfo = StructuredProgram.MakeStructuredProgram(funcs, config); - ShaderProgram program; - - switch (config.Options.TargetLanguage) - { - case TargetLanguage.Glsl: - program = new ShaderProgram(config.Stage, GlslGenerator.Generate(sInfo, config)); - break; - default: - throw new NotImplementedException(config.Options.TargetLanguage.ToString()); - } - - shaderProgramInfo = new ShaderProgramInfo( + ShaderProgramInfo info = new ShaderProgramInfo( config.GetConstantBufferDescriptors(), config.GetStorageBufferDescriptors(), config.GetTextureDescriptors(), config.GetImageDescriptors(), + config.Stage, config.UsedFeatures.HasFlag(FeatureFlags.InstanceId), config.UsedFeatures.HasFlag(FeatureFlags.RtLayer), config.ClipDistancesWritten, config.OmapTargets); - return program; + return config.Options.TargetLanguage switch + { + TargetLanguage.Glsl => new ShaderProgram(info, TargetLanguage.Glsl, GlslGenerator.Generate(sInfo, config)), + _ => throw new NotImplementedException(config.Options.TargetLanguage.ToString()) + }; } - private static TranslatorContext DecodeShader(ulong address, IGpuAccessor gpuAccessor, TranslationOptions options, TranslationCounts counts) + private static TranslatorContext DecodeShader(ulong address, IGpuAccessor gpuAccessor, TranslationOptions options) { ShaderConfig config; DecodedProgram program; @@ -119,13 +107,13 @@ namespace Ryujinx.Graphics.Shader.Translation if ((options.Flags & TranslationFlags.Compute) != 0) { - config = new ShaderConfig(gpuAccessor, options, counts); + config = new ShaderConfig(gpuAccessor, options); program = Decoder.Decode(config, address); } else { - config = new ShaderConfig(new ShaderHeader(gpuAccessor, address), gpuAccessor, options, counts); + config = new ShaderConfig(new ShaderHeader(gpuAccessor, address), gpuAccessor, options); program = Decoder.Decode(config, address + HeaderSize); } @@ -138,20 +126,6 @@ namespace Ryujinx.Graphics.Shader.Translation { maxEndAddress = block.EndAddress; } - - if (!config.UsedFeatures.HasFlag(FeatureFlags.Bindless)) - { - for (int index = 0; index < block.OpCodes.Count; index++) - { - InstOp op = block.OpCodes[index]; - - if (op.Props.HasFlag(InstProps.Tex)) - { - int tidB = (int)((op.RawOpCode >> 36) & 0x1fff); - config.TextureHandlesForCache.Add(tidB); - } - } - } } } diff --git a/Ryujinx.Graphics.Shader/Translation/TranslatorContext.cs b/Ryujinx.Graphics.Shader/Translation/TranslatorContext.cs index b4e61cb6..8900f9fe 100644 --- a/Ryujinx.Graphics.Shader/Translation/TranslatorContext.cs +++ b/Ryujinx.Graphics.Shader/Translation/TranslatorContext.cs @@ -16,10 +16,7 @@ namespace Ryujinx.Graphics.Shader.Translation public ShaderStage Stage => _config.Stage; public int Size => _config.Size; - - public FeatureFlags UsedFeatures => _config.UsedFeatures; - - public HashSet<int> TextureHandlesForCache => _config.TextureHandlesForCache; + public int Cb1DataSize => _config.Cb1DataSize; public IGpuAccessor GpuAccessor => _config.GpuAccessor; @@ -129,16 +126,13 @@ namespace Ryujinx.Graphics.Shader.Translation return output; } - public ShaderProgram Translate( - out ShaderProgramInfo shaderProgramInfo, - TranslatorContext nextStage = null, - TranslatorContext other = null) + public void SetNextStage(TranslatorContext nextStage) { - if (nextStage != null) - { - _config.MergeFromtNextStage(nextStage._config); - } + _config.MergeFromtNextStage(nextStage._config); + } + public ShaderProgram Translate(TranslatorContext other = null) + { FunctionCode[] code = EmitShader(_program, _config, initializeOutputs: other == null, out _); if (other != null) @@ -152,7 +146,7 @@ namespace Ryujinx.Graphics.Shader.Translation _config.InheritFrom(other._config); } - return Translator.Translate(code, _config, out shaderProgramInfo); + return Translator.Translate(code, _config); } } } |
