Implement Shader Instructions SUATOM and SURED (#2090)
* Initial Implementation * Further improvements (no support for float/64-bit types) * Merge atomic and reduce instructions, add missing format switch * Fix rebase issues. * Not used. * Whoops. Fixed. * Partial implementation of inc/dec, cleanup and TODOs * Remove testing path * Address Feedback
This commit is contained in:
parent
416dc8fde4
commit
142cededd4
16 changed files with 510 additions and 18 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -278,6 +278,7 @@ namespace Ryujinx.Graphics.Shader.Translation.Optimizations
|
|||
case Instruction.AtomicSwap:
|
||||
case Instruction.AtomicXor:
|
||||
case Instruction.Call:
|
||||
case Instruction.ImageAtomic:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue