shader: evaluate saturating float-to-signed conversions in runtime descriptor values

This commit is contained in:
Claxten
2026-10-27 01:43:04 +01:00
committed by nmzik
parent 99f4eba223
commit 0a72641678
2 changed files with 47 additions and 0 deletions
@@ -82,6 +82,7 @@ bool IsRuntimeUniformOp(ValueOpcode op) {
case ValueOpcode::BitCastU32F32:
case ValueOpcode::BitCastF32U32:
case ValueOpcode::ConvertU32F32:
case ValueOpcode::ConvertS32F32:
case ValueOpcode::ConvertF32U32:
case ValueOpcode::CompositeConstructU64:
case ValueOpcode::CompositeExtractU64:
@@ -1038,6 +1039,23 @@ void WalkerCompiler::EmitStrict(const Node& node) {
c.L(done);
break;
}
case ValueOpcode::ConvertS32F32: {
// The conversion saturates and maps NaN to zero. cvttss2si's out-of-range result,
// INT32_MIN, is already right for negative overflow.
Xbyak::Label done;
c.movd(c.xmm0, c.eax);
c.xor_(c.eax, c.eax);
c.ucomiss(c.xmm0, c.xmm0);
c.jp(done, Near);
c.mov(c.ecx, 0x4f000000u);
c.movd(c.xmm1, c.ecx);
c.mov(c.eax, INT32_MAX);
c.ucomiss(c.xmm0, c.xmm1);
c.jae(done, Near);
c.cvttss2si(c.eax, c.xmm0);
c.L(done);
break;
}
case ValueOpcode::FPMul32:
c.movd(c.xmm0, c.eax);
c.movd(c.xmm1, c.ecx);