2015-05-23 22:55:12 -06:00
|
|
|
// Copyright 2009 Dolphin Emulator Project
|
2015-05-17 17:08:10 -06:00
|
|
|
// Licensed under GPLv2+
|
2013-04-17 21:09:55 -06:00
|
|
|
// Refer to the license.txt file included.
|
2009-06-22 03:31:30 -06:00
|
|
|
|
2014-02-17 03:18:15 -07:00
|
|
|
#include "VideoCommon/BPMemory.h"
|
2009-06-22 03:31:30 -06:00
|
|
|
|
2018-05-18 12:25:40 -06:00
|
|
|
#include "Common/BitUtils.h"
|
2017-01-23 13:48:14 -07:00
|
|
|
|
2009-07-26 03:52:35 -06:00
|
|
|
// BP state
|
2009-06-22 03:31:30 -06:00
|
|
|
// STATE_TO_SAVE
|
|
|
|
BPMemory bpmem;
|
2017-01-23 13:48:14 -07:00
|
|
|
|
2017-09-03 00:32:37 -06:00
|
|
|
bool BlendMode::UseLogicOp() const
|
|
|
|
{
|
|
|
|
// Logicop bit has lowest priority.
|
|
|
|
if (subtract || blendenable || !logicopenable)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Fast path for Kirby's Return to Dreamland, they use it with dstAlpha.
|
2021-02-10 19:11:31 -07:00
|
|
|
if (logicmode == LogicOp::NoOp)
|
2017-09-03 00:32:37 -06:00
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-02-01 00:36:30 -07:00
|
|
|
bool FogParams::IsNaNCase() const
|
2017-01-23 13:48:14 -07:00
|
|
|
{
|
2018-02-01 00:36:30 -07:00
|
|
|
// Check for the case where both a and c are infinity or NaN.
|
|
|
|
// On hardware, this results in the following colors:
|
|
|
|
//
|
|
|
|
// -------------------------------------------------------
|
|
|
|
// | A | C | Result | A | C | Result |
|
|
|
|
// -------------------------------------------------------
|
|
|
|
// | inf | inf | Fogged | inf | nan | Fogged |
|
|
|
|
// | inf | -inf | Unfogged | inf | -nan | Unfogged |
|
|
|
|
// | -inf | inf | Unfogged | -inf | nan | Unfogged |
|
|
|
|
// | -inf | -inf | Unfogged | -inf | -nan | Unfogged |
|
|
|
|
// -------------------------------------------------------
|
|
|
|
// | nan | inf | Fogged | nan | nan | Fogged |
|
|
|
|
// | nan | -inf | Unfogged | nan | -nan | Unfogged |
|
|
|
|
// | -nan | inf | Unfogged | -nan | nan | Unfogged |
|
|
|
|
// | -nan | -inf | Unfogged | -nan | -nan | Unfogged |
|
|
|
|
// -------------------------------------------------------
|
|
|
|
//
|
|
|
|
// We replicate this by returning A=0, and C=inf for the inf/inf case, otherwise -inf.
|
|
|
|
// This ensures we do not pass a NaN to the GPU, and -inf/inf clamp to 0/1 respectively.
|
|
|
|
return a.exp == 255 && c_proj_fsel.c_exp == 255;
|
|
|
|
}
|
|
|
|
|
2021-02-11 23:38:07 -07:00
|
|
|
float FogParam0::FloatValue() const
|
|
|
|
{
|
|
|
|
// scale mantissa from 11 to 23 bits
|
|
|
|
const u32 integral = (sign << 31) | (exp << 23) | (mant << 12);
|
|
|
|
return Common::BitCast<float>(integral);
|
|
|
|
}
|
|
|
|
|
|
|
|
float FogParam3::FloatValue() const
|
|
|
|
{
|
|
|
|
// scale mantissa from 11 to 23 bits
|
|
|
|
const u32 integral = (c_sign << 31) | (c_exp << 23) | (c_mant << 12);
|
|
|
|
return Common::BitCast<float>(integral);
|
|
|
|
}
|
|
|
|
|
2018-02-01 00:36:30 -07:00
|
|
|
float FogParams::GetA() const
|
|
|
|
{
|
|
|
|
if (IsNaNCase())
|
|
|
|
return 0.0f;
|
|
|
|
|
2021-02-11 23:38:07 -07:00
|
|
|
return a.FloatValue();
|
2017-01-23 13:48:14 -07:00
|
|
|
}
|
|
|
|
|
2018-02-01 00:36:30 -07:00
|
|
|
float FogParams::GetC() const
|
2017-01-23 13:48:14 -07:00
|
|
|
{
|
2018-02-01 00:36:30 -07:00
|
|
|
if (IsNaNCase())
|
|
|
|
{
|
|
|
|
constexpr float inf = std::numeric_limits<float>::infinity();
|
|
|
|
return !a.sign && !c_proj_fsel.c_sign ? -inf : inf;
|
|
|
|
}
|
|
|
|
|
2021-02-11 23:38:07 -07:00
|
|
|
return c_proj_fsel.FloatValue();
|
2017-01-23 13:48:14 -07:00
|
|
|
}
|