Merge pull request #4705 from karanvora2599/perf/shader-unary-input-flush-once

perf(shader): drop the input flush that rcp, rsq, sqrt, exp and log results never use
This commit is contained in:
Adrià 2026-10-13 17:38:07 +02:00 committed by GitHub
commit fdefd76609
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 9 additions and 31 deletions

View File

@ -131,7 +131,6 @@ F32Class EmitClassifyF32(SpirvEmitterState& state, std::uint32_t value);
std::uint32_t EmitClassMaskBitMatch(SpirvEmitterState& state, std::uint32_t mask, std::uint32_t bit, std::uint32_t classMatch);
std::uint32_t EmitClassMaskF32(SpirvEmitterState& state, std::uint32_t value, std::uint32_t mask);
std::uint32_t EmitMinMaxF32Value(SpirvEmitterState& state, std::uint32_t lhs, std::uint32_t rhs, bool maxValue);
std::uint32_t EmitFlushF32DenormToSignedZero(SpirvEmitterState& state, std::uint32_t value);
std::uint32_t EmitTrigCycleF32(SpirvEmitterState& state, std::uint32_t src, bool preserveSignedZero);
void EmitF16DenormPreserve(SpirvEmitterState& state);
std::uint32_t EmitF16BitsToF32(SpirvEmitterState& state, std::uint32_t bits);

View File

@ -842,8 +842,7 @@ std::uint32_t EmitFPMedTri32(SpirvEmitterState& state, std::uint32_t arg0, std::
}
std::uint32_t EmitFPRecip32(SpirvEmitterState& state, std::uint32_t arg0) {
const auto source = EmitFlushF32DenormToSignedZero(state, arg0);
return Binary(state, spv::OpFDiv, TypeF32(state), ConstantF32(state, 0x3f800000u), source);
return Binary(state, spv::OpFDiv, TypeF32(state), ConstantF32(state, 0x3f800000u), arg0);
}
std::uint32_t EmitFPRecipIFlag32(SpirvEmitterState& state, std::uint32_t arg0) {
@ -851,15 +850,15 @@ std::uint32_t EmitFPRecipIFlag32(SpirvEmitterState& state, std::uint32_t arg0) {
}
std::uint32_t EmitFPRecipSqrt32(SpirvEmitterState& state, std::uint32_t arg0) {
return EmitExt(state, TypeF32(state), GLSLstd450InverseSqrt, {EmitFlushF32DenormToSignedZero(state, arg0)});
return EmitExt(state, TypeF32(state), GLSLstd450InverseSqrt, {arg0});
}
std::uint32_t EmitFPSqrt(SpirvEmitterState& state, std::uint32_t arg0) {
return EmitExt(state, TypeF32(state), GLSLstd450Sqrt, {EmitFlushF32DenormToSignedZero(state, arg0)});
return EmitExt(state, TypeF32(state), GLSLstd450Sqrt, {arg0});
}
std::uint32_t EmitFPExp2(SpirvEmitterState& state, std::uint32_t arg0) {
return EmitExt(state, TypeF32(state), GLSLstd450Exp2, {EmitFlushF32DenormToSignedZero(state, arg0)});
return EmitExt(state, TypeF32(state), GLSLstd450Exp2, {arg0});
}
std::uint32_t Log2SeriesNearOne(SpirvEmitterState& state, std::uint32_t difference) {
@ -872,9 +871,8 @@ std::uint32_t Log2SeriesNearOne(SpirvEmitterState& state, std::uint32_t differen
}
std::uint32_t EmitFPLog2(SpirvEmitterState& state, std::uint32_t arg0) {
const auto source = EmitFlushF32DenormToSignedZero(state, arg0);
const auto value = EmitExt(state, TypeF32(state), GLSLstd450Log2, {source});
const auto difference = Exact(state, Binary(state, spv::OpFSub, TypeF32(state), source, ConstantF32(state, 0x3f800000u)));
const auto value = EmitExt(state, TypeF32(state), GLSLstd450Log2, {arg0});
const auto difference = Exact(state, Binary(state, spv::OpFSub, TypeF32(state), arg0, ConstantF32(state, 0x3f800000u)));
const auto series = Log2SeriesNearOne(state, difference);
const auto valueBits = Unary(state, spv::OpBitcast, TypeU32(state), value);
const auto seriesBits = Unary(state, spv::OpBitcast, TypeU32(state), series);

View File

@ -945,26 +945,6 @@ std::uint32_t EmitMinMaxF32Value(SpirvEmitterState& state, std::uint32_t lhs, st
return Unary(state, spv::OpBitcast, TypeF32(state), resultBits);
}
std::uint32_t EmitFlushF32DenormToSignedZero(SpirvEmitterState& state, std::uint32_t value) {
const auto bits = state.module.AllocateId();
const auto absBits = state.module.AllocateId();
const auto signBits = state.module.AllocateId();
const auto nonZero = state.module.AllocateId();
const auto subnormal = state.module.AllocateId();
const auto flush = state.module.AllocateId();
const auto selected = state.module.AllocateId();
const auto result = state.module.AllocateId();
state.module.AddFunction(spv::OpBitcast, TypeU32(state), bits, value);
state.module.AddFunction(spv::OpBitwiseAnd, TypeU32(state), absBits, bits, ConstantU32(state, 0x7fffffffu));
state.module.AddFunction(spv::OpBitwiseAnd, TypeU32(state), signBits, bits, ConstantU32(state, 0x80000000u));
state.module.AddFunction(spv::OpINotEqual, TypeBool(state), nonZero, absBits, ConstantU32(state, 0u));
state.module.AddFunction(spv::OpULessThan, TypeBool(state), subnormal, absBits, ConstantU32(state, 0x00800000u));
state.module.AddFunction(spv::OpLogicalAnd, TypeBool(state), flush, nonZero, subnormal);
state.module.AddFunction(spv::OpSelect, TypeU32(state), selected, flush, signBits, bits);
state.module.AddFunction(spv::OpBitcast, TypeF32(state), result, selected);
return result;
}
std::uint32_t EmitTrigCycleF32(SpirvEmitterState& state, std::uint32_t src, bool preserveSignedZero) {
const auto rounded = state.module.AllocateId();
const auto reduced = state.module.AllocateId();

View File

@ -356,8 +356,9 @@ void emitEntryPrologue(IrProgram& program, IrBlock& entryBlock, const TranslateO
setVector(static_cast<VectorReg>(vgpr(PixelInput::PositionZ)), builtin(StageInputKind::FragCoord, 2u));
}
if (loaded(PixelInput::PositionW)) {
IrValue& reciprocalW = entryIr.BitCastF32(builtin(StageInputKind::FragCoord, 3u));
IrValue& w = entryIr.Emit(IrOpcode::FPRecip32, IrOpcodeType(IrOpcode::FPRecip32), {&reciprocalW});
IrValue& reciprocalBits = builtin(StageInputKind::FragCoord, 3u);
IrValue& flushed = entryIr.Select(entryIr.IEqual(entryIr.BitwiseAnd(reciprocalBits, entryIr.Constant(0x7f800000u)), entryIr.Constant(0u)), entryIr.BitwiseAnd(reciprocalBits, entryIr.Constant(0x80000000u)), reciprocalBits);
IrValue& w = entryIr.Emit(IrOpcode::FPRecip32, IrOpcodeType(IrOpcode::FPRecip32), {&entryIr.BitCastF32(flushed)});
setVector(static_cast<VectorReg>(vgpr(PixelInput::PositionW)), entryIr.BitCastU32(w));
}
if (loaded(PixelInput::FrontFace)) {