diff --git a/Ryujinx.Graphics.Gpu/Engine/Compute.cs b/Ryujinx.Graphics.Gpu/Engine/Compute.cs
index 3ea98f3e48..cd5002ca9b 100644
--- a/Ryujinx.Graphics.Gpu/Engine/Compute.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/Compute.cs
@@ -111,19 +111,12 @@ namespace Ryujinx.Graphics.Gpu.Engine
Target target = ShaderTexture.GetTarget(descriptor.Type);
- if (descriptor.IsBindless)
- {
- textureBindings[index] = new TextureBindingInfo(
- target,
- descriptor.Binding,
- descriptor.CbufOffset,
- descriptor.CbufSlot,
- descriptor.Flags);
- }
- else
- {
- textureBindings[index] = new TextureBindingInfo(target, descriptor.Binding, descriptor.HandleIndex, descriptor.Flags);
- }
+ textureBindings[index] = new TextureBindingInfo(
+ target,
+ descriptor.Binding,
+ descriptor.CbufSlot,
+ descriptor.HandleIndex,
+ descriptor.Flags);
}
TextureManager.SetComputeTextures(textureBindings);
@@ -137,7 +130,13 @@ namespace Ryujinx.Graphics.Gpu.Engine
Target target = ShaderTexture.GetTarget(descriptor.Type);
Format format = ShaderTexture.GetFormat(descriptor.Format);
- imageBindings[index] = new TextureBindingInfo(target, format, descriptor.Binding, descriptor.HandleIndex, descriptor.Flags);
+ imageBindings[index] = new TextureBindingInfo(
+ target,
+ format,
+ descriptor.Binding,
+ descriptor.CbufSlot,
+ descriptor.HandleIndex,
+ descriptor.Flags);
}
TextureManager.SetComputeImages(imageBindings);
diff --git a/Ryujinx.Graphics.Gpu/Engine/Methods.cs b/Ryujinx.Graphics.Gpu/Engine/Methods.cs
index 8bc2c22d0b..ef073a25a1 100644
--- a/Ryujinx.Graphics.Gpu/Engine/Methods.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/Methods.cs
@@ -1024,14 +1024,12 @@ namespace Ryujinx.Graphics.Gpu.Engine
Target target = ShaderTexture.GetTarget(descriptor.Type);
- if (descriptor.IsBindless)
- {
- textureBindings[index] = new TextureBindingInfo(target, descriptor.Binding, descriptor.CbufSlot, descriptor.CbufOffset, descriptor.Flags);
- }
- else
- {
- textureBindings[index] = new TextureBindingInfo(target, descriptor.Binding, descriptor.HandleIndex, descriptor.Flags);
- }
+ textureBindings[index] = new TextureBindingInfo(
+ target,
+ descriptor.Binding,
+ descriptor.CbufSlot,
+ descriptor.HandleIndex,
+ descriptor.Flags);
}
TextureManager.SetGraphicsTextures(stage, textureBindings);
@@ -1045,7 +1043,13 @@ namespace Ryujinx.Graphics.Gpu.Engine
Target target = ShaderTexture.GetTarget(descriptor.Type);
Format format = ShaderTexture.GetFormat(descriptor.Format);
- imageBindings[index] = new TextureBindingInfo(target, format, descriptor.Binding, descriptor.HandleIndex, descriptor.Flags);
+ imageBindings[index] = new TextureBindingInfo(
+ target,
+ format,
+ descriptor.Binding,
+ descriptor.CbufSlot,
+ descriptor.HandleIndex,
+ descriptor.Flags);
}
TextureManager.SetGraphicsImages(stage, imageBindings);
diff --git a/Ryujinx.Graphics.Gpu/Image/TextureBindingInfo.cs b/Ryujinx.Graphics.Gpu/Image/TextureBindingInfo.cs
index a328fc2b69..be94f310e0 100644
--- a/Ryujinx.Graphics.Gpu/Image/TextureBindingInfo.cs
+++ b/Ryujinx.Graphics.Gpu/Image/TextureBindingInfo.cs
@@ -25,28 +25,14 @@ namespace Ryujinx.Graphics.Gpu.Image
public int Binding { get; }
///
- /// Shader texture handle.
- /// This is an index into the texture constant buffer.
- ///
- public int Handle { get; }
-
- ///
- /// Indicates if the texture is a bindless texture.
- ///
- ///
- /// For those textures, Handle is ignored.
- ///
- public bool IsBindless { get; }
-
- ///
- /// Constant buffer slot with the bindless texture handle, for bindless texture.
+ /// Constant buffer slot with the texture handle.
///
public int CbufSlot { get; }
///
- /// Constant buffer offset of the bindless texture handle, for bindless texture.
+ /// Index of the texture handle on the constant buffer at slot .
///
- public int CbufOffset { get; }
+ public int Handle { get; }
///
/// Flags from the texture descriptor that indicate how the texture is used.
@@ -59,21 +45,17 @@ namespace Ryujinx.Graphics.Gpu.Image
/// The shader sampler target type
/// Format of the image as declared on the shader
/// The shader texture binding point
+ /// Constant buffer slot where the texture handle is located
/// The shader texture handle (read index into the texture constant buffer)
/// The texture's usage flags, indicating how it is used in the shader
- public TextureBindingInfo(Target target, Format format, int binding, int handle, TextureUsageFlags flags)
+ public TextureBindingInfo(Target target, Format format, int binding, int cbufSlot, int handle, TextureUsageFlags flags)
{
- Target = target;
- Format = format;
- Binding = binding;
- Handle = handle;
-
- IsBindless = false;
-
- CbufSlot = 0;
- CbufOffset = 0;
-
- Flags = flags;
+ Target = target;
+ Format = format;
+ Binding = binding;
+ CbufSlot = cbufSlot;
+ Handle = handle;
+ Flags = flags;
}
///
@@ -81,33 +63,11 @@ namespace Ryujinx.Graphics.Gpu.Image
///
/// The shader sampler target type
/// The shader texture binding point
+ /// Constant buffer slot where the texture handle is located
/// The shader texture handle (read index into the texture constant buffer)
/// The texture's usage flags, indicating how it is used in the shader
- public TextureBindingInfo(Target target, int binding, int handle, TextureUsageFlags flags) : this(target, (Format)0, binding, handle, flags)
+ public TextureBindingInfo(Target target, int binding, int cbufSlot, int handle, TextureUsageFlags flags) : this(target, (Format)0, binding, cbufSlot, handle, flags)
{
}
-
- ///
- /// Constructs the bindless texture binding information structure.
- ///
- /// The shader sampler target type
- /// The shader texture binding point
- /// Constant buffer slot where the bindless texture handle is located
- /// Constant buffer offset of the bindless texture handle
- /// The texture's usage flags, indicating how it is used in the shader
- public TextureBindingInfo(Target target, int binding, int cbufSlot, int cbufOffset, TextureUsageFlags flags)
- {
- Target = target;
- Format = 0;
- Binding = binding;
- Handle = 0;
-
- IsBindless = true;
-
- CbufSlot = cbufSlot;
- CbufOffset = cbufOffset;
-
- Flags = flags;
- }
}
}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs b/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs
index bfb6da2513..8d44165c6b 100644
--- a/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs
+++ b/Ryujinx.Graphics.Gpu/Image/TextureBindingsManager.cs
@@ -267,30 +267,9 @@ namespace Ryujinx.Graphics.Gpu.Image
{
TextureBindingInfo bindingInfo = _textureBindings[stageIndex][index];
- int packedId;
-
- if (bindingInfo.IsBindless)
- {
- ulong address;
-
- var bufferManager = _context.Methods.BufferManager;
-
- if (_isCompute)
- {
- address = bufferManager.GetComputeUniformBufferAddress(bindingInfo.CbufSlot);
- }
- else
- {
- address = bufferManager.GetGraphicsUniformBufferAddress(stageIndex, bindingInfo.CbufSlot);
- }
-
- packedId = _context.PhysicalMemory.Read(address + (ulong)bindingInfo.CbufOffset * 4);
- }
- else
- {
- packedId = ReadPackedId(stageIndex, bindingInfo.Handle, _textureBufferIndex);
- }
+ int textureBufferIndex = bindingInfo.CbufSlot < 0 ? _textureBufferIndex : bindingInfo.CbufSlot;
+ int packedId = ReadPackedId(stageIndex, bindingInfo.Handle, textureBufferIndex);
int textureId = UnpackTextureId(packedId);
int samplerId;
@@ -361,7 +340,9 @@ namespace Ryujinx.Graphics.Gpu.Image
{
TextureBindingInfo bindingInfo = _imageBindings[stageIndex][index];
- int packedId = ReadPackedId(stageIndex, bindingInfo.Handle, _textureBufferIndex);
+ int textureBufferIndex = bindingInfo.CbufSlot < 0 ? _textureBufferIndex : bindingInfo.CbufSlot;
+
+ int packedId = ReadPackedId(stageIndex, bindingInfo.Handle, textureBufferIndex);
int textureId = UnpackTextureId(packedId);
Texture texture = pool.Get(textureId);
diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/CodeGenContext.cs b/Ryujinx.Graphics.Shader/CodeGen/Glsl/CodeGenContext.cs
index f86e82da2d..e20df384e3 100644
--- a/Ryujinx.Graphics.Shader/CodeGen/Glsl/CodeGenContext.cs
+++ b/Ryujinx.Graphics.Shader/CodeGen/Glsl/CodeGenContext.cs
@@ -86,18 +86,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
private int FindDescriptorIndex(List list, AstTextureOperation texOp)
{
- AstOperand operand = texOp.GetSource(0) as AstOperand;
- bool bindless = (texOp.Flags & TextureFlags.Bindless) > 0;
-
- int cBufSlot = bindless ? operand.CbufSlot : 0;
- int cBufOffset = bindless ? operand.CbufOffset : 0;
-
return list.FindIndex(descriptor =>
descriptor.Type == texOp.Type &&
+ descriptor.CbufSlot == texOp.CbufSlot &&
descriptor.HandleIndex == texOp.Handle &&
- descriptor.Format == texOp.Format &&
- descriptor.CbufSlot == cBufSlot &&
- descriptor.CbufOffset == cBufOffset);
+ descriptor.Format == texOp.Format);
}
public int FindTextureDescriptorIndex(AstTextureOperation texOp)
diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs
index 56a0126412..825564b8c5 100644
--- a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs
+++ b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Declarations.cs
@@ -305,24 +305,14 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
string samplerName = OperandManager.GetSamplerName(context.Config.Stage, texOp, indexExpr);
- if (!samplers.Add(samplerName))
+ if ((texOp.Flags & TextureFlags.Bindless) != 0 || !samplers.Add(samplerName))
{
continue;
}
int firstBinding = -1;
- if ((texOp.Flags & TextureFlags.Bindless) != 0)
- {
- AstOperand operand = texOp.GetSource(0) as AstOperand;
-
- firstBinding = context.Config.Counts.IncrementTexturesCount();
-
- var desc = new TextureDescriptor(firstBinding, texOp.Type, operand.CbufSlot, operand.CbufOffset);
-
- context.TextureDescriptors.Add(desc);
- }
- else if ((texOp.Type & SamplerType.Indexed) != 0)
+ if ((texOp.Type & SamplerType.Indexed) != 0)
{
for (int index = 0; index < texOp.ArraySize; index++)
{
@@ -333,7 +323,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
firstBinding = binding;
}
- var desc = new TextureDescriptor(binding, texOp.Type, texOp.Format, texOp.Handle + index * 2);
+ var desc = new TextureDescriptor(binding, texOp.Type, texOp.Format, texOp.CbufSlot, texOp.Handle + index * 2);
context.TextureDescriptors.Add(desc);
}
@@ -342,7 +332,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
{
firstBinding = context.Config.Counts.IncrementTexturesCount();
- var desc = new TextureDescriptor(firstBinding, texOp.Type, texOp.Format, texOp.Handle);
+ var desc = new TextureDescriptor(firstBinding, texOp.Type, texOp.Format, texOp.CbufSlot, texOp.Handle);
context.TextureDescriptors.Add(desc);
}
@@ -363,7 +353,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
string imageName = OperandManager.GetImageName(context.Config.Stage, texOp, indexExpr);
- if (!images.Add(imageName))
+ if ((texOp.Flags & TextureFlags.Bindless) != 0 || !images.Add(imageName))
{
continue;
}
@@ -381,7 +371,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
firstBinding = binding;
}
- var desc = new TextureDescriptor(binding, texOp.Type, texOp.Format, texOp.Handle + index * 2);
+ var desc = new TextureDescriptor(binding, texOp.Type, texOp.Format, texOp.CbufSlot, texOp.Handle + index * 2);
context.ImageDescriptors.Add(desc);
}
@@ -390,7 +380,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
{
firstBinding = context.Config.Counts.IncrementImagesCount();
- var desc = new TextureDescriptor(firstBinding, texOp.Type, texOp.Format, texOp.Handle);
+ var desc = new TextureDescriptor(firstBinding, texOp.Type, texOp.Format, texOp.CbufSlot, texOp.Handle);
context.ImageDescriptors.Add(desc);
}
diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs
index f10eb101b9..6244f68b62 100644
--- a/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs
+++ b/Ryujinx.Graphics.Shader/CodeGen/Glsl/Instructions/InstGenMemory.cs
@@ -15,7 +15,13 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
bool isBindless = (texOp.Flags & TextureFlags.Bindless) != 0;
- bool isArray = (texOp.Type & SamplerType.Array) != 0;
+ // TODO: Bindless texture support. For now we just return 0/do nothing.
+ if (isBindless)
+ {
+ return texOp.Inst == Instruction.ImageLoad ? NumberFormatter.FormatFloat(0) : "// imageStore(bindless)";
+ }
+
+ bool isArray = (texOp.Type & SamplerType.Array) != 0;
bool isIndexed = (texOp.Type & SamplerType.Indexed) != 0;
string texCall = texOp.Inst == Instruction.ImageLoad ? "imageLoad" : "imageStore";
@@ -79,7 +85,10 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
flags |= TextureUsageFlags.ResScaleUnsupported;
}
- context.ImageDescriptors[index] = context.ImageDescriptors[index].SetFlag(flags);
+ if (!isBindless)
+ {
+ context.ImageDescriptors[index] = context.ImageDescriptors[index].SetFlag(flags);
+ }
return vector;
}
@@ -212,6 +221,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
bool isBindless = (texOp.Flags & TextureFlags.Bindless) != 0;
+ // TODO: Bindless texture support. For now we just return 0.
+ if (isBindless)
+ {
+ return NumberFormatter.FormatFloat(0);
+ }
+
bool isIndexed = (texOp.Type & SamplerType.Indexed) != 0;
string indexExpr = null;
@@ -306,6 +321,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
bool isMultisample = (texOp.Type & SamplerType.Multisample) != 0;
bool isShadow = (texOp.Type & SamplerType.Shadow) != 0;
+ // TODO: Bindless texture support. For now we just return 0.
+ if (isBindless)
+ {
+ return NumberFormatter.FormatFloat(0);
+ }
+
// This combination is valid, but not available on GLSL.
// For now, ignore the LOD level and do a normal sample.
// TODO: How to implement it properly?
@@ -469,7 +490,10 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
flags |= TextureUsageFlags.ResScaleUnsupported;
}
- context.TextureDescriptors[index] = context.TextureDescriptors[index].SetFlag(flags);
+ if (!isBindless)
+ {
+ context.TextureDescriptors[index] = context.TextureDescriptors[index].SetFlag(flags);
+ }
}
return vector;
@@ -572,6 +596,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl.Instructions
bool isBindless = (texOp.Flags & TextureFlags.Bindless) != 0;
+ // TODO: Bindless texture support. For now we just return 0.
+ if (isBindless)
+ {
+ return NumberFormatter.FormatInt(0);
+ }
+
bool isIndexed = (texOp.Type & SamplerType.Indexed) != 0;
string indexExpr = null;
diff --git a/Ryujinx.Graphics.Shader/CodeGen/Glsl/OperandManager.cs b/Ryujinx.Graphics.Shader/CodeGen/Glsl/OperandManager.cs
index 8e878b0d03..5c5d4403ed 100644
--- a/Ryujinx.Graphics.Shader/CodeGen/Glsl/OperandManager.cs
+++ b/Ryujinx.Graphics.Shader/CodeGen/Glsl/OperandManager.cs
@@ -241,22 +241,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
public static string GetSamplerName(ShaderStage stage, AstTextureOperation texOp, string indexExpr)
{
- string suffix;
+ string suffix = texOp.CbufSlot < 0 ? $"_tcb_{texOp.Handle:X}" : $"_cb{texOp.CbufSlot}_{texOp.Handle:X}";
- if ((texOp.Flags & TextureFlags.Bindless) != 0)
+ if ((texOp.Type & SamplerType.Indexed) != 0)
{
- AstOperand operand = texOp.GetSource(0) as AstOperand;
-
- suffix = $"_{texOp.Type.ToGlslSamplerType()}_cb{operand.CbufSlot}_{operand.CbufOffset}";
- }
- else
- {
- suffix = texOp.Handle.ToString("X");
-
- if ((texOp.Type & SamplerType.Indexed) != 0)
- {
- suffix += $"a[{indexExpr}]";
- }
+ suffix += $"a[{indexExpr}]";
}
return GetShaderStagePrefix(stage) + "_" + DefaultNames.SamplerNamePrefix + suffix;
@@ -264,7 +253,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Glsl
public static string GetImageName(ShaderStage stage, AstTextureOperation texOp, string indexExpr)
{
- string suffix = texOp.Handle.ToString("X") + "_" + texOp.Format.ToGlslFormat();
+ string suffix = texOp.CbufSlot < 0 ? $"_tcb_{texOp.Handle:X}_{texOp.Format.ToGlslFormat()}" : $"_cb{texOp.CbufSlot}_{texOp.Handle:X}_{texOp.Format.ToGlslFormat()}";
if ((texOp.Type & SamplerType.Indexed) != 0)
{
diff --git a/Ryujinx.Graphics.Shader/IntermediateRepresentation/TextureOperation.cs b/Ryujinx.Graphics.Shader/IntermediateRepresentation/TextureOperation.cs
index 9c5cd25c16..52f02bfb9f 100644
--- a/Ryujinx.Graphics.Shader/IntermediateRepresentation/TextureOperation.cs
+++ b/Ryujinx.Graphics.Shader/IntermediateRepresentation/TextureOperation.cs
@@ -2,9 +2,13 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
{
class TextureOperation : Operation
{
+ private const int DefaultCbufSlot = -1;
+
public SamplerType Type { get; private set; }
public TextureFlags Flags { get; private set; }
+ public int CbufSlot { get; private set; }
+
public int Handle { get; private set; }
public TextureFormat Format { get; set; }
@@ -18,9 +22,10 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
Operand dest,
params Operand[] sources) : base(inst, compIndex, dest, sources)
{
- Type = type;
- Flags = flags;
- Handle = handle;
+ Type = type;
+ Flags = flags;
+ CbufSlot = DefaultCbufSlot;
+ Handle = handle;
}
public void TurnIntoIndexed(int handle)
@@ -30,7 +35,7 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
Handle = handle;
}
- public void SetHandle(int handle)
+ public void SetHandle(int handle, int cbufSlot = DefaultCbufSlot)
{
if ((Flags & TextureFlags.Bindless) != 0)
{
@@ -39,7 +44,8 @@ namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
RemoveSource(0);
}
- Handle = handle;
+ CbufSlot = cbufSlot;
+ Handle = handle;
}
}
}
\ No newline at end of file
diff --git a/Ryujinx.Graphics.Shader/StructuredIr/AstTextureOperation.cs b/Ryujinx.Graphics.Shader/StructuredIr/AstTextureOperation.cs
index 188bf91918..cdb9748805 100644
--- a/Ryujinx.Graphics.Shader/StructuredIr/AstTextureOperation.cs
+++ b/Ryujinx.Graphics.Shader/StructuredIr/AstTextureOperation.cs
@@ -8,6 +8,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
public TextureFormat Format { get; }
public TextureFlags Flags { get; }
+ public int CbufSlot { get; }
public int Handle { get; }
public int ArraySize { get; }
@@ -16,6 +17,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
SamplerType type,
TextureFormat format,
TextureFlags flags,
+ int cbufSlot,
int handle,
int arraySize,
int index,
@@ -24,6 +26,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
Type = type;
Format = format;
Flags = flags;
+ CbufSlot = cbufSlot;
Handle = handle;
ArraySize = arraySize;
}
diff --git a/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs b/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs
index 66570dc98d..733805cde5 100644
--- a/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs
+++ b/Ryujinx.Graphics.Shader/StructuredIr/StructuredProgram.cs
@@ -117,6 +117,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
texOp.Type,
texOp.Format,
texOp.Flags,
+ texOp.CbufSlot,
texOp.Handle,
4, // TODO: Non-hardcoded array size.
texOp.Index,
diff --git a/Ryujinx.Graphics.Shader/TextureDescriptor.cs b/Ryujinx.Graphics.Shader/TextureDescriptor.cs
index b39d6c3d1a..95f5e01dfc 100644
--- a/Ryujinx.Graphics.Shader/TextureDescriptor.cs
+++ b/Ryujinx.Graphics.Shader/TextureDescriptor.cs
@@ -5,46 +5,21 @@ namespace Ryujinx.Graphics.Shader
public int Binding { get; }
public SamplerType Type { get; }
-
public TextureFormat Format { get; }
+ public int CbufSlot { get; }
public int HandleIndex { get; }
- public bool IsBindless { get; }
-
- public int CbufSlot { get; }
- public int CbufOffset { get; }
-
public TextureUsageFlags Flags { get; set; }
- public TextureDescriptor(int binding, SamplerType type, TextureFormat format, int handleIndex)
+ public TextureDescriptor(int binding, SamplerType type, TextureFormat format, int cbufSlot, int handleIndex)
{
Binding = binding;
Type = type;
Format = format;
+ CbufSlot = cbufSlot;
HandleIndex = handleIndex;
-
- IsBindless = false;
-
- CbufSlot = 0;
- CbufOffset = 0;
-
- Flags = TextureUsageFlags.None;
- }
-
- public TextureDescriptor(int binding, SamplerType type, int cbufSlot, int cbufOffset)
- {
- Binding = binding;
- Type = type;
- Format = TextureFormat.Unknown;
- HandleIndex = 0;
-
- IsBindless = true;
-
- CbufSlot = cbufSlot;
- CbufOffset = cbufOffset;
-
- Flags = TextureUsageFlags.None;
+ Flags = TextureUsageFlags.None;
}
public TextureDescriptor SetFlag(TextureUsageFlags flag)
diff --git a/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs b/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs
index a26c81c93e..b326aaa435 100644
--- a/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs
+++ b/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs
@@ -5,15 +5,14 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
{
class BindlessElimination
{
- private const int NvnTextureBufferSlot = 2;
-
public static void RunPass(BasicBlock block, ShaderConfig config)
{
// We can turn a bindless into regular access by recognizing the pattern
// produced by the compiler for separate texture and sampler.
// We check for the following conditions:
+ // - The handle is a constant buffer value.
// - The handle is the result of a bitwise OR logical operation.
- // - Both sources of the OR operation comes from CB2 (used by NVN to hold texture handles).
+ // - Both sources of the OR operation comes from a constant buffer.
for (LinkedListNode node = block.Operations.First; node != null; node = node.Next)
{
if (!(node.Value is TextureOperation texOp))
@@ -26,9 +25,19 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
continue;
}
- if (texOp.Inst == Instruction.TextureSample)
+ if (texOp.Inst == Instruction.Lod ||
+ texOp.Inst == Instruction.TextureSample ||
+ texOp.Inst == Instruction.TextureSize)
{
- if (!(texOp.GetSource(0).AsgOp is Operation handleCombineOp))
+ Operand bindlessHandle = texOp.GetSource(0);
+
+ if (bindlessHandle.Type == OperandType.ConstantBuffer)
+ {
+ texOp.SetHandle(bindlessHandle.GetCbufOffset(), bindlessHandle.GetCbufSlot());
+ continue;
+ }
+
+ if (!(bindlessHandle.AsgOp is Operation handleCombineOp))
{
continue;
}
@@ -41,21 +50,21 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
Operand src0 = handleCombineOp.GetSource(0);
Operand src1 = handleCombineOp.GetSource(1);
- if (src0.Type != OperandType.ConstantBuffer || src0.GetCbufSlot() != NvnTextureBufferSlot ||
- src1.Type != OperandType.ConstantBuffer || src1.GetCbufSlot() != NvnTextureBufferSlot)
+ if (src0.Type != OperandType.ConstantBuffer ||
+ src1.Type != OperandType.ConstantBuffer || src0.GetCbufSlot() != src1.GetCbufSlot())
{
continue;
}
- texOp.SetHandle(src0.GetCbufOffset() | (src1.GetCbufOffset() << 16));
+ texOp.SetHandle(src0.GetCbufOffset() | (src1.GetCbufOffset() << 16), src0.GetCbufSlot());
}
else if (texOp.Inst == Instruction.ImageLoad || texOp.Inst == Instruction.ImageStore)
{
Operand src0 = texOp.GetSource(0);
- if (src0.Type == OperandType.ConstantBuffer && src0.GetCbufSlot() == NvnTextureBufferSlot)
+ if (src0.Type == OperandType.ConstantBuffer)
{
- texOp.SetHandle(src0.GetCbufOffset());
+ texOp.SetHandle(src0.GetCbufOffset(), src0.GetCbufSlot());
texOp.Format = config.GetTextureFormat(texOp.Handle);
}
}
diff --git a/Ryujinx.Graphics.Shader/Translation/Lowering.cs b/Ryujinx.Graphics.Shader/Translation/Rewriter.cs
similarity index 99%
rename from Ryujinx.Graphics.Shader/Translation/Lowering.cs
rename to Ryujinx.Graphics.Shader/Translation/Rewriter.cs
index 6da25983ae..a928f93571 100644
--- a/Ryujinx.Graphics.Shader/Translation/Lowering.cs
+++ b/Ryujinx.Graphics.Shader/Translation/Rewriter.cs
@@ -8,7 +8,7 @@ using static Ryujinx.Graphics.Shader.Translation.GlobalMemory;
namespace Ryujinx.Graphics.Shader.Translation
{
- static class Lowering
+ static class Rewriter
{
public static void RunPass(BasicBlock[] blocks, ShaderConfig config)
{
diff --git a/Ryujinx.Graphics.Shader/Translation/Translator.cs b/Ryujinx.Graphics.Shader/Translation/Translator.cs
index f86b69647c..3485b5ed9d 100644
--- a/Ryujinx.Graphics.Shader/Translation/Translator.cs
+++ b/Ryujinx.Graphics.Shader/Translation/Translator.cs
@@ -96,7 +96,7 @@ namespace Ryujinx.Graphics.Shader.Translation
Optimizer.RunPass(cfg.Blocks, config);
- Lowering.RunPass(cfg.Blocks, config);
+ Rewriter.RunPass(cfg.Blocks, config);
}
funcs[i] = new Function(cfg.Blocks, $"fun{i}", false, inArgumentsCount, outArgumentsCount);
diff --git a/Ryujinx.Graphics.Texture/BCnDecoder.cs b/Ryujinx.Graphics.Texture/BCnDecoder.cs
index 398e835842..b8b04bac2e 100644
--- a/Ryujinx.Graphics.Texture/BCnDecoder.cs
+++ b/Ryujinx.Graphics.Texture/BCnDecoder.cs
@@ -192,7 +192,7 @@ namespace Ryujinx.Graphics.Texture
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static void CalculateBC3Alpha(Span alpha)
+ private static void CalculateBC3Alpha(Span alpha)
{
for (int i = 2; i < 8; i++)
{