aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.Shader
diff options
context:
space:
mode:
Diffstat (limited to 'src/Ryujinx.Graphics.Shader')
-rw-r--r--src/Ryujinx.Graphics.Shader/BufferDescriptor.cs7
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs8
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs6
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs6
-rw-r--r--src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs18
-rw-r--r--src/Ryujinx.Graphics.Shader/IGpuAccessor.cs25
-rw-r--r--src/Ryujinx.Graphics.Shader/Instructions/InstEmitSurface.cs20
-rw-r--r--src/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs18
-rw-r--r--src/Ryujinx.Graphics.Shader/IntermediateRepresentation/TextureOperation.cs22
-rw-r--r--src/Ryujinx.Graphics.Shader/SetBindingPair.cs4
-rw-r--r--src/Ryujinx.Graphics.Shader/StructuredIr/AstTextureOperation.cs16
-rw-r--r--src/Ryujinx.Graphics.Shader/StructuredIr/ShaderProperties.cs16
-rw-r--r--src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs12
-rw-r--r--src/Ryujinx.Graphics.Shader/TextureDescriptor.cs3
-rw-r--r--src/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs4
-rw-r--r--src/Ryujinx.Graphics.Shader/Translation/EmitterContextInsts.cs91
-rw-r--r--src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs12
-rw-r--r--src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessToArray.cs4
-rw-r--r--src/Ryujinx.Graphics.Shader/Translation/ResourceManager.cs98
-rw-r--r--src/Ryujinx.Graphics.Shader/Translation/ResourceReservations.cs17
-rw-r--r--src/Ryujinx.Graphics.Shader/Translation/Transforms/TexturePass.cs7
-rw-r--r--src/Ryujinx.Graphics.Shader/Translation/Transforms/VertexToCompute.cs8
-rw-r--r--src/Ryujinx.Graphics.Shader/Translation/TranslatorContext.cs12
23 files changed, 300 insertions, 134 deletions
diff --git a/src/Ryujinx.Graphics.Shader/BufferDescriptor.cs b/src/Ryujinx.Graphics.Shader/BufferDescriptor.cs
index ead1c5e6..11d4e3c1 100644
--- a/src/Ryujinx.Graphics.Shader/BufferDescriptor.cs
+++ b/src/Ryujinx.Graphics.Shader/BufferDescriptor.cs
@@ -4,14 +4,16 @@ namespace Ryujinx.Graphics.Shader
{
// New fields should be added to the end of the struct to keep disk shader cache compatibility.
+ public readonly int Set;
public readonly int Binding;
public readonly byte Slot;
public readonly byte SbCbSlot;
public readonly ushort SbCbOffset;
public readonly BufferUsageFlags Flags;
- public BufferDescriptor(int binding, int slot)
+ public BufferDescriptor(int set, int binding, int slot)
{
+ Set = set;
Binding = binding;
Slot = (byte)slot;
SbCbSlot = 0;
@@ -19,8 +21,9 @@ namespace Ryujinx.Graphics.Shader
Flags = BufferUsageFlags.None;
}
- public BufferDescriptor(int binding, int slot, int sbCbSlot, int sbCbOffset, BufferUsageFlags flags)
+ public BufferDescriptor(int set, int binding, int slot, int sbCbSlot, int sbCbOffset, BufferUsageFlags flags)
{
+ Set = set;
Binding = binding;
Slot = (byte)slot;
SbCbSlot = (byte)sbCbSlot;
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs
index f0e57b53..4308b08f 100644
--- a/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs
@@ -462,7 +462,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
}
else
{
- context.Properties.Textures.TryGetValue(texOp.Binding, out TextureDefinition definition);
+ context.Properties.Textures.TryGetValue(texOp.GetTextureSetAndBinding(), out TextureDefinition definition);
bool hasLod = !definition.Type.HasFlag(SamplerType.Multisample) && (definition.Type & SamplerType.Mask) != SamplerType.TextureBuffer;
string texCall;
@@ -639,7 +639,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
private static string GetSamplerName(CodeGenContext context, AstTextureOperation texOp, ref int srcIndex)
{
- TextureDefinition textureDefinition = context.Properties.Textures[texOp.Binding];
+ TextureDefinition textureDefinition = context.Properties.Textures[texOp.GetTextureSetAndBinding()];
string name = textureDefinition.Name;
if (textureDefinition.ArrayLength != 1)
@@ -649,7 +649,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
if (texOp.IsSeparate)
{
- TextureDefinition samplerDefinition = context.Properties.Textures[texOp.SamplerBinding];
+ TextureDefinition samplerDefinition = context.Properties.Textures[texOp.GetSamplerSetAndBinding()];
string samplerName = samplerDefinition.Name;
if (samplerDefinition.ArrayLength != 1)
@@ -665,7 +665,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
private static string GetImageName(CodeGenContext context, AstTextureOperation texOp, ref int srcIndex)
{
- TextureDefinition definition = context.Properties.Images[texOp.Binding];
+ TextureDefinition definition = context.Properties.Images[texOp.GetTextureSetAndBinding()];
string name = definition.Name;
if (definition.ArrayLength != 1)
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs
index 2b1fdf44..f3be29bb 100644
--- a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/CodeGenContext.cs
@@ -33,9 +33,9 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
public Dictionary<int, Instruction> LocalMemories { get; } = new();
public Dictionary<int, Instruction> SharedMemories { get; } = new();
- public Dictionary<int, SamplerType> SamplersTypes { get; } = new();
- public Dictionary<int, SamplerDeclaration> Samplers { get; } = new();
- public Dictionary<int, ImageDeclaration> Images { get; } = new();
+ public Dictionary<SetBindingPair, SamplerType> SamplersTypes { get; } = new();
+ public Dictionary<SetBindingPair, SamplerDeclaration> Samplers { get; } = new();
+ public Dictionary<SetBindingPair, ImageDeclaration> Images { get; } = new();
public Dictionary<IoDefinition, Instruction> Inputs { get; } = new();
public Dictionary<IoDefinition, Instruction> Outputs { get; } = new();
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs
index 37df4df8..55d35bf0 100644
--- a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Declarations.cs
@@ -208,13 +208,13 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
var sampledImageVariable = context.Variable(sampledImageArrayPointerType, StorageClass.UniformConstant);
- context.Samplers.Add(sampler.Binding, new SamplerDeclaration(
+ context.Samplers.Add(new(sampler.Set, sampler.Binding), new SamplerDeclaration(
imageType,
sampledImageType,
sampledImagePointerType,
sampledImageVariable,
sampler.ArrayLength != 1));
- context.SamplersTypes.Add(sampler.Binding, sampler.Type);
+ context.SamplersTypes.Add(new(sampler.Set, sampler.Binding), sampler.Type);
context.Name(sampledImageVariable, sampler.Name);
context.Decorate(sampledImageVariable, Decoration.DescriptorSet, (LiteralInteger)setIndex);
@@ -256,7 +256,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
var imageVariable = context.Variable(imageArrayPointerType, StorageClass.UniformConstant);
- context.Images.Add(image.Binding, new ImageDeclaration(imageType, imagePointerType, imageVariable, image.ArrayLength != 1));
+ context.Images.Add(new(image.Set, image.Binding), new ImageDeclaration(imageType, imagePointerType, imageVariable, image.ArrayLength != 1));
context.Name(imageVariable, image.Name);
context.Decorate(imageVariable, Decoration.DescriptorSet, (LiteralInteger)setIndex);
diff --git a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs
index 34f8532a..6206985d 100644
--- a/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs
+++ b/src/Ryujinx.Graphics.Shader/CodeGen/Spirv/Instructions.cs
@@ -602,7 +602,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
return context.Get(type, texOp.GetSource(srcIndex++));
}
- ImageDeclaration declaration = context.Images[texOp.Binding];
+ ImageDeclaration declaration = context.Images[texOp.GetTextureSetAndBinding()];
SpvInstruction image = declaration.Image;
SpvInstruction resultType = context.GetType(componentType);
@@ -681,7 +681,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
return context.Get(type, texOp.GetSource(srcIndex++));
}
- ImageDeclaration declaration = context.Images[texOp.Binding];
+ ImageDeclaration declaration = context.Images[texOp.GetTextureSetAndBinding()];
SpvInstruction image = declaration.Image;
if (declaration.IsIndexed)
@@ -738,7 +738,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
return context.Get(type, texOp.GetSource(srcIndex++));
}
- ImageDeclaration declaration = context.Images[texOp.Binding];
+ ImageDeclaration declaration = context.Images[texOp.GetTextureSetAndBinding()];
SpvInstruction image = declaration.Image;
if (declaration.IsIndexed)
@@ -837,7 +837,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
return context.Get(type, texOp.GetSource(srcIndex++));
}
- SamplerDeclaration declaration = context.Samplers[texOp.Binding];
+ SamplerDeclaration declaration = context.Samplers[texOp.GetTextureSetAndBinding()];
SpvInstruction image = GenerateSampledImageLoad(context, texOp, declaration, ref srcIndex);
int pCount = texOp.Type.GetDimensions();
@@ -1161,7 +1161,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
return context.Get(type, texOp.GetSource(srcIndex++));
}
- SamplerDeclaration declaration = context.Samplers[texOp.Binding];
+ SamplerDeclaration declaration = context.Samplers[texOp.GetTextureSetAndBinding()];
SpvInstruction image = GenerateSampledImageLoad(context, texOp, declaration, ref srcIndex);
int coordsCount = texOp.Type.GetDimensions();
@@ -1433,7 +1433,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
int srcIndex = 0;
- SamplerDeclaration declaration = context.Samplers[texOp.Binding];
+ SamplerDeclaration declaration = context.Samplers[texOp.GetTextureSetAndBinding()];
SpvInstruction image = GenerateSampledImageLoad(context, texOp, declaration, ref srcIndex);
image = context.Image(declaration.ImageType, image);
@@ -1449,7 +1449,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
int srcIndex = 0;
- SamplerDeclaration declaration = context.Samplers[texOp.Binding];
+ SamplerDeclaration declaration = context.Samplers[texOp.GetTextureSetAndBinding()];
SpvInstruction image = GenerateSampledImageLoad(context, texOp, declaration, ref srcIndex);
image = context.Image(declaration.ImageType, image);
@@ -1460,7 +1460,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
}
else
{
- var type = context.SamplersTypes[texOp.Binding];
+ var type = context.SamplersTypes[texOp.GetTextureSetAndBinding()];
bool hasLod = !type.HasFlag(SamplerType.Multisample) && type != SamplerType.TextureBuffer;
int dimensions = (type & SamplerType.Mask) == SamplerType.TextureCube ? 2 : type.GetDimensions();
@@ -1889,7 +1889,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
{
image = context.Load(declaration.ImageType, image);
- SamplerDeclaration samplerDeclaration = context.Samplers[texOp.SamplerBinding];
+ SamplerDeclaration samplerDeclaration = context.Samplers[texOp.GetSamplerSetAndBinding()];
SpvInstruction sampler = samplerDeclaration.Image;
diff --git a/src/Ryujinx.Graphics.Shader/IGpuAccessor.cs b/src/Ryujinx.Graphics.Shader/IGpuAccessor.cs
index 3dc4ad90..4e6d6edf 100644
--- a/src/Ryujinx.Graphics.Shader/IGpuAccessor.cs
+++ b/src/Ryujinx.Graphics.Shader/IGpuAccessor.cs
@@ -27,34 +27,43 @@ namespace Ryujinx.Graphics.Shader
ReadOnlySpan<ulong> GetCode(ulong address, int minimumSize);
/// <summary>
- /// Queries the binding number of a constant buffer.
+ /// Gets the binding number of a constant buffer.
/// </summary>
/// <param name="index">Constant buffer index</param>
/// <returns>Binding number</returns>
- int CreateConstantBufferBinding(int index);
+ SetBindingPair CreateConstantBufferBinding(int index);
/// <summary>
- /// Queries the binding number of an image.
+ /// Gets the binding number of an image.
/// </summary>
/// <param name="count">For array of images, the number of elements of the array, otherwise it should be 1</param>
/// <param name="isBuffer">Indicates if the image is a buffer image</param>
/// <returns>Binding number</returns>
- int CreateImageBinding(int count, bool isBuffer);
+ SetBindingPair CreateImageBinding(int count, bool isBuffer);
/// <summary>
- /// Queries the binding number of a storage buffer.
+ /// Gets the binding number of a storage buffer.
/// </summary>
/// <param name="index">Storage buffer index</param>
/// <returns>Binding number</returns>
- int CreateStorageBufferBinding(int index);
+ SetBindingPair CreateStorageBufferBinding(int index);
/// <summary>
- /// Queries the binding number of a texture.
+ /// Gets the binding number of a texture.
/// </summary>
/// <param name="count">For array of textures, the number of elements of the array, otherwise it should be 1</param>
/// <param name="isBuffer">Indicates if the texture is a buffer texture</param>
/// <returns>Binding number</returns>
- int CreateTextureBinding(int count, bool isBuffer);
+ SetBindingPair CreateTextureBinding(int count, bool isBuffer);
+
+ /// <summary>
+ /// Gets the set index for an additional set, or -1 if there's no extra set available.
+ /// </summary>
+ /// <returns>Extra set index, or -1 if not available</returns>
+ int CreateExtraSet()
+ {
+ return -1;
+ }
/// <summary>
/// Queries Local Size X for compute shaders.
diff --git a/src/Ryujinx.Graphics.Shader/Instructions/InstEmitSurface.cs b/src/Ryujinx.Graphics.Shader/Instructions/InstEmitSurface.cs
index 0aac0ffa..383e82c6 100644
--- a/src/Ryujinx.Graphics.Shader/Instructions/InstEmitSurface.cs
+++ b/src/Ryujinx.Graphics.Shader/Instructions/InstEmitSurface.cs
@@ -278,7 +278,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
flags |= TextureFlags.Bindless;
}
- int binding = isBindless ? 0 : context.ResourceManager.GetTextureOrImageBinding(
+ SetBindingPair setAndBinding = isBindless ? default : context.ResourceManager.GetTextureOrImageBinding(
Instruction.ImageAtomic,
type,
format,
@@ -286,7 +286,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
TextureOperation.DefaultCbufSlot,
imm);
- Operand res = context.ImageAtomic(type, format, flags, binding, sources);
+ Operand res = context.ImageAtomic(type, format, flags, setAndBinding, sources);
context.Copy(d, res);
}
@@ -389,7 +389,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
TextureFormat format = isBindless ? TextureFormat.Unknown : ShaderProperties.GetTextureFormat(context.TranslatorContext.GpuAccessor, handle);
- int binding = isBindless ? 0 : context.ResourceManager.GetTextureOrImageBinding(
+ SetBindingPair setAndBinding = isBindless ? default : context.ResourceManager.GetTextureOrImageBinding(
Instruction.ImageLoad,
type,
format,
@@ -397,7 +397,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
TextureOperation.DefaultCbufSlot,
handle);
- context.ImageLoad(type, format, flags, binding, (int)componentMask, dests, sources);
+ context.ImageLoad(type, format, flags, setAndBinding, (int)componentMask, dests, sources);
}
else
{
@@ -432,7 +432,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
TextureFormat format = GetTextureFormat(size);
- int binding = isBindless ? 0 : context.ResourceManager.GetTextureOrImageBinding(
+ SetBindingPair setAndBinding = isBindless ? default : context.ResourceManager.GetTextureOrImageBinding(
Instruction.ImageLoad,
type,
format,
@@ -440,7 +440,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
TextureOperation.DefaultCbufSlot,
handle);
- context.ImageLoad(type, format, flags, binding, compMask, dests, sources);
+ context.ImageLoad(type, format, flags, setAndBinding, compMask, dests, sources);
switch (size)
{
@@ -552,7 +552,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
flags |= TextureFlags.Bindless;
}
- int binding = isBindless ? 0 : context.ResourceManager.GetTextureOrImageBinding(
+ SetBindingPair setAndBinding = isBindless ? default : context.ResourceManager.GetTextureOrImageBinding(
Instruction.ImageAtomic,
type,
format,
@@ -560,7 +560,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
TextureOperation.DefaultCbufSlot,
imm);
- context.ImageAtomic(type, format, flags, binding, sources);
+ context.ImageAtomic(type, format, flags, setAndBinding, sources);
}
private static void EmitSust(
@@ -679,7 +679,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
flags |= TextureFlags.Coherent;
}
- int binding = isBindless ? 0 : context.ResourceManager.GetTextureOrImageBinding(
+ SetBindingPair setAndBinding = isBindless ? default : context.ResourceManager.GetTextureOrImageBinding(
Instruction.ImageStore,
type,
format,
@@ -687,7 +687,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
TextureOperation.DefaultCbufSlot,
handle);
- context.ImageStore(type, format, flags, binding, sources);
+ context.ImageStore(type, format, flags, setAndBinding, sources);
}
private static int GetComponentSizeInBytesLog2(SuatomSize size)
diff --git a/src/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs b/src/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs
index 06daa26a..2076262d 100644
--- a/src/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs
+++ b/src/Ryujinx.Graphics.Shader/Instructions/InstEmitTexture.cs
@@ -885,7 +885,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
return Register(dest++, RegisterType.Gpr);
}
- int binding = isBindless ? 0 : context.ResourceManager.GetTextureOrImageBinding(
+ SetBindingPair setAndBinding = isBindless ? default : context.ResourceManager.GetTextureOrImageBinding(
Instruction.Lod,
type,
TextureFormat.Unknown,
@@ -913,7 +913,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
else
{
// The instruction component order is the inverse of GLSL's.
- Operand res = context.Lod(type, flags, binding, compIndex ^ 1, sources);
+ Operand res = context.Lod(type, flags, setAndBinding, compIndex ^ 1, sources);
res = context.FPMultiply(res, ConstF(256.0f));
@@ -1116,12 +1116,12 @@ namespace Ryujinx.Graphics.Shader.Instructions
}
TextureFlags flags = isBindless ? TextureFlags.Bindless : TextureFlags.None;
- int binding;
+ SetBindingPair setAndBinding;
switch (query)
{
case TexQuery.TexHeaderDimension:
- binding = isBindless ? 0 : context.ResourceManager.GetTextureOrImageBinding(
+ setAndBinding = isBindless ? default : context.ResourceManager.GetTextureOrImageBinding(
Instruction.TextureQuerySize,
type,
TextureFormat.Unknown,
@@ -1140,13 +1140,13 @@ namespace Ryujinx.Graphics.Shader.Instructions
break;
}
- context.Copy(d, context.TextureQuerySize(type, flags, binding, compIndex, sources));
+ context.Copy(d, context.TextureQuerySize(type, flags, setAndBinding, compIndex, sources));
}
}
break;
case TexQuery.TexHeaderTextureType:
- binding = isBindless ? 0 : context.ResourceManager.GetTextureOrImageBinding(
+ setAndBinding = isBindless ? default : context.ResourceManager.GetTextureOrImageBinding(
Instruction.TextureQuerySamples,
type,
TextureFormat.Unknown,
@@ -1171,7 +1171,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
if (d != null)
{
- context.Copy(d, context.TextureQuerySamples(type, flags, binding, sources));
+ context.Copy(d, context.TextureQuerySamples(type, flags, setAndBinding, sources));
}
}
break;
@@ -1191,7 +1191,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
Operand[] dests,
Operand[] sources)
{
- int binding = flags.HasFlag(TextureFlags.Bindless) ? 0 : context.ResourceManager.GetTextureOrImageBinding(
+ SetBindingPair setAndBinding = flags.HasFlag(TextureFlags.Bindless) ? default : context.ResourceManager.GetTextureOrImageBinding(
Instruction.TextureSample,
type,
TextureFormat.Unknown,
@@ -1199,7 +1199,7 @@ namespace Ryujinx.Graphics.Shader.Instructions
TextureOperation.DefaultCbufSlot,
handle);
- context.TextureSample(type, flags, binding, componentMask, dests, sources);
+ context.TextureSample(type, flags, setAndBinding, componentMask, dests, sources);
}
private static SamplerType ConvertSamplerType(TexDim dimensions)
diff --git a/src/Ryujinx.Graphics.Shader/IntermediateRepresentation/TextureOperation.cs b/src/Ryujinx.Graphics.Shader/IntermediateRepresentation/TextureOperation.cs
index 74ec5ca6..7eee8f2e 100644
--- a/src/Ryujinx.Graphics.Shader/IntermediateRepresentation/TextureOperation.cs
+++ b/src/Ryujinx.Graphics.Shader/IntermediateRepresentation/TextureOperation.cs
@@ -8,7 +8,9 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
public TextureFormat Format { get; set; }
public TextureFlags Flags { get; private set; }
+ public int Set { get; private set; }
public int Binding { get; private set; }
+ public int SamplerSet { get; private set; }
public int SamplerBinding { get; private set; }
public TextureOperation(
@@ -16,6 +18,7 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
SamplerType type,
TextureFormat format,
TextureFlags flags,
+ int set,
int binding,
int compIndex,
Operand[] dests,
@@ -24,24 +27,28 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
Type = type;
Format = format;
Flags = flags;
+ Set = set;
Binding = binding;
+ SamplerSet = -1;
SamplerBinding = -1;
}
- public void TurnIntoArray(int binding)
+ public void TurnIntoArray(SetBindingPair setAndBinding)
{
Flags &= ~TextureFlags.Bindless;
- Binding = binding;
+ Set = setAndBinding.SetIndex;
+ Binding = setAndBinding.Binding;
}
- public void TurnIntoArray(int textureBinding, int samplerBinding)
+ public void TurnIntoArray(SetBindingPair textureSetAndBinding, SetBindingPair samplerSetAndBinding)
{
- TurnIntoArray(textureBinding);
+ TurnIntoArray(textureSetAndBinding);
- SamplerBinding = samplerBinding;
+ SamplerSet = samplerSetAndBinding.SetIndex;
+ SamplerBinding = samplerSetAndBinding.Binding;
}
- public void SetBinding(int binding)
+ public void SetBinding(SetBindingPair setAndBinding)
{
if ((Flags & TextureFlags.Bindless) != 0)
{
@@ -50,7 +57,8 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
RemoveSource(0);
}
- Binding = binding;
+ Set = setAndBinding.SetIndex;
+ Binding = setAndBinding.Binding;
}
public void SetLodLevelFlag()
diff --git a/src/Ryujinx.Graphics.Shader/SetBindingPair.cs b/src/Ryujinx.Graphics.Shader/SetBindingPair.cs
new file mode 100644
index 00000000..1e8a4f9c
--- /dev/null
+++ b/src/Ryujinx.Graphics.Shader/SetBindingPair.cs
@@ -0,0 +1,4 @@
+namespace Ryujinx.Graphics.Shader
+{
+ public readonly record struct SetBindingPair(int SetIndex, int Binding);
+}
diff --git a/src/Ryujinx.Graphics.Shader/StructuredIr/AstTextureOperation.cs b/src/Ryujinx.Graphics.Shader/StructuredIr/AstTextureOperation.cs
index 4068c412..867cae85 100644
--- a/src/Ryujinx.Graphics.Shader/StructuredIr/AstTextureOperation.cs
+++ b/src/Ryujinx.Graphics.Shader/StructuredIr/AstTextureOperation.cs
@@ -8,7 +8,9 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
public TextureFormat Format { get; }
public TextureFlags Flags { get; }
+ public int Set { get; }
public int Binding { get; }
+ public int SamplerSet { get; }
public int SamplerBinding { get; }
public bool IsSeparate => SamplerBinding >= 0;
@@ -18,7 +20,9 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
SamplerType type,
TextureFormat format,
TextureFlags flags,
+ int set,
int binding,
+ int samplerSet,
int samplerBinding,
int index,
params IAstNode[] sources) : base(inst, StorageKind.None, false, index, sources, sources.Length)
@@ -26,8 +30,20 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
Type = type;
Format = format;
Flags = flags;
+ Set = set;
Binding = binding;
+ SamplerSet = samplerSet;
SamplerBinding = samplerBinding;
}
+
+ public SetBindingPair GetTextureSetAndBinding()
+ {
+ return new SetBindingPair(Set, Binding);
+ }
+
+ public SetBindingPair GetSamplerSetAndBinding()
+ {
+ return new SetBindingPair(SamplerSet, SamplerBinding);
+ }
}
}
diff --git a/src/Ryujinx.Graphics.Shader/StructuredIr/ShaderProperties.cs b/src/Ryujinx.Graphics.Shader/StructuredIr/ShaderProperties.cs
index 8c12c2aa..53ed6bfc 100644
--- a/src/Ryujinx.Graphics.Shader/StructuredIr/ShaderProperties.cs
+++ b/src/Ryujinx.Graphics.Shader/StructuredIr/ShaderProperties.cs
@@ -6,15 +6,15 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
{
private readonly Dictionary<int, BufferDefinition> _constantBuffers;
private readonly Dictionary<int, BufferDefinition> _storageBuffers;
- private readonly Dictionary<int, TextureDefinition> _textures;
- private readonly Dictionary<int, TextureDefinition> _images;
+ private readonly Dictionary<SetBindingPair, TextureDefinition> _textures;
+ private readonly Dictionary<SetBindingPair, TextureDefinition> _images;
private readonly Dictionary<int, MemoryDefinition> _localMemories;
private readonly Dictionary<int, MemoryDefinition> _sharedMemories;
public IReadOnlyDictionary<int, BufferDefinition> ConstantBuffers => _constantBuffers;
public IReadOnlyDictionary<int, BufferDefinition> StorageBuffers => _storageBuffers;
- public IReadOnlyDictionary<int, TextureDefinition> Textures => _textures;
- public IReadOnlyDictionary<int, TextureDefinition> Images => _images;
+ public IReadOnlyDictionary<SetBindingPair, TextureDefinition> Textures => _textures;
+ public IReadOnlyDictionary<SetBindingPair, TextureDefinition> Images => _images;
public IReadOnlyDictionary<int, MemoryDefinition> LocalMemories => _localMemories;
public IReadOnlyDictionary<int, MemoryDefinition> SharedMemories => _sharedMemories;
@@ -22,8 +22,8 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
{
_constantBuffers = new Dictionary<int, BufferDefinition>();
_storageBuffers = new Dictionary<int, BufferDefinition>();
- _textures = new Dictionary<int, TextureDefinition>();
- _images = new Dictionary<int, TextureDefinition>();
+ _textures = new Dictionary<SetBindingPair, TextureDefinition>();
+ _images = new Dictionary<SetBindingPair, TextureDefinition>();
_localMemories = new Dictionary<int, MemoryDefinition>();
_sharedMemories = new Dictionary<int, MemoryDefinition>();
}
@@ -40,12 +40,12 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
public void AddOrUpdateTexture(TextureDefinition definition)
{
- _textures[definition.Binding] = definition;
+ _textures[new(definition.Set, definition.Binding)] = definition;
}
public void AddOrUpdateImage(TextureDefinition definition)
{
- _images[definition.Binding] = definition;
+ _images[new(definition.Set, definition.Binding)] = definition;
}
public int AddLocalMemory(MemoryDefinition definition)
diff --git a/src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs b/src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs
index c4ebaee7..88053658 100644
--- a/src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs
+++ b/src/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs
@@ -169,7 +169,17 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
AstTextureOperation GetAstTextureOperation(TextureOperation texOp)
{
- return new AstTextureOperation(inst, texOp.Type, texOp.Format, texOp.Flags, texOp.Binding, texOp.SamplerBinding, texOp.Index, sources);
+ return new AstTextureOperation(
+ inst,
+ texOp.Type,
+ texOp.Format,
+ texOp.Flags,
+ texOp.Set,
+ texOp.Binding,
+ texOp.SamplerSet,
+ texOp.SamplerBinding,
+ texOp.Index,
+ sources);
}
int componentsCount = BitOperations.PopCount((uint)operation.Index);
diff --git a/src/Ryujinx.Graphics.Shader/TextureDescriptor.cs b/src/Ryujinx.Graphics.Shader/TextureDescriptor.cs
index d287a1aa..1e387407 100644
--- a/src/Ryujinx.Graphics.Shader/TextureDescriptor.cs
+++ b/src/Ryujinx.Graphics.Shader/TextureDescriptor.cs
@@ -4,6 +4,7 @@ namespace Ryujinx.Graphics.Shader
{
// New fields should be added to the end of the struct to keep disk shader cache compatibility.
+ public readonly int Set;
public readonly int Binding;
public readonly SamplerType Type;
@@ -18,6 +19,7 @@ namespace Ryujinx.Graphics.Shader
public readonly TextureUsageFlags Flags;
public TextureDescriptor(
+ int set,
int binding,
SamplerType type,
TextureFormat format,
@@ -27,6 +29,7 @@ namespace Ryujinx.Graphics.Shader
bool separate,
TextureUsageFlags flags)
{
+ Set = set;
Binding = binding;
Type = type;
Format = format;
diff --git a/src/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs b/src/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs
index e1157eea..5e07b39f 100644
--- a/src/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs
+++ b/src/Ryujinx.Graphics.Shader/Translation/EmitterContext.cs
@@ -124,7 +124,7 @@ namespace Ryujinx.Graphics.Shader.Translation
this.TextureSample(
SamplerType.TextureBuffer,
TextureFlags.IntCoords,
- ResourceManager.Reservations.IndexBufferTextureBinding,
+ ResourceManager.Reservations.GetIndexBufferTextureSetAndBinding(),
1,
new[] { vertexIndexVr },
new[] { this.IAdd(ibBaseOffset, outputVertexOffset) });
@@ -145,7 +145,7 @@ namespace Ryujinx.Graphics.Shader.Translation
this.TextureSample(
SamplerType.TextureBuffer,
TextureFlags.IntCoords,
- ResourceManager.Reservations.TopologyRemapBufferTextureBinding,
+ ResourceManager.Reservations.GetTopologyRemapBufferTextureSetAndBinding(),
1,
new[] { vertexIndex },
new[] { this.IAdd(baseVertex, Const(index)) });
diff --git a/src/Ryujinx.Graphics.Shader/Translation/EmitterContextInsts.cs b/src/Ryujinx.Graphics.Shader/Translation/EmitterContextInsts.cs
index 9e314c62..5bdbb002 100644
--- a/src/Ryujinx.Graphics.Shader/Translation/EmitterContextInsts.cs
+++ b/src/Ryujinx.Graphics.Shader/Translation/EmitterContextInsts.cs
@@ -618,12 +618,21 @@ namespace Ryujinx.Graphics.Shader.Translation
SamplerType type,
TextureFormat format,
TextureFlags flags,
- int binding,
+ SetBindingPair setAndBinding,
Operand[] sources)
{
Operand dest = Local();
- context.Add(new TextureOperation(Instruction.ImageAtomic, type, format, flags, binding, 0, new[] { dest }, sources));
+ context.Add(new TextureOperation(
+ Instruction.ImageAtomic,
+ type,
+ format,
+ flags,
+ setAndBinding.SetIndex,
+ setAndBinding.Binding,
+ 0,
+ new[] { dest },
+ sources));
return dest;
}
@@ -633,12 +642,21 @@ namespace Ryujinx.Graphics.Shader.Translation
SamplerType type,
TextureFormat format,
TextureFlags flags,
- int binding,
+ SetBindingPair setAndBinding,
int compMask,
Operand[] dests,
Operand[] sources)
{
- context.Add(new TextureOperation(Instruction.ImageLoad, type, format, flags, binding, compMask, dests, sources));
+ context.Add(new TextureOperation(
+ Instruction.ImageLoad,
+ type,
+ format,
+ flags,
+ setAndBinding.SetIndex,
+ setAndBinding.Binding,
+ compMask,
+ dests,
+ sources));
}
public static void ImageStore(
@@ -646,10 +664,19 @@ namespace Ryujinx.Graphics.Shader.Translation
SamplerType type,
TextureFormat format,
TextureFlags flags,
- int binding,
+ SetBindingPair setAndBinding,
Operand[] sources)
{
- context.Add(new TextureOperation(Instruction.ImageStore, type, format, flags, binding, 0, null, sources));
+ context.Add(new TextureOperation(
+ Instruction.ImageStore,
+ type,
+ format,
+ flags,
+ setAndBinding.SetIndex,
+ setAndBinding.Binding,
+ 0,
+ null,
+ sources));
}
public static Operand IsNan(this EmitterContext context, Operand a, Instruction fpType = Instruction.FP32)
@@ -718,13 +745,22 @@ namespace Ryujinx.Graphics.Shader.Translation
this EmitterContext context,
SamplerType type,
TextureFlags flags,
- int binding,
+ SetBindingPair setAndBinding,
int compIndex,
Operand[] sources)
{
Operand dest = Local();
- context.Add(new TextureOperation(Instruction.Lod, type, TextureFormat.Unknown, flags, binding, compIndex, new[] { dest }, sources));
+ context.Add(new TextureOperation(
+ Instruction.Lod,
+ type,
+ TextureFormat.Unknown,
+ flags,
+ setAndBinding.SetIndex,
+ setAndBinding.Binding,
+ compIndex,
+ new[] { dest },
+ sources));
return dest;
}
@@ -889,24 +925,42 @@ namespace Ryujinx.Graphics.Shader.Translation
this EmitterContext context,
SamplerType type,
TextureFlags flags,
- int binding,
+ SetBindingPair setAndBinding,
int compMask,
Operand[] dests,
Operand[] sources)
{
- context.Add(new TextureOperation(Instruction.TextureSample, type, TextureFormat.Unknown, flags, binding, compMask, dests, sources));
+ context.Add(new TextureOperation(
+ Instruction.TextureSample,
+ type,
+ TextureFormat.Unknown,
+ flags,
+ setAndBinding.SetIndex,
+ setAndBinding.Binding,
+ compMask,
+ dests,
+ sources));
}
public static Operand TextureQuerySamples(
this EmitterContext context,
SamplerType type,
TextureFlags flags,
- int binding,
+ SetBindingPair setAndBinding,
Operand[] sources)
{
Operand dest = Local();
- context.Add(new TextureOperation(Instruction.TextureQuerySamples, type, TextureFormat.Unknown, flags, binding, 0, new[] { dest }, sources));
+ context.Add(new TextureOperation(
+ Instruction.TextureQuerySamples,
+ type,
+ TextureFormat.Unknown,
+ flags,
+ setAndBinding.SetIndex,
+ setAndBinding.Binding,
+ 0,
+ new[] { dest },
+ sources));
return dest;
}
@@ -915,13 +969,22 @@ namespace Ryujinx.Graphics.Shader.Translation
this EmitterContext context,
SamplerType type,
TextureFlags flags,
- int binding,
+ SetBindingPair setAndBinding,
int compIndex,
Operand[] sources)
{
Operand dest = Local();
- context.Add(new TextureOperation(Instruction.TextureQuerySize, type, TextureFormat.Unknown, flags, binding, compIndex, new[] { dest }, sources));
+ context.Add(new TextureOperation(
+ Instruction.TextureQuerySize,
+ type,
+ TextureFormat.Unknown,
+ flags,
+ setAndBinding.SetIndex,
+ setAndBinding.Binding,
+ compIndex,
+ new[] { dest },
+ sources));
return dest;
}
diff --git a/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs b/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs
index 4128af24..29501b71 100644
--- a/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs
+++ b/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs
@@ -91,7 +91,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
bool hasSampler = !texOp.Inst.IsImage();
- int textureBinding = resourceManager.GetTextureOrImageBinding(
+ SetBindingPair textureSetAndBinding = resourceManager.GetTextureOrImageBinding(
texOp.Inst,
texOp.Type,
texOp.Format,
@@ -111,7 +111,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
texOp.InsertSource(1, samplerIndex);
- int samplerBinding = resourceManager.GetTextureOrImageBinding(
+ SetBindingPair samplerSetAndBinding = resourceManager.GetTextureOrImageBinding(
texOp.Inst,
SamplerType.None,
texOp.Format,
@@ -120,11 +120,11 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
TextureHandle.PackOffsets(0, 0, TextureHandleType.Direct),
samplerPoolLength);
- texOp.TurnIntoArray(textureBinding, samplerBinding);
+ texOp.TurnIntoArray(textureSetAndBinding, samplerSetAndBinding);
}
else
{
- texOp.TurnIntoArray(textureBinding);
+ texOp.TurnIntoArray(textureSetAndBinding);
}
return true;
@@ -445,7 +445,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
}
}
- int binding = resourceManager.GetTextureOrImageBinding(
+ SetBindingPair setAndBinding = resourceManager.GetTextureOrImageBinding(
texOp.Inst,
texOp.Type,
texOp.Format,
@@ -453,7 +453,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
cbufSlot,
cbufOffset);
- texOp.SetBinding(binding);
+ texOp.SetBinding(setAndBinding);
}
}
}
diff --git a/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessToArray.cs b/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessToArray.cs
index f2be7975..8eed139d 100644
--- a/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessToArray.cs
+++ b/src/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessToArray.cs
@@ -221,7 +221,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
private static void TurnIntoArray(ResourceManager resourceManager, TextureOperation texOp, int cbufSlot, int handleIndex, int length)
{
- int binding = resourceManager.GetTextureOrImageBinding(
+ SetBindingPair setAndBinding = resourceManager.GetTextureOrImageBinding(
texOp.Inst,
texOp.Type,
texOp.Format,
@@ -230,7 +230,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
handleIndex,
length);
- texOp.TurnIntoArray(binding);
+ texOp.TurnIntoArray(setAndBinding);
}
}
}
diff --git a/src/Ryujinx.Graphics.Shader/Translation/ResourceManager.cs b/src/Ryujinx.Graphics.Shader/Translation/ResourceManager.cs
index 890501c9..94691a5b 100644
--- a/src/Ryujinx.Graphics.Shader/Translation/ResourceManager.cs
+++ b/src/Ryujinx.Graphics.Shader/Translation/ResourceManager.cs
@@ -20,8 +20,8 @@ namespace Ryujinx.Graphics.Shader.Translation
private readonly ShaderStage _stage;
private readonly string _stagePrefix;
- private readonly int[] _cbSlotToBindingMap;
- private readonly int[] _sbSlotToBindingMap;
+ private readonly SetBindingPair[] _cbSlotToBindingMap;
+ private readonly SetBindingPair[] _sbSlotToBindingMap;
private uint _sbSlotWritten;
private readonly Dictionary<int, int> _sbSlots;
@@ -33,6 +33,7 @@ namespace Ryujinx.Graphics.Shader.Translation
private struct TextureMeta
{
+ public int Set;
public int Binding;
public bool AccurateType;
public SamplerType Type;
@@ -64,10 +65,10 @@ namespace Ryujinx.Graphics.Shader.Translation
_stage = stage;
_stagePrefix = GetShaderStagePrefix(stage);
- _cbSlotToBindingMap = new int[18];
- _sbSlotToBindingMap = new int[16];
- _cbSlotToBindingMap.AsSpan().Fill(-1);
- _sbSlotToBindingMap.AsSpan().Fill(-1);
+ _cbSlotToBindingMap = new SetBindingPair[18];
+ _sbSlotToBindingMap = new SetBindingPair[16];
+ _cbSlotToBindingMap.AsSpan().Fill(new(-1, -1));
+ _sbSlotToBindingMap.AsSpan().Fill(new(-1, -1));
_sbSlots = new();
_sbSlotsReverse = new();
@@ -146,16 +147,16 @@ namespace Ryujinx.Graphics.Shader.Translation
public int GetConstantBufferBinding(int slot)
{
- int binding = _cbSlotToBindingMap[slot];
- if (binding < 0)
+ SetBindingPair setAndBinding = _cbSlotToBindingMap[slot];
+ if (setAndBinding.Binding < 0)
{
- binding = _gpuAccessor.CreateConstantBufferBinding(slot);
- _cbSlotToBindingMap[slot] = binding;
+ setAndBinding = _gpuAccessor.CreateConstantBufferBinding(slot);
+ _cbSlotToBindingMap[slot] = setAndBinding;
string slotNumber = slot.ToString(CultureInfo.InvariantCulture);
- AddNewConstantBuffer(binding, $"{_stagePrefix}_c{slotNumber}");
+ AddNewConstantBuffer(setAndBinding.SetIndex, setAndBinding.Binding, $"{_stagePrefix}_c{slotNumber}");
}
- return binding;
+ return setAndBinding.Binding;
}
public bool TryGetStorageBufferBinding(int sbCbSlot, int sbCbOffset, bool write, out int binding)
@@ -166,14 +167,14 @@ namespace Ryujinx.Graphics.Shader.Translation
return false;
}
- binding = _sbSlotToBindingMap[slot];
+ SetBindingPair setAndBinding = _sbSlotToBindingMap[slot];
- if (binding < 0)
+ if (setAndBinding.Binding < 0)
{
- binding = _gpuAccessor.CreateStorageBufferBinding(slot);
- _sbSlotToBindingMap[slot] = binding;
+ setAndBinding = _gpuAccessor.CreateStorageBufferBinding(slot);
+ _sbSlotToBindingMap[slot] = setAndBinding;
string slotNumber = slot.ToString(CultureInfo.InvariantCulture);
- AddNewStorageBuffer(binding, $"{_stagePrefix}_s{slotNumber}");
+ AddNewStorageBuffer(setAndBinding.SetIndex, setAndBinding.Binding, $"{_stagePrefix}_s{slotNumber}");
}
if (write)
@@ -181,6 +182,7 @@ namespace Ryujinx.Graphics.Shader.Translation
_sbSlotWritten |= 1u << slot;
}
+ binding = setAndBinding.Binding;
return true;
}
@@ -208,7 +210,7 @@ namespace Ryujinx.Graphics.Shader.Translation
{
for (slot = 0; slot < _cbSlotToBindingMap.Length; slot++)
{
- if (_cbSlotToBindingMap[slot] == binding)
+ if (_cbSlotToBindingMap[slot].Binding == binding)
{
return true;
}
@@ -218,7 +220,7 @@ namespace Ryujinx.Graphics.Shader.Translation
return false;
}
- public int GetTextureOrImageBinding(
+ public SetBindingPair GetTextureOrImageBinding(
Instruction inst,
SamplerType type,
TextureFormat format,
@@ -240,7 +242,7 @@ namespace Ryujinx.Graphics.Shader.Translation
format = TextureFormat.Unknown;
}
- int binding = GetTextureOrImageBinding(
+ SetBindingPair setAndBinding = GetTextureOrImageBinding(
cbufSlot,
handle,
arrayLength,
@@ -255,10 +257,10 @@ namespace Ryujinx.Graphics.Shader.Translation
_gpuAccessor.RegisterTexture(handle, cbufSlot);
- return binding;
+ return setAndBinding;
}
- private int GetTextureOrImageBinding(
+ private SetBindingPair GetTextureOrImageBinding(
int cbufSlot,
int handle,
int arrayLength,
@@ -311,21 +313,38 @@ namespace Ryujinx.Graphics.Shader.Translation
UsageFlags = usageFlags,
};
+ int setIndex;
int binding;
if (dict.TryGetValue(info, out var existingMeta))
{
dict[info] = MergeTextureMeta(meta, existingMeta);
+ setIndex = existingMeta.Set;
binding = existingMeta.Binding;
}
else
{
- bool isBuffer = (type & SamplerType.Mask) == SamplerType.TextureBuffer;
+ if (arrayLength > 1 && (setIndex = _gpuAccessor.CreateExtraSet()) >= 0)
+ {
+ // We reserved an "extra set" for the array.
+ // In this case the binding is always the first one (0).
+ // Using separate sets for array is better as we need to do less descriptor set updates.
+
+ binding = 0;
+ }
+ else
+ {
+ bool isBuffer = (type & SamplerType.Mask) == SamplerType.TextureBuffer;
+
+ SetBindingPair setAndBinding = isImage
+ ? _gpuAccessor.CreateImageBinding(arrayLength, isBuffer)
+ : _gpuAccessor.CreateTextureBinding(arrayLength, isBuffer);
- binding = isImage
- ? _gpuAccessor.CreateImageBinding(arrayLength, isBuffer)
- : _gpuAccessor.CreateTextureBinding(arrayLength, isBuffer);
+ setIndex = setAndBinding.SetIndex;
+ binding = setAndBinding.Binding;
+ }
+ meta.Set = setIndex;
meta.Binding = binding;
dict.Add(info, meta);
@@ -355,7 +374,7 @@ namespace Ryujinx.Graphics.Shader.Translation
}
var definition = new TextureDefinition(
- isImage ? 3 : 2,
+ setIndex,
binding,
arrayLength,
separate,
@@ -373,11 +392,12 @@ namespace Ryujinx.Graphics.Shader.Translation
Properties.AddOrUpdateTexture(definition);
}
- return binding;
+ return new SetBindingPair(setIndex, binding);
}
private static TextureMeta MergeTextureMeta(TextureMeta meta, TextureMeta existingMeta)
{
+ meta.Set = existingMeta.Set;
meta.Binding = existingMeta.Binding;
meta.UsageFlags |= existingMeta.UsageFlags;
@@ -440,11 +460,11 @@ namespace Ryujinx.Graphics.Shader.Translation
for (int slot = 0; slot < _cbSlotToBindingMap.Length; slot++)
{
- int binding = _cbSlotToBindingMap[slot];
+ SetBindingPair setAndBinding = _cbSlotToBindingMap[slot];
- if (binding >= 0 && _usedConstantBufferBindings.Contains(binding))
+ if (setAndBinding.Binding >= 0 && _usedConstantBufferBindings.Contains(setAndBinding.Binding))
{
- descriptors[descriptorIndex++] = new BufferDescriptor(binding, slot);
+ descriptors[descriptorIndex++] = new BufferDescriptor(setAndBinding.SetIndex, setAndBinding.Binding, slot);
}
}
@@ -464,13 +484,13 @@ namespace Ryujinx.Graphics.Shader.Translation
foreach ((int key, int slot) in _sbSlots)
{
- int binding = _sbSlotToBindingMap[slot];
+ SetBindingPair setAndBinding = _sbSlotToBindingMap[slot];
- if (binding >= 0)
+ if (setAndBinding.Binding >= 0)
{
(int sbCbSlot, int sbCbOffset) = UnpackSbCbInfo(key);
BufferUsageFlags flags = (_sbSlotWritten & (1u << slot)) != 0 ? BufferUsageFlags.Write : BufferUsageFlags.None;
- descriptors[descriptorIndex++] = new BufferDescriptor(binding, slot, sbCbSlot, sbCbOffset, flags);
+ descriptors[descriptorIndex++] = new BufferDescriptor(setAndBinding.SetIndex, setAndBinding.Binding, slot, sbCbSlot, sbCbOffset, flags);
}
}
@@ -507,6 +527,7 @@ namespace Ryujinx.Graphics.Shader.Translation
}
descriptors.Add(new TextureDescriptor(
+ meta.Set,
meta.Binding,
meta.Type,
info.Format,
@@ -527,6 +548,7 @@ namespace Ryujinx.Graphics.Shader.Translation
}
descriptors.Add(new TextureDescriptor(
+ meta.Set,
meta.Binding,
meta.Type,
info.Format,
@@ -587,24 +609,24 @@ namespace Ryujinx.Graphics.Shader.Translation
return false;
}
- private void AddNewConstantBuffer(int binding, string name)
+ private void AddNewConstantBuffer(int setIndex, int binding, string name)
{
StructureType type = new(new[]
{
new StructureField(AggregateType.Array | AggregateType.Vector4 | AggregateType.FP32, "data", Constants.ConstantBufferSize / 16),
});
- Properties.AddOrUpdateConstantBuffer(new(BufferLayout.Std140, 0, binding, name, type));
+ Properties.AddOrUpdateConstantBuffer(new(BufferLayout.Std140, setIndex, binding, name, type));
}
- private void AddNewStorageBuffer(int binding, string name)
+ private void AddNewStorageBuffer(int setIndex, int binding, string name)
{
StructureType type = new(new[]
{
new StructureField(AggregateType.Array | AggregateType.U32, "data", 0),
});
- Properties.AddOrUpdateStorageBuffer(new(BufferLayout.Std430, 1, binding, name, type));
+ Properties.AddOrUpdateStorageBuffer(new(BufferLayout.Std430, setIndex, binding, name, type));
}
public static string GetShaderStagePrefix(ShaderStage stage)
diff --git a/src/Ryujinx.Graphics.Shader/Translation/ResourceReservations.cs b/src/Ryujinx.Graphics.Shader/Translation/ResourceReservations.cs
index d559f669..c89c4d0b 100644
--- a/src/Ryujinx.Graphics.Shader/Translation/ResourceReservations.cs
+++ b/src/Ryujinx.Graphics.Shader/Translation/ResourceReservations.cs
@@ -11,6 +11,8 @@ namespace Ryujinx.Graphics.Shader.Translation
public const int MaxVertexBufferTextures = 32;
+ private const int TextureSetIndex = 2; // TODO: Get from GPU accessor.
+
public int VertexInfoConstantBufferBinding { get; }
public int VertexOutputStorageBufferBinding { get; }
public int GeometryVertexOutputStorageBufferBinding { get; }
@@ -163,6 +165,21 @@ namespace Ryujinx.Graphics.Shader.Translation
return _vertexBufferTextureBaseBinding + vaLocation;
}
+ public SetBindingPair GetVertexBufferTextureSetAndBinding(int vaLocation)
+ {
+ return new SetBindingPair(TextureSetIndex, GetVertexBufferTextureBinding(vaLocation));
+ }
+
+ public SetBindingPair GetIndexBufferTextureSetAndBinding()
+ {
+ return new SetBindingPair(TextureSetIndex, IndexBufferTextureBinding);
+ }
+
+ public SetBindingPair GetTopologyRemapBufferTextureSetAndBinding()
+ {
+ return new SetBindingPair(TextureSetIndex, TopologyRemapBufferTextureBinding);
+ }
+
internal bool TryGetOffset(StorageKind storageKind, int location, int component, out int offset)
{
return _offsets.TryGetValue(new IoDefinition(storageKind, IoVariable.UserDefined, location, component), out offset);
diff --git a/src/Ryujinx.Graphics.Shader/Translation/Transforms/TexturePass.cs b/src/Ryujinx.Graphics.Shader/Translation/Transforms/TexturePass.cs
index 072b4569..6ba8cb44 100644
--- a/src/Ryujinx.Graphics.Shader/Translation/Transforms/TexturePass.cs
+++ b/src/Ryujinx.Graphics.Shader/Translation/Transforms/TexturePass.cs
@@ -182,6 +182,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
texOp.Type,
texOp.Format,
texOp.Flags,
+ texOp.Set,
texOp.Binding,
index,
new[] { coordSize },
@@ -251,6 +252,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
texOp.Type,
texOp.Format,
texOp.Flags,
+ texOp.Set,
texOp.Binding,
index,
new[] { coordSize },
@@ -471,6 +473,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
texOp.Type,
texOp.Format,
texOp.Flags & ~(TextureFlags.Offset | TextureFlags.Offsets),
+ texOp.Set,
texOp.Binding,
1 << 3, // W component: i=0, j=0
new[] { dests[destIndex++] },
@@ -527,6 +530,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
texOp.Type,
texOp.Format,
texOp.Flags & ~(TextureFlags.Offset | TextureFlags.Offsets),
+ texOp.Set,
texOp.Binding,
componentIndex,
dests,
@@ -573,6 +577,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
texOp.Type,
texOp.Format,
texOp.Flags,
+ texOp.Set,
texOp.Binding,
index,
new[] { texSizes[index] },
@@ -603,6 +608,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
texOp.Type,
texOp.Format,
texOp.Flags,
+ texOp.Set,
texOp.Binding,
0,
new[] { lod },
@@ -633,6 +639,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
texOp.Type,
texOp.Format,
texOp.Flags,
+ texOp.Set,
texOp.Binding,
index,
new[] { texSizes[index] },
diff --git a/src/Ryujinx.Graphics.Shader/Translation/Transforms/VertexToCompute.cs b/src/Ryujinx.Graphics.Shader/Translation/Transforms/VertexToCompute.cs
index d71ada86..ddd2134d 100644
--- a/src/Ryujinx.Graphics.Shader/Translation/Transforms/VertexToCompute.cs
+++ b/src/Ryujinx.Graphics.Shader/Translation/Transforms/VertexToCompute.cs
@@ -54,6 +54,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
{
bool needsSextNorm = context.Definitions.IsAttributePackedRgb10A2Signed(location);
+ SetBindingPair setAndBinding = context.ResourceManager.Reservations.GetVertexBufferTextureSetAndBinding(location);
Operand temp = needsSextNorm ? Local() : dest;
Operand vertexElemOffset = GenerateVertexOffset(context.ResourceManager, node, location, 0);
@@ -62,7 +63,8 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
SamplerType.TextureBuffer,
TextureFormat.Unknown,
TextureFlags.IntCoords,
- context.ResourceManager.Reservations.GetVertexBufferTextureBinding(location),
+ setAndBinding.SetIndex,
+ setAndBinding.Binding,
1 << component,
new[] { temp },
new[] { vertexElemOffset }));
@@ -75,6 +77,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
}
else
{
+ SetBindingPair setAndBinding = context.ResourceManager.Reservations.GetVertexBufferTextureSetAndBinding(location);
Operand temp = component > 0 ? Local() : dest;
Operand vertexElemOffset = GenerateVertexOffset(context.ResourceManager, node, location, component);
@@ -83,7 +86,8 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
SamplerType.TextureBuffer,
TextureFormat.Unknown,
TextureFlags.IntCoords,
- context.ResourceManager.Reservations.GetVertexBufferTextureBinding(location),
+ setAndBinding.SetIndex,
+ setAndBinding.Binding,
1,
new[] { temp },
new[] { vertexElemOffset }));
diff --git a/src/Ryujinx.Graphics.Shader/Translation/TranslatorContext.cs b/src/Ryujinx.Graphics.Shader/Translation/TranslatorContext.cs
index 10653558..59914736 100644
--- a/src/Ryujinx.Graphics.Shader/Translation/TranslatorContext.cs
+++ b/src/Ryujinx.Graphics.Shader/Translation/TranslatorContext.cs
@@ -412,8 +412,8 @@ namespace Ryujinx.Graphics.Shader.Translation
if (Stage == ShaderStage.Vertex)
{
- int ibBinding = resourceManager.Reservations.IndexBufferTextureBinding;
- TextureDefinition indexBuffer = new(2, ibBinding, "ib_data", SamplerType.TextureBuffer);
+ SetBindingPair ibSetAndBinding = resourceManager.Reservations.GetIndexBufferTextureSetAndBinding();
+ TextureDefinition indexBuffer = new(ibSetAndBinding.SetIndex, ibSetAndBinding.Binding, "ib_data", SamplerType.TextureBuffer);
resourceManager.Properties.AddOrUpdateTexture(indexBuffer);
int inputMap = _program.AttributeUsage.UsedInputAttributes;
@@ -421,8 +421,8 @@ namespace Ryujinx.Graphics.Shader.Translation
while (inputMap != 0)
{
int location = BitOperations.TrailingZeroCount(inputMap);
- int binding = resourceManager.Reservations.GetVertexBufferTextureBinding(location);
- TextureDefinition vaBuffer = new(2, binding, $"vb_data{location}", SamplerType.TextureBuffer);
+ SetBindingPair setAndBinding = resourceManager.Reservations.GetVertexBufferTextureSetAndBinding(location);
+ TextureDefinition vaBuffer = new(setAndBinding.SetIndex, setAndBinding.Binding, $"vb_data{location}", SamplerType.TextureBuffer);
resourceManager.Properties.AddOrUpdateTexture(vaBuffer);
inputMap &= ~(1 << location);
@@ -430,8 +430,8 @@ namespace Ryujinx.Graphics.Shader.Translation
}
else if (Stage == ShaderStage.Geometry)
{
- int trbBinding = resourceManager.Reservations.TopologyRemapBufferTextureBinding;
- TextureDefinition remapBuffer = new(2, trbBinding, "trb_data", SamplerType.TextureBuffer);
+ SetBindingPair trbSetAndBinding = resourceManager.Reservations.GetTopologyRemapBufferTextureSetAndBinding();
+ TextureDefinition remapBuffer = new(trbSetAndBinding.SetIndex, trbSetAndBinding.Binding, "trb_data", SamplerType.TextureBuffer);
resourceManager.Properties.AddOrUpdateTexture(remapBuffer);
int geometryVbOutputSbBinding = resourceManager.Reservations.GeometryVertexOutputStorageBufferBinding;