[SpirvTranslator] Match guest F32 denormal and trigonometric semantics
Co-authored-by: Sekai <140012992+SekaixX@users.noreply.github.com>
This commit is contained in:
parent
c566dba5a1
commit
b368247d64
|
|
@ -442,6 +442,15 @@ public static partial class Gen5SpirvTranslator
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "VRcpF32":
|
case "VRcpF32":
|
||||||
|
result = EmitFloatResult(
|
||||||
|
instruction,
|
||||||
|
_module.AddInstruction(
|
||||||
|
SpirvOp.FDiv,
|
||||||
|
_floatType,
|
||||||
|
Float(1),
|
||||||
|
EmitFlushF32DenormToSignedZero(
|
||||||
|
GetFloatSource(instruction, 0))));
|
||||||
|
break;
|
||||||
case "VRcpIflagF32":
|
case "VRcpIflagF32":
|
||||||
result = EmitFloatResult(
|
result = EmitFloatResult(
|
||||||
instruction,
|
instruction,
|
||||||
|
|
@ -454,7 +463,11 @@ public static partial class Gen5SpirvTranslator
|
||||||
case "VLogF32":
|
case "VLogF32":
|
||||||
result = EmitFloatResult(
|
result = EmitFloatResult(
|
||||||
instruction,
|
instruction,
|
||||||
Ext(30, _floatType, GetFloatSource(instruction, 0)));
|
Ext(
|
||||||
|
30,
|
||||||
|
_floatType,
|
||||||
|
EmitFlushF32DenormToSignedZero(
|
||||||
|
GetFloatSource(instruction, 0))));
|
||||||
break;
|
break;
|
||||||
case "VLdexpF32":
|
case "VLdexpF32":
|
||||||
result = EmitFloatResult(
|
result = EmitFloatResult(
|
||||||
|
|
@ -468,12 +481,20 @@ public static partial class Gen5SpirvTranslator
|
||||||
case "VExpF32":
|
case "VExpF32":
|
||||||
result = EmitFloatResult(
|
result = EmitFloatResult(
|
||||||
instruction,
|
instruction,
|
||||||
Ext(29, _floatType, GetFloatSource(instruction, 0)));
|
Ext(
|
||||||
|
29,
|
||||||
|
_floatType,
|
||||||
|
EmitFlushF32DenormToSignedZero(
|
||||||
|
GetFloatSource(instruction, 0))));
|
||||||
break;
|
break;
|
||||||
case "VRsqF32":
|
case "VRsqF32":
|
||||||
result = EmitFloatResult(
|
result = EmitFloatResult(
|
||||||
instruction,
|
instruction,
|
||||||
Ext(32, _floatType, GetFloatSource(instruction, 0)));
|
Ext(
|
||||||
|
32,
|
||||||
|
_floatType,
|
||||||
|
EmitFlushF32DenormToSignedZero(
|
||||||
|
GetFloatSource(instruction, 0))));
|
||||||
break;
|
break;
|
||||||
case "VRcpF16":
|
case "VRcpF16":
|
||||||
result = EmitFloat16Result(instruction, destination, _module.AddInstruction(SpirvOp.FDiv, _floatType, Float(1), GetFloat16Source(instruction, 0)));
|
result = EmitFloat16Result(instruction, destination, _module.AddInstruction(SpirvOp.FDiv, _floatType, Float(1), GetFloat16Source(instruction, 0)));
|
||||||
|
|
@ -542,7 +563,11 @@ public static partial class Gen5SpirvTranslator
|
||||||
case "VSqrtF32":
|
case "VSqrtF32":
|
||||||
result = EmitFloatResult(
|
result = EmitFloatResult(
|
||||||
instruction,
|
instruction,
|
||||||
Ext(31, _floatType, GetFloatSource(instruction, 0)));
|
Ext(
|
||||||
|
31,
|
||||||
|
_floatType,
|
||||||
|
EmitFlushF32DenormToSignedZero(
|
||||||
|
GetFloatSource(instruction, 0))));
|
||||||
break;
|
break;
|
||||||
case "VSinF32":
|
case "VSinF32":
|
||||||
result = EmitFloatResult(
|
result = EmitFloatResult(
|
||||||
|
|
@ -553,7 +578,9 @@ public static partial class Gen5SpirvTranslator
|
||||||
_module.AddInstruction(
|
_module.AddInstruction(
|
||||||
SpirvOp.FMul,
|
SpirvOp.FMul,
|
||||||
_floatType,
|
_floatType,
|
||||||
GetFloatSource(instruction, 0),
|
EmitTrigCycleF32(
|
||||||
|
GetFloatSource(instruction, 0),
|
||||||
|
preserveSignedZero: true),
|
||||||
Float(MathF.Tau))));
|
Float(MathF.Tau))));
|
||||||
break;
|
break;
|
||||||
case "VCosF32":
|
case "VCosF32":
|
||||||
|
|
@ -565,7 +592,9 @@ public static partial class Gen5SpirvTranslator
|
||||||
_module.AddInstruction(
|
_module.AddInstruction(
|
||||||
SpirvOp.FMul,
|
SpirvOp.FMul,
|
||||||
_floatType,
|
_floatType,
|
||||||
GetFloatSource(instruction, 0),
|
EmitTrigCycleF32(
|
||||||
|
GetFloatSource(instruction, 0),
|
||||||
|
preserveSignedZero: false),
|
||||||
Float(MathF.Tau))));
|
Float(MathF.Tau))));
|
||||||
break;
|
break;
|
||||||
case "VAddF32":
|
case "VAddF32":
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,91 @@
|
||||||
|
// Copyright (C) 2026 SharpEmu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
namespace SharpEmu.ShaderCompiler.Vulkan;
|
||||||
|
|
||||||
|
public static partial class Gen5SpirvTranslator
|
||||||
|
{
|
||||||
|
private sealed partial class CompilationContext
|
||||||
|
{
|
||||||
|
private uint EmitFlushF32DenormToSignedZero(uint value)
|
||||||
|
{
|
||||||
|
var bits = Bitcast(_uintType, value);
|
||||||
|
var absolute = _module.AddInstruction(
|
||||||
|
SpirvOp.BitwiseAnd,
|
||||||
|
_uintType,
|
||||||
|
bits,
|
||||||
|
UInt(0x7FFF_FFFF));
|
||||||
|
var sign = _module.AddInstruction(
|
||||||
|
SpirvOp.BitwiseAnd,
|
||||||
|
_uintType,
|
||||||
|
bits,
|
||||||
|
UInt(0x8000_0000));
|
||||||
|
var nonZero = IsNotZero(absolute);
|
||||||
|
var subnormal = _module.AddInstruction(
|
||||||
|
SpirvOp.ULessThan,
|
||||||
|
_boolType,
|
||||||
|
absolute,
|
||||||
|
UInt(0x0080_0000));
|
||||||
|
var flush = _module.AddInstruction(
|
||||||
|
SpirvOp.LogicalAnd,
|
||||||
|
_boolType,
|
||||||
|
nonZero,
|
||||||
|
subnormal);
|
||||||
|
var selected = _module.AddInstruction(
|
||||||
|
SpirvOp.Select,
|
||||||
|
_uintType,
|
||||||
|
flush,
|
||||||
|
sign,
|
||||||
|
bits);
|
||||||
|
return Bitcast(_floatType, selected);
|
||||||
|
}
|
||||||
|
|
||||||
|
private uint EmitTrigCycleF32(uint source, bool preserveSignedZero)
|
||||||
|
{
|
||||||
|
var fraction = Ext(10, _floatType, source);
|
||||||
|
var bits = Bitcast(_uintType, source);
|
||||||
|
var absolute = _module.AddInstruction(
|
||||||
|
SpirvOp.BitwiseAnd,
|
||||||
|
_uintType,
|
||||||
|
bits,
|
||||||
|
UInt(0x7FFF_FFFF));
|
||||||
|
var large = _module.AddInstruction(
|
||||||
|
SpirvOp.UGreaterThanEqual,
|
||||||
|
_boolType,
|
||||||
|
absolute,
|
||||||
|
UInt(0x4B00_0000));
|
||||||
|
var finite = _module.AddInstruction(
|
||||||
|
SpirvOp.ULessThan,
|
||||||
|
_boolType,
|
||||||
|
absolute,
|
||||||
|
UInt(0x7F80_0000));
|
||||||
|
var largeFinite = _module.AddInstruction(
|
||||||
|
SpirvOp.LogicalAnd,
|
||||||
|
_boolType,
|
||||||
|
large,
|
||||||
|
finite);
|
||||||
|
var reduced = _module.AddInstruction(
|
||||||
|
SpirvOp.Select,
|
||||||
|
_floatType,
|
||||||
|
largeFinite,
|
||||||
|
Float(0),
|
||||||
|
fraction);
|
||||||
|
if (!preserveSignedZero)
|
||||||
|
{
|
||||||
|
return reduced;
|
||||||
|
}
|
||||||
|
|
||||||
|
var zero = _module.AddInstruction(
|
||||||
|
SpirvOp.IEqual,
|
||||||
|
_boolType,
|
||||||
|
absolute,
|
||||||
|
UInt(0));
|
||||||
|
return _module.AddInstruction(
|
||||||
|
SpirvOp.Select,
|
||||||
|
_floatType,
|
||||||
|
zero,
|
||||||
|
source,
|
||||||
|
reduced);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue