mirror of
				https://github.com/dolphin-emu/dolphin.git
				synced 2025-10-25 01:19:19 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			80 lines
		
	
	
	
		
			2.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			80 lines
		
	
	
	
		
			2.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // Copyright 2009 Dolphin Emulator Project
 | |
| // SPDX-License-Identifier: GPL-2.0-or-later
 | |
| 
 | |
| #include "VideoCommon/BPMemory.h"
 | |
| 
 | |
| #include <bit>
 | |
| 
 | |
| // BP state
 | |
| // STATE_TO_SAVE
 | |
| BPMemory bpmem;
 | |
| 
 | |
| bool BlendMode::UseLogicOp() const
 | |
| {
 | |
|   // Blending overrides the logicop bit.
 | |
|   if (blend_enable || !logic_op_enable)
 | |
|     return false;
 | |
| 
 | |
|   // Fast path for Kirby's Return to Dreamland, they use it with dstAlpha.
 | |
|   if (logic_mode == LogicOp::NoOp)
 | |
|     return false;
 | |
| 
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| bool FogParams::IsNaNCase() const
 | |
| {
 | |
|   // 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;
 | |
| }
 | |
| 
 | |
| float FogParam0::FloatValue() const
 | |
| {
 | |
|   // scale mantissa from 11 to 23 bits
 | |
|   const u32 integral = (sign << 31) | (exp << 23) | (mant << 12);
 | |
|   return std::bit_cast<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 std::bit_cast<float>(integral);
 | |
| }
 | |
| 
 | |
| float FogParams::GetA() const
 | |
| {
 | |
|   if (IsNaNCase())
 | |
|     return 0.0f;
 | |
| 
 | |
|   return a.FloatValue();
 | |
| }
 | |
| 
 | |
| float FogParams::GetC() const
 | |
| {
 | |
|   if (IsNaNCase())
 | |
|   {
 | |
|     constexpr float inf = std::numeric_limits<float>::infinity();
 | |
|     return !a.sign && !c_proj_fsel.c_sign ? -inf : inf;
 | |
|   }
 | |
| 
 | |
|   return c_proj_fsel.FloatValue();
 | |
| }
 |