mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-22 03:46:53 +02:00
shader: drop the large-input select before sin and cos since fract already returns zero
This commit is contained in:
@@ -162,34 +162,19 @@ uint32_t EmitFlushF32DenormToSignedZero(EmitterState& state, uint32_t value) {
|
||||
}
|
||||
|
||||
uint32_t EmitTrigCycleF32(EmitterState& state, uint32_t src, bool preserve_signed_zero) {
|
||||
const auto fract = state.builder.AllocateId();
|
||||
const auto bits = state.builder.AllocateId();
|
||||
const auto abs_bits = state.builder.AllocateId();
|
||||
const auto large = state.builder.AllocateId();
|
||||
const auto finite = state.builder.AllocateId();
|
||||
const auto large_finite = state.builder.AllocateId();
|
||||
const auto reduced = state.builder.AllocateId();
|
||||
// Finite values of magnitude 2^23 and above are integers, so fract already gives them +0.
|
||||
const auto fract = state.builder.AllocateId();
|
||||
state.builder.AddFunction(spv::OpExtInst, TypeF32(state), fract, GlslStd450(state),
|
||||
GLSLstd450Fract, src);
|
||||
state.builder.AddFunction(spv::OpBitcast, TypeU32(state), bits, src);
|
||||
state.builder.AddFunction(spv::OpBitwiseAnd, TypeU32(state), abs_bits, bits,
|
||||
ConstantU32(state, 0x7fffffffu));
|
||||
state.builder.AddFunction(spv::OpUGreaterThanEqual, TypeBool(state), large, abs_bits,
|
||||
ConstantU32(state, 0x4b000000u));
|
||||
state.builder.AddFunction(spv::OpULessThan, TypeBool(state), finite, abs_bits,
|
||||
ConstantU32(state, 0x7f800000u));
|
||||
state.builder.AddFunction(spv::OpLogicalAnd, TypeBool(state), large_finite, large, finite);
|
||||
state.builder.AddFunction(spv::OpSelect, TypeF32(state), reduced, large_finite,
|
||||
ConstantF32(state, 0), fract);
|
||||
if (!preserve_signed_zero) {
|
||||
return reduced;
|
||||
return fract;
|
||||
}
|
||||
const auto zero = state.builder.AllocateId();
|
||||
const auto ret = state.builder.AllocateId();
|
||||
state.builder.AddFunction(spv::OpIEqual, TypeBool(state), zero, abs_bits,
|
||||
ConstantU32(state, 0));
|
||||
state.builder.AddFunction(spv::OpSelect, TypeF32(state), ret, zero, src, reduced);
|
||||
return ret;
|
||||
const auto abs_bits = Binary(state, spv::OpBitwiseAnd, TypeU32(state),
|
||||
Unary(state, spv::OpBitcast, TypeU32(state), src),
|
||||
ConstantU32(state, 0x7fffffffu));
|
||||
return Select(state, TypeF32(state),
|
||||
Binary(state, spv::OpIEqual, TypeBool(state), abs_bits, ConstantU32(state, 0)),
|
||||
src, fract);
|
||||
}
|
||||
|
||||
uint32_t EmitF16BitsToF32(EmitterState& state, uint32_t bits) {
|
||||
|
||||
@@ -29230,23 +29230,28 @@ TestCase VectorRcpIflagF32IntegerReciprocal() {
|
||||
return test;
|
||||
}
|
||||
|
||||
// Runtime inputs keep the driver from folding; finite values from 2^23 up are whole periods.
|
||||
TestCase VectorSinCosMaxFiniteSpecialCases() {
|
||||
using O = ShaderOpcode;
|
||||
|
||||
std::vector<u32> code;
|
||||
AppendVMovLiteral(&code, 0, 0xff7fffffu);
|
||||
code.push_back(EncodeVop1(0x35, 1, Vgpr(0)));
|
||||
code.push_back(EncodeVop1(0x36, 2, Vgpr(0)));
|
||||
AppendStoreVgpr(&code, 1, 0);
|
||||
AppendStoreVgpr(&code, 2, 1);
|
||||
AppendEnd(&code);
|
||||
|
||||
return {"VectorSinCosMaxFiniteSpecialCases",
|
||||
code,
|
||||
{},
|
||||
{0x00000000u, 0x3f800000u},
|
||||
{O::V_MOV_B32, O::V_SIN_F32, O::V_COS_F32, O::BUFFER_STORE_DWORD,
|
||||
O::S_ENDPGM}};
|
||||
constexpr u32 inputs[] = {0xff7fffffu, 0x7f7fffffu, 0x4b000001u, 0xcb800000u};
|
||||
TestCase test;
|
||||
test.name = "VectorSinCosMaxFiniteSpecialCases";
|
||||
test.initial.assign(std::begin(inputs), std::end(inputs));
|
||||
test.expected = test.initial;
|
||||
for (u32 i = 0; i < std::size(inputs); i++) {
|
||||
AppendVMovU32(&test.code, 30, i * 4u);
|
||||
AppendBufferLoadDword(&test.code, 0, 30);
|
||||
test.code.push_back(EncodeVop1(0x35, 1, Vgpr(0)));
|
||||
test.code.push_back(EncodeVop1(0x36, 2, Vgpr(0)));
|
||||
AppendStoreVgpr(&test.code, 1, u32(test.expected.size()));
|
||||
AppendStoreVgpr(&test.code, 2, u32(test.expected.size() + 1));
|
||||
test.expected.insert(test.expected.end(), {0x00000000u, 0x3f800000u});
|
||||
}
|
||||
AppendEnd(&test.code);
|
||||
test.initial.resize(test.expected.size());
|
||||
test.opcodes = {O::V_MOV_B32, O::BUFFER_LOAD_DWORD, O::V_SIN_F32, O::V_COS_F32,
|
||||
O::BUFFER_STORE_DWORD, O::S_ENDPGM};
|
||||
return test;
|
||||
}
|
||||
|
||||
TestCase VectorCompareF32ExposureGuard() {
|
||||
|
||||
Reference in New Issue
Block a user