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/Optimizations/BindlessElimination.cs15
-rw-r--r--Ryujinx.Graphics.Shader/Translation/Optimizations/Optimizer.cs1
-rw-r--r--Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs26
3 files changed, 38 insertions, 4 deletions
diff --git a/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs b/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs
index e66bde0a..709668f4 100644
--- a/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs
+++ b/Ryujinx.Graphics.Shader/Translation/Optimizations/BindlessElimination.cs
@@ -61,7 +61,9 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
src0.GetCbufOffset() | ((src1.GetCbufOffset() + 1) << 16),
src0.GetCbufSlot() | ((src1.GetCbufSlot() + 1) << 16));
}
- else if (texOp.Inst == Instruction.ImageLoad || texOp.Inst == Instruction.ImageStore)
+ else if (texOp.Inst == Instruction.ImageLoad ||
+ texOp.Inst == Instruction.ImageStore ||
+ texOp.Inst == Instruction.ImageAtomic)
{
Operand src0 = Utils.FindLastOperation(texOp.GetSource(0), block);
@@ -69,7 +71,16 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
{
int cbufOffset = src0.GetCbufOffset();
int cbufSlot = src0.GetCbufSlot();
- texOp.Format = config.GetTextureFormat(cbufOffset, cbufSlot);
+
+ if (texOp.Inst == Instruction.ImageAtomic)
+ {
+ texOp.Format = config.GetTextureFormatAtomic(cbufOffset, cbufSlot);
+ }
+ else
+ {
+ texOp.Format = config.GetTextureFormat(cbufOffset, cbufSlot);
+ }
+
SetHandle(config, texOp, cbufOffset, cbufSlot);
}
}
diff --git a/Ryujinx.Graphics.Shader/Translation/Optimizations/Optimizer.cs b/Ryujinx.Graphics.Shader/Translation/Optimizations/Optimizer.cs
index 51fe825f..078f3bb9 100644
--- a/Ryujinx.Graphics.Shader/Translation/Optimizations/Optimizer.cs
+++ b/Ryujinx.Graphics.Shader/Translation/Optimizations/Optimizer.cs
@@ -278,6 +278,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
case Instruction.AtomicSwap:
case Instruction.AtomicXor:
case Instruction.Call:
+ case Instruction.ImageAtomic:
return true;
}
}
diff --git a/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs b/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs
index f454ceea..7d3246db 100644
--- a/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs
+++ b/Ryujinx.Graphics.Shader/Translation/ShaderConfig.cs
@@ -162,6 +162,28 @@ namespace Ryujinx.Graphics.Shader.Translation
return format;
}
+ private bool FormatSupportsAtomic(TextureFormat format)
+ {
+ return format == TextureFormat.R32Sint || format == TextureFormat.R32Uint;
+ }
+
+ public TextureFormat GetTextureFormatAtomic(int handle, int cbufSlot = -1)
+ {
+ // Atomic image instructions do not support GL_EXT_shader_image_load_formatted,
+ // and must have a type specified. Default to R32Sint if not available.
+
+ var format = GpuAccessor.QueryTextureFormat(handle, cbufSlot);
+
+ if (!FormatSupportsAtomic(format))
+ {
+ GpuAccessor.Log($"Unsupported format for texture {handle}: {format}.");
+
+ format = TextureFormat.R32Sint;
+ }
+
+ return format;
+ }
+
public void SizeAdd(int size)
{
Size += size;
@@ -270,8 +292,8 @@ namespace Ryujinx.Graphics.Shader.Translation
int handle)
{
inst &= Instruction.Mask;
- bool isImage = inst == Instruction.ImageLoad || inst == Instruction.ImageStore;
- bool isWrite = inst == Instruction.ImageStore;
+ bool isImage = inst == Instruction.ImageLoad || inst == Instruction.ImageStore || inst == Instruction.ImageAtomic;
+ bool isWrite = inst == Instruction.ImageStore || inst == Instruction.ImageAtomic;
bool accurateType = inst != Instruction.TextureSize && inst != Instruction.Lod;
if (isImage)