aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Shader/Translation
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics.Shader/Translation')
-rw-r--r--Ryujinx.Graphics.Shader/Translation/Rewriter.cs16
-rw-r--r--Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs80
-rw-r--r--Ryujinx.Graphics.Shader/Translation/TranslationCounts.cs36
-rw-r--r--Ryujinx.Graphics.Shader/Translation/Translator.cs52
-rw-r--r--Ryujinx.Graphics.Shader/Translation/TranslatorContext.cs20
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);
}
}
}