Precise Float Fixes

Fixes artifacts in TOTK
This commit is contained in:
Isaac Marovitz 2024-08-01 15:51:06 +01:00 committed by Isaac Marovitz
parent 3360740250
commit 8fa8f3a390
12 changed files with 52 additions and 5 deletions

View file

@ -122,6 +122,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/SwizzleAdd.metal"); AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/SwizzleAdd.metal");
} }
if ((info.HelperFunctionsMask & HelperFunctionsMask.Precise) != 0)
{
AppendHelperFunction(context, "Ryujinx.Graphics.Shader/CodeGen/Msl/HelperFunctions/Precise.metal");
}
return sets; return sets;
} }

View file

@ -0,0 +1,14 @@
template<typename T>
[[clang::optnone]] T PreciseFAdd(T l, T r) {
return fma(T(1), l, r);
}
template<typename T>
[[clang::optnone]] T PreciseFSub(T l, T r) {
return fma(T(-1), r, l);
}
template<typename T>
[[clang::optnone]] T PreciseFMul(T l, T r) {
return fma(l, r, T(0));
}

View file

@ -118,6 +118,18 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl.Instructions
return op + expr[0]; return op + expr[0];
case 2: case 2:
if (operation.ForcePrecise)
{
var func = (inst & Instruction.Mask) switch
{
Instruction.Add => "PreciseFAdd",
Instruction.Subtract => "PreciseFSub",
Instruction.Multiply => "PreciseFMul",
};
return $"{func}({expr[0]}, {expr[1]})";
}
return $"{expr[0]} {op} {expr[1]}"; return $"{expr[0]} {op} {expr[1]}";
case 3: case 3:

View file

@ -49,9 +49,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
return false; return false;
} }
formatted = value.ToString("F9", CultureInfo.InvariantCulture); formatted = value.ToString("G9", CultureInfo.InvariantCulture);
if (!formatted.Contains('.')) if (!(formatted.Contains('.') ||
formatted.Contains('e') ||
formatted.Contains('E')))
{ {
formatted += ".0f"; formatted += ".0f";
} }

View file

@ -20,5 +20,6 @@
<EmbeddedResource Include="CodeGen\Msl\HelperFunctions\FindMSBS32.metal" /> <EmbeddedResource Include="CodeGen\Msl\HelperFunctions\FindMSBS32.metal" />
<EmbeddedResource Include="CodeGen\Msl\HelperFunctions\FindMSBU32.metal" /> <EmbeddedResource Include="CodeGen\Msl\HelperFunctions\FindMSBU32.metal" />
<EmbeddedResource Include="CodeGen\Msl\HelperFunctions\SwizzleAdd.metal" /> <EmbeddedResource Include="CodeGen\Msl\HelperFunctions\SwizzleAdd.metal" />
<EmbeddedResource Include="CodeGen\Msl\HelperFunctions\Precise.metal" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View file

@ -14,5 +14,7 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
SwizzleAdd = 1 << 10, SwizzleAdd = 1 << 10,
FSI = 1 << 11, FSI = 1 << 11,
Precise = 1 << 13
} }
} }

View file

@ -18,9 +18,10 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
ShaderDefinitions definitions, ShaderDefinitions definitions,
ResourceManager resourceManager, ResourceManager resourceManager,
TargetLanguage targetLanguage, TargetLanguage targetLanguage,
bool precise,
bool debugMode) bool debugMode)
{ {
StructuredProgramContext context = new(attributeUsage, definitions, resourceManager, debugMode); StructuredProgramContext context = new(attributeUsage, definitions, resourceManager, precise, debugMode);
for (int funcIndex = 0; funcIndex < functions.Count; funcIndex++) for (int funcIndex = 0; funcIndex < functions.Count; funcIndex++)
{ {

View file

@ -36,9 +36,10 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
AttributeUsage attributeUsage, AttributeUsage attributeUsage,
ShaderDefinitions definitions, ShaderDefinitions definitions,
ResourceManager resourceManager, ResourceManager resourceManager,
bool precise,
bool debugMode) bool debugMode)
{ {
Info = new StructuredProgramInfo(); Info = new StructuredProgramInfo(precise);
Definitions = definitions; Definitions = definitions;
ResourceManager = resourceManager; ResourceManager = resourceManager;

View file

@ -10,11 +10,16 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
public HelperFunctionsMask HelperFunctionsMask { get; set; } public HelperFunctionsMask HelperFunctionsMask { get; set; }
public StructuredProgramInfo() public StructuredProgramInfo(bool precise)
{ {
Functions = new List<StructuredFunction>(); Functions = new List<StructuredFunction>();
IoDefinitions = new HashSet<IoDefinition>(); IoDefinitions = new HashSet<IoDefinition>();
if (precise)
{
HelperFunctionsMask |= HelperFunctionsMask.Precise;
}
} }
} }
} }

View file

@ -26,5 +26,6 @@ namespace Ryujinx.Graphics.Shader.Translation
SharedMemory = 1 << 11, SharedMemory = 1 << 11,
Store = 1 << 12, Store = 1 << 12,
VtgAsCompute = 1 << 13, VtgAsCompute = 1 << 13,
Precise = 1 << 14,
} }
} }

View file

@ -27,6 +27,8 @@ namespace Ryujinx.Graphics.Shader.Translation.Transforms
addOp.Inst == (Instruction.FP32 | Instruction.Add) && addOp.Inst == (Instruction.FP32 | Instruction.Add) &&
addOp.GetSource(1).Type == OperandType.Constant) addOp.GetSource(1).Type == OperandType.Constant)
{ {
context.UsedFeatures |= FeatureFlags.Precise;
addOp.ForcePrecise = true; addOp.ForcePrecise = true;
} }

View file

@ -332,6 +332,7 @@ namespace Ryujinx.Graphics.Shader.Translation
definitions, definitions,
resourceManager, resourceManager,
Options.TargetLanguage, Options.TargetLanguage,
usedFeatures.HasFlag(FeatureFlags.Precise),
Options.Flags.HasFlag(TranslationFlags.DebugMode)); Options.Flags.HasFlag(TranslationFlags.DebugMode));
int geometryVerticesPerPrimitive = Definitions.OutputTopology switch int geometryVerticesPerPrimitive = Definitions.OutputTopology switch