PixelEngine: Convert to BitField and enum class
This commit is contained in:
parent
45b8ebeb25
commit
8882eb040a
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
|
#include "Common/BitField.h"
|
||||||
#include "Common/ChunkFile.h"
|
#include "Common/ChunkFile.h"
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
|
@ -24,70 +25,115 @@
|
||||||
|
|
||||||
namespace PixelEngine
|
namespace PixelEngine
|
||||||
{
|
{
|
||||||
|
// Note: These enums are (assumed to be) identical to the one in BPMemory, but the base type is set
|
||||||
|
// to u16 instead of u32 for BitField
|
||||||
|
enum class CompareMode : u16
|
||||||
|
{
|
||||||
|
Never = 0,
|
||||||
|
Less = 1,
|
||||||
|
Equal = 2,
|
||||||
|
LEqual = 3,
|
||||||
|
Greater = 4,
|
||||||
|
NEqual = 5,
|
||||||
|
GEqual = 6,
|
||||||
|
Always = 7
|
||||||
|
};
|
||||||
|
|
||||||
union UPEZConfReg
|
union UPEZConfReg
|
||||||
{
|
{
|
||||||
u16 Hex;
|
u16 hex;
|
||||||
struct
|
BitField<0, 1, bool, u16> z_comparator_enable;
|
||||||
{
|
BitField<1, 3, CompareMode, u16> function;
|
||||||
u16 ZCompEnable : 1; // Z Comparator Enable
|
BitField<4, 1, bool, u16> z_update_enable;
|
||||||
u16 Function : 3;
|
};
|
||||||
u16 ZUpdEnable : 1;
|
|
||||||
u16 : 11;
|
enum class SrcBlendFactor : u16
|
||||||
};
|
{
|
||||||
|
Zero = 0,
|
||||||
|
One = 1,
|
||||||
|
DstClr = 2,
|
||||||
|
InvDstClr = 3,
|
||||||
|
SrcAlpha = 4,
|
||||||
|
InvSrcAlpha = 5,
|
||||||
|
DstAlpha = 6,
|
||||||
|
InvDstAlpha = 7
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class DstBlendFactor : u16
|
||||||
|
{
|
||||||
|
Zero = 0,
|
||||||
|
One = 1,
|
||||||
|
SrcClr = 2,
|
||||||
|
InvSrcClr = 3,
|
||||||
|
SrcAlpha = 4,
|
||||||
|
InvSrcAlpha = 5,
|
||||||
|
DstAlpha = 6,
|
||||||
|
InvDstAlpha = 7
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class LogicOp : u16
|
||||||
|
{
|
||||||
|
Clear = 0,
|
||||||
|
And = 1,
|
||||||
|
AndReverse = 2,
|
||||||
|
Copy = 3,
|
||||||
|
AndInverted = 4,
|
||||||
|
NoOp = 5,
|
||||||
|
Xor = 6,
|
||||||
|
Or = 7,
|
||||||
|
Nor = 8,
|
||||||
|
Equiv = 9,
|
||||||
|
Invert = 10,
|
||||||
|
OrReverse = 11,
|
||||||
|
CopyInverted = 12,
|
||||||
|
OrInverted = 13,
|
||||||
|
Nand = 14,
|
||||||
|
Set = 15
|
||||||
};
|
};
|
||||||
|
|
||||||
union UPEAlphaConfReg
|
union UPEAlphaConfReg
|
||||||
{
|
{
|
||||||
u16 Hex;
|
u16 hex;
|
||||||
struct
|
BitField<0, 1, bool, u16> blend; // Set for GX_BM_BLEND or GX_BM_SUBTRACT
|
||||||
{
|
BitField<1, 1, bool, u16> logic; // Set for GX_BM_LOGIC
|
||||||
u16 BMMath : 1; // GX_BM_BLEND || GX_BM_SUBSTRACT
|
BitField<2, 1, bool, u16> dither;
|
||||||
u16 BMLogic : 1; // GX_BM_LOGIC
|
BitField<3, 1, bool, u16> color_update_enable;
|
||||||
u16 Dither : 1;
|
BitField<4, 1, bool, u16> alpha_update_enable;
|
||||||
u16 ColorUpdEnable : 1;
|
BitField<5, 3, DstBlendFactor, u16> dst_factor;
|
||||||
u16 AlphaUpdEnable : 1;
|
BitField<8, 3, SrcBlendFactor, u16> src_factor;
|
||||||
u16 DstFactor : 3;
|
BitField<11, 1, bool, u16> subtract; // Set for GX_BM_SUBTRACT
|
||||||
u16 SrcFactor : 3;
|
BitField<12, 4, LogicOp, u16> logic_op;
|
||||||
u16 Substract : 1; // Additive mode by default
|
|
||||||
u16 BlendOperator : 4;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
union UPEDstAlphaConfReg
|
union UPEDstAlphaConfReg
|
||||||
{
|
{
|
||||||
u16 Hex;
|
u16 hex;
|
||||||
struct
|
BitField<0, 8, u8, u16> alpha;
|
||||||
{
|
BitField<8, 1, bool, u16> enable;
|
||||||
u16 DstAlpha : 8;
|
|
||||||
u16 Enable : 1;
|
|
||||||
u16 : 7;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
union UPEAlphaModeConfReg
|
union UPEAlphaModeConfReg
|
||||||
{
|
{
|
||||||
u16 Hex;
|
u16 hex;
|
||||||
struct
|
BitField<0, 8, u8, u16> threshold;
|
||||||
{
|
// Yagcd and libogc use 8 bits for this, but the enum only needs 3
|
||||||
u16 Threshold : 8;
|
BitField<8, 3, CompareMode, u16> compare_mode;
|
||||||
u16 CompareMode : 8;
|
};
|
||||||
};
|
|
||||||
|
union UPEAlphaReadReg
|
||||||
|
{
|
||||||
|
u16 hex;
|
||||||
|
BitField<0, 2, AlphaReadMode, u16> read_mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
// fifo Control Register
|
// fifo Control Register
|
||||||
union UPECtrlReg
|
union UPECtrlReg
|
||||||
{
|
{
|
||||||
struct
|
u16 hex;
|
||||||
{
|
BitField<0, 1, bool, u16> pe_token_enable;
|
||||||
u16 PETokenEnable : 1;
|
BitField<1, 1, bool, u16> pe_finish_enable;
|
||||||
u16 PEFinishEnable : 1;
|
BitField<2, 1, bool, u16> pe_token; // Write only
|
||||||
u16 PEToken : 1; // write only
|
BitField<3, 1, bool, u16> pe_finish; // Write only
|
||||||
u16 PEFinish : 1; // write only
|
|
||||||
u16 : 12;
|
|
||||||
};
|
|
||||||
u16 Hex;
|
|
||||||
UPECtrlReg() { Hex = 0; }
|
|
||||||
UPECtrlReg(u16 _hex) { Hex = _hex; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// STATE_TO_SAVE
|
// STATE_TO_SAVE
|
||||||
|
@ -140,12 +186,12 @@ static void SetTokenFinish_OnMainThread(u64 userdata, s64 cyclesLate);
|
||||||
|
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
m_Control.Hex = 0;
|
m_Control.hex = 0;
|
||||||
m_ZConf.Hex = 0;
|
m_ZConf.hex = 0;
|
||||||
m_AlphaConf.Hex = 0;
|
m_AlphaConf.hex = 0;
|
||||||
m_DstAlphaConf.Hex = 0;
|
m_DstAlphaConf.hex = 0;
|
||||||
m_AlphaModeConf.Hex = 0;
|
m_AlphaModeConf.hex = 0;
|
||||||
m_AlphaRead.Hex = 0;
|
m_AlphaRead.hex = 0;
|
||||||
|
|
||||||
s_token = 0;
|
s_token = 0;
|
||||||
s_token_pending = 0;
|
s_token_pending = 0;
|
||||||
|
@ -168,11 +214,11 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
||||||
u32 addr;
|
u32 addr;
|
||||||
u16* ptr;
|
u16* ptr;
|
||||||
} directly_mapped_vars[] = {
|
} directly_mapped_vars[] = {
|
||||||
{PE_ZCONF, &m_ZConf.Hex},
|
{PE_ZCONF, &m_ZConf.hex},
|
||||||
{PE_ALPHACONF, &m_AlphaConf.Hex},
|
{PE_ALPHACONF, &m_AlphaConf.hex},
|
||||||
{PE_DSTALPHACONF, &m_DstAlphaConf.Hex},
|
{PE_DSTALPHACONF, &m_DstAlphaConf.hex},
|
||||||
{PE_ALPHAMODE, &m_AlphaModeConf.Hex},
|
{PE_ALPHAMODE, &m_AlphaModeConf.hex},
|
||||||
{PE_ALPHAREAD, &m_AlphaRead.Hex},
|
{PE_ALPHAREAD, &m_AlphaRead.hex},
|
||||||
};
|
};
|
||||||
for (auto& mapped_var : directly_mapped_vars)
|
for (auto& mapped_var : directly_mapped_vars)
|
||||||
{
|
{
|
||||||
|
@ -207,20 +253,20 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Control register
|
// Control register
|
||||||
mmio->Register(base | PE_CTRL_REGISTER, MMIO::DirectRead<u16>(&m_Control.Hex),
|
mmio->Register(base | PE_CTRL_REGISTER, MMIO::DirectRead<u16>(&m_Control.hex),
|
||||||
MMIO::ComplexWrite<u16>([](u32, u16 val) {
|
MMIO::ComplexWrite<u16>([](u32, u16 val) {
|
||||||
UPECtrlReg tmpCtrl(val);
|
UPECtrlReg tmpCtrl{.hex = val};
|
||||||
|
|
||||||
if (tmpCtrl.PEToken)
|
if (tmpCtrl.pe_token)
|
||||||
s_signal_token_interrupt = false;
|
s_signal_token_interrupt = false;
|
||||||
|
|
||||||
if (tmpCtrl.PEFinish)
|
if (tmpCtrl.pe_finish)
|
||||||
s_signal_finish_interrupt = false;
|
s_signal_finish_interrupt = false;
|
||||||
|
|
||||||
m_Control.PETokenEnable = tmpCtrl.PETokenEnable;
|
m_Control.pe_token_enable = tmpCtrl.pe_token_enable.Value();
|
||||||
m_Control.PEFinishEnable = tmpCtrl.PEFinishEnable;
|
m_Control.pe_finish_enable = tmpCtrl.pe_finish_enable.Value();
|
||||||
m_Control.PEToken = 0; // this flag is write only
|
m_Control.pe_token = false; // this flag is write only
|
||||||
m_Control.PEFinish = 0; // this flag is write only
|
m_Control.pe_finish = false; // this flag is write only
|
||||||
|
|
||||||
DEBUG_LOG_FMT(PIXELENGINE, "(w16) CTRL_REGISTER: {:#06x}", val);
|
DEBUG_LOG_FMT(PIXELENGINE, "(w16) CTRL_REGISTER: {:#06x}", val);
|
||||||
UpdateInterrupts();
|
UpdateInterrupts();
|
||||||
|
@ -244,11 +290,11 @@ static void UpdateInterrupts()
|
||||||
{
|
{
|
||||||
// check if there is a token-interrupt
|
// check if there is a token-interrupt
|
||||||
ProcessorInterface::SetInterrupt(INT_CAUSE_PE_TOKEN,
|
ProcessorInterface::SetInterrupt(INT_CAUSE_PE_TOKEN,
|
||||||
s_signal_token_interrupt && m_Control.PETokenEnable);
|
s_signal_token_interrupt && m_Control.pe_token_enable);
|
||||||
|
|
||||||
// check if there is a finish-interrupt
|
// check if there is a finish-interrupt
|
||||||
ProcessorInterface::SetInterrupt(INT_CAUSE_PE_FINISH,
|
ProcessorInterface::SetInterrupt(INT_CAUSE_PE_FINISH,
|
||||||
s_signal_finish_interrupt && m_Control.PEFinishEnable);
|
s_signal_finish_interrupt && m_Control.pe_finish_enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetTokenFinish_OnMainThread(u64 userdata, s64 cyclesLate)
|
static void SetTokenFinish_OnMainThread(u64 userdata, s64 cyclesLate)
|
||||||
|
@ -325,9 +371,9 @@ void SetFinish(int cycles_into_future)
|
||||||
RaiseEvent(cycles_into_future);
|
RaiseEvent(cycles_into_future);
|
||||||
}
|
}
|
||||||
|
|
||||||
UPEAlphaReadReg GetAlphaReadMode()
|
AlphaReadMode GetAlphaReadMode()
|
||||||
{
|
{
|
||||||
return m_AlphaRead;
|
return m_AlphaRead.read_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace PixelEngine
|
} // namespace PixelEngine
|
||||||
|
|
|
@ -4,7 +4,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
|
||||||
class PointerWrap;
|
class PointerWrap;
|
||||||
|
|
||||||
namespace MMIO
|
namespace MMIO
|
||||||
{
|
{
|
||||||
class Mapping;
|
class Mapping;
|
||||||
|
@ -45,14 +47,11 @@ enum
|
||||||
};
|
};
|
||||||
|
|
||||||
// ReadMode specifies the returned alpha channel for EFB peeks
|
// ReadMode specifies the returned alpha channel for EFB peeks
|
||||||
union UPEAlphaReadReg
|
enum class AlphaReadMode : u16
|
||||||
{
|
{
|
||||||
u16 Hex;
|
Read00 = 0, // Always read 0x00
|
||||||
struct
|
ReadFF = 1, // Always read 0xFF
|
||||||
{
|
ReadNone = 2, // Always read the real alpha value
|
||||||
u16 ReadMode : 2;
|
|
||||||
u16 : 14;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void Init();
|
void Init();
|
||||||
|
@ -63,6 +62,6 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
|
||||||
// gfx backend support
|
// gfx backend support
|
||||||
void SetToken(const u16 token, const bool interrupt, int cycle_delay);
|
void SetToken(const u16 token, const bool interrupt, int cycle_delay);
|
||||||
void SetFinish(int cycle_delay);
|
void SetFinish(int cycle_delay);
|
||||||
UPEAlphaReadReg GetAlphaReadMode();
|
AlphaReadMode GetAlphaReadMode();
|
||||||
|
|
||||||
} // namespace PixelEngine
|
} // namespace PixelEngine
|
||||||
|
|
|
@ -247,9 +247,6 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
|
||||||
// a little-endian value is expected to be returned
|
// a little-endian value is expected to be returned
|
||||||
color = ((color & 0xFF00FF00) | ((color >> 16) & 0xFF) | ((color << 16) & 0xFF0000));
|
color = ((color & 0xFF00FF00) | ((color >> 16) & 0xFF) | ((color << 16) & 0xFF0000));
|
||||||
|
|
||||||
// check what to do with the alpha channel (GX_PokeAlphaRead)
|
|
||||||
PixelEngine::UPEAlphaReadReg alpha_read_mode = PixelEngine::GetAlphaReadMode();
|
|
||||||
|
|
||||||
if (bpmem.zcontrol.pixel_format == PixelFormat::RGBA6_Z24)
|
if (bpmem.zcontrol.pixel_format == PixelFormat::RGBA6_Z24)
|
||||||
{
|
{
|
||||||
color = RGBA8ToRGBA6ToRGBA8(color);
|
color = RGBA8ToRGBA6ToRGBA8(color);
|
||||||
|
@ -263,17 +260,24 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
|
||||||
color |= 0xFF000000;
|
color |= 0xFF000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (alpha_read_mode.ReadMode == 2)
|
// check what to do with the alpha channel (GX_PokeAlphaRead)
|
||||||
|
PixelEngine::AlphaReadMode alpha_read_mode = PixelEngine::GetAlphaReadMode();
|
||||||
|
|
||||||
|
if (alpha_read_mode == PixelEngine::AlphaReadMode::ReadNone)
|
||||||
{
|
{
|
||||||
return color; // GX_READ_NONE
|
return color;
|
||||||
}
|
}
|
||||||
else if (alpha_read_mode.ReadMode == 1)
|
else if (alpha_read_mode == PixelEngine::AlphaReadMode::ReadFF)
|
||||||
{
|
{
|
||||||
return color | 0xFF000000; // GX_READ_FF
|
return color | 0xFF000000;
|
||||||
}
|
}
|
||||||
else /*if(alpha_read_mode.ReadMode == 0)*/
|
else
|
||||||
{
|
{
|
||||||
return color & 0x00FFFFFF; // GX_READ_00
|
if (alpha_read_mode != PixelEngine::AlphaReadMode::Read00)
|
||||||
|
{
|
||||||
|
PanicAlertFmt("Invalid PE alpha read mode: {}", static_cast<u16>(alpha_read_mode));
|
||||||
|
}
|
||||||
|
return color & 0x00FFFFFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // if (type == EFBAccessType::PeekZ)
|
else // if (type == EFBAccessType::PeekZ)
|
||||||
|
|
Loading…
Reference in New Issue