summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorPokechu22 <Pokechu022@gmail.com>2021-02-10 18:11:31 -0800
committerPokechu22 <Pokechu022@gmail.com>2021-03-06 19:27:19 -0800
commit70f9fc4e7526fc9cfc008a43cd33229f62be99b6 (patch)
tree48fae2cac1ed47ec5912dca4bf00716509192225 /Source/Core
parentdb8ced7e4e4724c38f148ee449c346e447dd3942 (diff)
Convert BPMemory to BitField and enum class
Additional changes: - For TevStageCombiner's ColorCombiner and AlphaCombiner, op/comparison and scale/compare_mode have been split as there are different meanings and enums if bias is set to compare. (Shift has also been renamed to scale) - In TexMode0, min_filter has been split into min_mip and min_filter. - In TexImage1, image_type is now cache_manually_managed. - The unused bit in GenMode is now exposed. - LPSize's lineaspect is now named adjust_for_aspect_ratio.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/VideoBackends/D3D/D3DState.cpp14
-rw-r--r--Source/Core/VideoBackends/D3D12/DX12Pipeline.cpp22
-rw-r--r--Source/Core/VideoBackends/OGL/OGLRender.cpp14
-rw-r--r--Source/Core/VideoBackends/Software/Clipper.cpp7
-rw-r--r--Source/Core/VideoBackends/Software/EfbInterface.cpp156
-rw-r--r--Source/Core/VideoBackends/Software/Rasterizer.cpp5
-rw-r--r--Source/Core/VideoBackends/Software/Tev.cpp329
-rw-r--r--Source/Core/VideoBackends/Software/Tev.h2
-rw-r--r--Source/Core/VideoBackends/Software/TextureEncoder.cpp28
-rw-r--r--Source/Core/VideoBackends/Software/TextureSampler.cpp28
-rw-r--r--Source/Core/VideoBackends/Vulkan/VKPipeline.cpp50
-rw-r--r--Source/Core/VideoBackends/Vulkan/VKRenderer.cpp6
-rw-r--r--Source/Core/VideoCommon/BPFunctions.cpp48
-rw-r--r--Source/Core/VideoCommon/BPMemory.cpp2
-rw-r--r--Source/Core/VideoCommon/BPMemory.h1215
-rw-r--r--Source/Core/VideoCommon/BPStructs.cpp148
-rw-r--r--Source/Core/VideoCommon/ConstantManager.h11
-rw-r--r--Source/Core/VideoCommon/PixelShaderGen.cpp310
-rw-r--r--Source/Core/VideoCommon/PixelShaderGen.h41
-rw-r--r--Source/Core/VideoCommon/PixelShaderManager.cpp16
-rw-r--r--Source/Core/VideoCommon/RenderBase.cpp20
-rw-r--r--Source/Core/VideoCommon/RenderBase.h6
-rw-r--r--Source/Core/VideoCommon/RenderState.cpp152
-rw-r--r--Source/Core/VideoCommon/RenderState.h14
-rw-r--r--Source/Core/VideoCommon/SamplerCommon.h4
-rw-r--r--Source/Core/VideoCommon/ShaderCache.cpp2
-rw-r--r--Source/Core/VideoCommon/TextureCacheBase.cpp8
-rw-r--r--Source/Core/VideoCommon/TextureCacheBase.h6
-rw-r--r--Source/Core/VideoCommon/TextureConversionShader.cpp6
-rw-r--r--Source/Core/VideoCommon/TextureConverterShaderGen.cpp2
-rw-r--r--Source/Core/VideoCommon/TextureDecoder.h27
-rw-r--r--Source/Core/VideoCommon/UberShaderPixel.cpp82
-rw-r--r--Source/Core/VideoCommon/VertexLoaderManager.cpp2
33 files changed, 1550 insertions, 1233 deletions
diff --git a/Source/Core/VideoBackends/D3D/D3DState.cpp b/Source/Core/VideoBackends/D3D/D3DState.cpp
index b345de0a38..b542c2b3de 100644
--- a/Source/Core/VideoBackends/D3D/D3DState.cpp
+++ b/Source/Core/VideoBackends/D3D/D3DState.cpp
@@ -378,7 +378,7 @@ ID3D11BlendState* StateCache::Get(BlendingState state)
D3D11_LOGIC_OP_COPY_INVERTED, D3D11_LOGIC_OP_OR_INVERTED, D3D11_LOGIC_OP_NAND,
D3D11_LOGIC_OP_SET}};
tdesc.LogicOpEnable = TRUE;
- tdesc.LogicOp = logic_ops[state.logicmode];
+ tdesc.LogicOp = logic_ops[u32(state.logicmode.Value())];
ComPtr<ID3D11BlendState1> res;
HRESULT hr = D3D::device1->CreateBlendState1(&desc, res.GetAddressOf());
@@ -416,10 +416,10 @@ ID3D11BlendState* StateCache::Get(BlendingState state)
use_dual_source ? D3D11_BLEND_INV_SRC1_ALPHA : D3D11_BLEND_INV_SRC_ALPHA,
D3D11_BLEND_DEST_ALPHA, D3D11_BLEND_INV_DEST_ALPHA}};
- tdesc.SrcBlend = src_factors[state.srcfactor];
- tdesc.SrcBlendAlpha = src_factors[state.srcfactoralpha];
- tdesc.DestBlend = dst_factors[state.dstfactor];
- tdesc.DestBlendAlpha = dst_factors[state.dstfactoralpha];
+ tdesc.SrcBlend = src_factors[u32(state.srcfactor.Value())];
+ tdesc.SrcBlendAlpha = src_factors[u32(state.srcfactoralpha.Value())];
+ tdesc.DestBlend = dst_factors[u32(state.dstfactor.Value())];
+ tdesc.DestBlendAlpha = dst_factors[u32(state.dstfactoralpha.Value())];
tdesc.BlendOp = state.subtract ? D3D11_BLEND_OP_REV_SUBTRACT : D3D11_BLEND_OP_ADD;
tdesc.BlendOpAlpha = state.subtractAlpha ? D3D11_BLEND_OP_REV_SUBTRACT : D3D11_BLEND_OP_ADD;
@@ -441,7 +441,7 @@ ID3D11RasterizerState* StateCache::Get(RasterizationState state)
D3D11_RASTERIZER_DESC desc = {};
desc.FillMode = D3D11_FILL_SOLID;
- desc.CullMode = cull_modes[state.cullmode];
+ desc.CullMode = cull_modes[u32(state.cullmode.Value())];
desc.ScissorEnable = TRUE;
ComPtr<ID3D11RasterizerState> res;
@@ -477,7 +477,7 @@ ID3D11DepthStencilState* StateCache::Get(DepthState state)
depthdc.DepthEnable = TRUE;
depthdc.DepthWriteMask =
state.updateenable ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
- depthdc.DepthFunc = d3dCmpFuncs[state.func];
+ depthdc.DepthFunc = d3dCmpFuncs[u32(state.func.Value())];
}
else
{
diff --git a/Source/Core/VideoBackends/D3D12/DX12Pipeline.cpp b/Source/Core/VideoBackends/D3D12/DX12Pipeline.cpp
index dfce47a2fb..4cd75c10e5 100644
--- a/Source/Core/VideoBackends/D3D12/DX12Pipeline.cpp
+++ b/Source/Core/VideoBackends/D3D12/DX12Pipeline.cpp
@@ -66,7 +66,7 @@ static void GetD3DRasterizerDesc(D3D12_RASTERIZER_DESC* desc, const Rasterizatio
{D3D12_CULL_MODE_NONE, D3D12_CULL_MODE_BACK, D3D12_CULL_MODE_FRONT, D3D12_CULL_MODE_FRONT}};
desc->FillMode = D3D12_FILL_MODE_SOLID;
- desc->CullMode = cull_modes[rs_state.cullmode];
+ desc->CullMode = cull_modes[u32(rs_state.cullmode.Value())];
desc->MultisampleEnable = fb_state.samples > 1;
}
@@ -80,7 +80,7 @@ static void GetD3DDepthDesc(D3D12_DEPTH_STENCIL_DESC* desc, const DepthState& st
D3D12_COMPARISON_FUNC_ALWAYS}};
desc->DepthEnable = state.testenable;
- desc->DepthFunc = compare_funcs[state.func];
+ desc->DepthFunc = compare_funcs[u32(state.func.Value())];
desc->DepthWriteMask =
state.updateenable ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO;
}
@@ -135,24 +135,24 @@ static void GetD3DBlendDesc(D3D12_BLEND_DESC* desc, const BlendingState& state)
rtblend->BlendOpAlpha = state.subtractAlpha ? D3D12_BLEND_OP_REV_SUBTRACT : D3D12_BLEND_OP_ADD;
if (state.usedualsrc)
{
- rtblend->SrcBlend = src_dual_src_factors[state.srcfactor];
- rtblend->SrcBlendAlpha = src_dual_src_factors[state.srcfactoralpha];
- rtblend->DestBlend = dst_dual_src_factors[state.dstfactor];
- rtblend->DestBlendAlpha = dst_dual_src_factors[state.dstfactoralpha];
+ rtblend->SrcBlend = src_dual_src_factors[u32(state.srcfactor.Value())];
+ rtblend->SrcBlendAlpha = src_dual_src_factors[u32(state.srcfactoralpha.Value())];
+ rtblend->DestBlend = dst_dual_src_factors[u32(state.dstfactor.Value())];
+ rtblend->DestBlendAlpha = dst_dual_src_factors[u32(state.dstfactoralpha.Value())];
}
else
{
- rtblend->SrcBlend = src_factors[state.srcfactor];
- rtblend->SrcBlendAlpha = src_factors[state.srcfactoralpha];
- rtblend->DestBlend = dst_factors[state.dstfactor];
- rtblend->DestBlendAlpha = dst_factors[state.dstfactoralpha];
+ rtblend->SrcBlend = src_factors[u32(state.srcfactor.Value())];
+ rtblend->SrcBlendAlpha = src_factors[u32(state.srcfactoralpha.Value())];
+ rtblend->DestBlend = dst_factors[u32(state.dstfactor.Value())];
+ rtblend->DestBlendAlpha = dst_factors[u32(state.dstfactoralpha.Value())];
}
}
else
{
rtblend->LogicOpEnable = state.logicopenable;
if (state.logicopenable)
- rtblend->LogicOp = logic_ops[state.logicmode];
+ rtblend->LogicOp = logic_ops[u32(state.logicmode.Value())];
}
}
diff --git a/Source/Core/VideoBackends/OGL/OGLRender.cpp b/Source/Core/VideoBackends/OGL/OGLRender.cpp
index 6b99327fee..3bcf38c2ae 100644
--- a/Source/Core/VideoBackends/OGL/OGLRender.cpp
+++ b/Source/Core/VideoBackends/OGL/OGLRender.cpp
@@ -1140,11 +1140,11 @@ void Renderer::ApplyRasterizationState(const RasterizationState state)
return;
// none, ccw, cw, ccw
- if (state.cullmode != GenMode::CULL_NONE)
+ if (state.cullmode != CullMode::None)
{
// TODO: GX_CULL_ALL not supported, yet!
glEnable(GL_CULL_FACE);
- glFrontFace(state.cullmode == GenMode::CULL_FRONT ? GL_CCW : GL_CW);
+ glFrontFace(state.cullmode == CullMode::Front ? GL_CCW : GL_CW);
}
else
{
@@ -1166,7 +1166,7 @@ void Renderer::ApplyDepthState(const DepthState state)
{
glEnable(GL_DEPTH_TEST);
glDepthMask(state.updateenable ? GL_TRUE : GL_FALSE);
- glDepthFunc(glCmpFuncs[state.func]);
+ glDepthFunc(glCmpFuncs[u32(state.func.Value())]);
}
else
{
@@ -1229,8 +1229,10 @@ void Renderer::ApplyBlendingState(const BlendingState state)
GLenum equation = state.subtract ? GL_FUNC_REVERSE_SUBTRACT : GL_FUNC_ADD;
GLenum equationAlpha = state.subtractAlpha ? GL_FUNC_REVERSE_SUBTRACT : GL_FUNC_ADD;
glBlendEquationSeparate(equation, equationAlpha);
- glBlendFuncSeparate(src_factors[state.srcfactor], dst_factors[state.dstfactor],
- src_factors[state.srcfactoralpha], dst_factors[state.dstfactoralpha]);
+ glBlendFuncSeparate(src_factors[u32(state.srcfactor.Value())],
+ dst_factors[u32(state.dstfactor.Value())],
+ src_factors[u32(state.srcfactoralpha.Value())],
+ dst_factors[u32(state.dstfactoralpha.Value())]);
}
const GLenum logic_op_codes[16] = {
@@ -1244,7 +1246,7 @@ void Renderer::ApplyBlendingState(const BlendingState state)
if (state.logicopenable)
{
glEnable(GL_COLOR_LOGIC_OP);
- glLogicOp(logic_op_codes[state.logicmode]);
+ glLogicOp(logic_op_codes[u32(state.logicmode.Value())]);
}
else
{
diff --git a/Source/Core/VideoBackends/Software/Clipper.cpp b/Source/Core/VideoBackends/Software/Clipper.cpp
index 4c4e0db52d..417bc63fa3 100644
--- a/Source/Core/VideoBackends/Software/Clipper.cpp
+++ b/Source/Core/VideoBackends/Software/Clipper.cpp
@@ -489,13 +489,16 @@ bool CullTest(const OutputVertexData* v0, const OutputVertexData* v1, const Outp
backface = normalZDir <= 0.0f;
- if ((bpmem.genMode.cullmode & 1) && !backface) // cull frontfacing
+ // TODO: Are these tests / the definition of backface above backwards?
+ if ((bpmem.genMode.cullmode == CullMode::Back || bpmem.genMode.cullmode == CullMode::All) &&
+ !backface) // cull frontfacing
{
INCSTAT(g_stats.this_frame.num_triangles_culled)
return false;
}
- if ((bpmem.genMode.cullmode & 2) && backface) // cull backfacing
+ if ((bpmem.genMode.cullmode == CullMode::Front || bpmem.genMode.cullmode == CullMode::All) &&
+ backface) // cull backfacing
{
INCSTAT(g_stats.this_frame.num_triangles_culled)
return false;
diff --git a/Source/Core/VideoBackends/Software/EfbInterface.cpp b/Source/Core/VideoBackends/Software/EfbInterface.cpp
index 0bd2f0343d..8ef62d5b03 100644
--- a/Source/Core/VideoBackends/Software/EfbInterface.cpp
+++ b/Source/Core/VideoBackends/Software/EfbInterface.cpp
@@ -41,12 +41,12 @@ static void SetPixelAlphaOnly(u32 offset, u8 a)
{
switch (bpmem.zcontrol.pixel_format)
{
- case PEControl::RGB8_Z24:
- case PEControl::Z24:
- case PEControl::RGB565_Z16:
+ case PixelFormat::RGB8_Z24:
+ case PixelFormat::Z24:
+ case PixelFormat::RGB565_Z16:
// do nothing
break;
- case PEControl::RGBA6_Z24:
+ case PixelFormat::RGBA6_Z24:
{
u32 a32 = a;
u32* dst = (u32*)&efb[offset];
@@ -56,8 +56,7 @@ static void SetPixelAlphaOnly(u32 offset, u8 a)
}
break;
default:
- ERROR_LOG_FMT(VIDEO, "Unsupported pixel format: {}",
- static_cast<int>(bpmem.zcontrol.pixel_format));
+ ERROR_LOG_FMT(VIDEO, "Unsupported pixel format: {}", bpmem.zcontrol.pixel_format);
break;
}
}
@@ -66,8 +65,8 @@ static void SetPixelColorOnly(u32 offset, u8* rgb)
{
switch (bpmem.zcontrol.pixel_format)
{
- case PEControl::RGB8_Z24:
- case PEControl::Z24:
+ case PixelFormat::RGB8_Z24:
+ case PixelFormat::Z24:
{
u32 src = *(u32*)rgb;
u32* dst = (u32*)&efb[offset];
@@ -76,7 +75,7 @@ static void SetPixelColorOnly(u32 offset, u8* rgb)
*dst = val;
}
break;
- case PEControl::RGBA6_Z24:
+ case PixelFormat::RGBA6_Z24:
{
u32 src = *(u32*)rgb;
u32* dst = (u32*)&efb[offset];
@@ -87,7 +86,7 @@ static void SetPixelColorOnly(u32 offset, u8* rgb)
*dst = val;
}
break;
- case PEControl::RGB565_Z16:
+ case PixelFormat::RGB565_Z16:
{
INFO_LOG_FMT(VIDEO, "RGB565_Z16 is not supported correctly yet");
u32 src = *(u32*)rgb;
@@ -98,8 +97,7 @@ static void SetPixelColorOnly(u32 offset, u8* rgb)
}
break;
default:
- ERROR_LOG_FMT(VIDEO, "Unsupported pixel format: {}",
- static_cast<int>(bpmem.zcontrol.pixel_format));
+ ERROR_LOG_FMT(VIDEO, "Unsupported pixel format: {}", bpmem.zcontrol.pixel_format);
break;
}
}
@@ -108,8 +106,8 @@ static void SetPixelAlphaColor(u32 offset, u8* color)
{
switch (bpmem.zcontrol.pixel_format)
{
- case PEControl::RGB8_Z24:
- case PEControl::Z24:
+ case PixelFormat::RGB8_Z24:
+ case PixelFormat::Z24:
{
u32 src = *(u32*)color;
u32* dst = (u32*)&efb[offset];
@@ -118,7 +116,7 @@ static void SetPixelAlphaColor(u32 offset, u8* color)
*dst = val;
}
break;
- case PEControl::RGBA6_Z24:
+ case PixelFormat::RGBA6_Z24:
{
u32 src = *(u32*)color;
u32* dst = (u32*)&efb[offset];
@@ -130,7 +128,7 @@ static void SetPixelAlphaColor(u32 offset, u8* color)
*dst = val;
}
break;
- case PEControl::RGB565_Z16:
+ case PixelFormat::RGB565_Z16:
{
INFO_LOG_FMT(VIDEO, "RGB565_Z16 is not supported correctly yet");
u32 src = *(u32*)color;
@@ -141,8 +139,7 @@ static void SetPixelAlphaColor(u32 offset, u8* color)
}
break;
default:
- ERROR_LOG_FMT(VIDEO, "Unsupported pixel format: {}",
- static_cast<int>(bpmem.zcontrol.pixel_format));
+ ERROR_LOG_FMT(VIDEO, "Unsupported pixel format: {}", bpmem.zcontrol.pixel_format);
break;
}
}
@@ -154,23 +151,22 @@ static u32 GetPixelColor(u32 offset)
switch (bpmem.zcontrol.pixel_format)
{
- case PEControl::RGB8_Z24:
- case PEControl::Z24:
+ case PixelFormat::RGB8_Z24:
+ case PixelFormat::Z24:
return 0xff | ((src & 0x00ffffff) << 8);
- case PEControl::RGBA6_Z24:
+ case PixelFormat::RGBA6_Z24:
return Convert6To8(src & 0x3f) | // Alpha
Convert6To8((src >> 6) & 0x3f) << 8 | // Blue
Convert6To8((src >> 12) & 0x3f) << 16 | // Green
Convert6To8((src >> 18) & 0x3f) << 24; // Red
- case PEControl::RGB565_Z16:
+ case PixelFormat::RGB565_Z16:
INFO_LOG_FMT(VIDEO, "RGB565_Z16 is not supported correctly yet");
return 0xff | ((src & 0x00ffffff) << 8);
default:
- ERROR_LOG_FMT(VIDEO, "Unsupported pixel format: {}",
- static_cast<int>(bpmem.zcontrol.pixel_format));
+ ERROR_LOG_FMT(VIDEO, "Unsupported pixel format: {}", bpmem.zcontrol.pixel_format);
return 0;
}
}
@@ -179,9 +175,9 @@ static void SetPixelDepth(u32 offset, u32 depth)
{
switch (bpmem.zcontrol.pixel_format)
{
- case PEControl::RGB8_Z24:
- case PEControl::RGBA6_Z24:
- case PEControl::Z24:
+ case PixelFormat::RGB8_Z24:
+ case PixelFormat::RGBA6_Z24:
+ case PixelFormat::Z24:
{
u32* dst = (u32*)&efb[offset];
u32 val = *dst & 0xff000000;
@@ -189,7 +185,7 @@ static void SetPixelDepth(u32 offset, u32 depth)
*dst = val;
}
break;
- case PEControl::RGB565_Z16:
+ case PixelFormat::RGB565_Z16:
{
INFO_LOG_FMT(VIDEO, "RGB565_Z16 is not supported correctly yet");
u32* dst = (u32*)&efb[offset];
@@ -199,8 +195,7 @@ static void SetPixelDepth(u32 offset, u32 depth)
}
break;
default:
- ERROR_LOG_FMT(VIDEO, "Unsupported pixel format: {}",
- static_cast<int>(bpmem.zcontrol.pixel_format));
+ ERROR_LOG_FMT(VIDEO, "Unsupported pixel format: {}", bpmem.zcontrol.pixel_format);
break;
}
}
@@ -211,59 +206,58 @@ static u32 GetPixelDepth(u32 offset)
switch (bpmem.zcontrol.pixel_format)
{
- case PEControl::RGB8_Z24:
- case PEControl::RGBA6_Z24:
- case PEControl::Z24:
+ case PixelFormat::RGB8_Z24:
+ case PixelFormat::RGBA6_Z24:
+ case PixelFormat::Z24:
{
depth = (*(u32*)&efb[offset]) & 0x00ffffff;
}
break;
- case PEControl::RGB565_Z16:
+ case PixelFormat::RGB565_Z16:
{
INFO_LOG_FMT(VIDEO, "RGB565_Z16 is not supported correctly yet");
depth = (*(u32*)&efb[offset]) & 0x00ffffff;
}
break;
default:
- ERROR_LOG_FMT(VIDEO, "Unsupported pixel format: {}",
- static_cast<int>(bpmem.zcontrol.pixel_format));
+ ERROR_LOG_FMT(VIDEO, "Unsupported pixel format: {}", bpmem.zcontrol.pixel_format);
break;
}
return depth;
}
-static u32 GetSourceFactor(u8* srcClr, u8* dstClr, BlendMode::BlendFactor mode)
+static u32 GetSourceFactor(u8* srcClr, u8* dstClr, SrcBlendFactor mode)
{
switch (mode)
{
- case BlendMode::ZERO:
+ case SrcBlendFactor::Zero:
return 0;
- case BlendMode::ONE:
+ case SrcBlendFactor::One:
return 0xffffffff;
- case BlendMode::DSTCLR:
+ case SrcBlendFactor::DstClr:
return *(u32*)dstClr;
- case BlendMode::INVDSTCLR:
+ case SrcBlendFactor::InvDstClr:
return 0xffffffff - *(u32*)dstClr;
- case BlendMode::SRCALPHA:
+ case SrcBlendFactor::SrcAlpha:
{
u8 alpha = srcClr[ALP_C];
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
return factor;
}
- case BlendMode::INVSRCALPHA:
+ case SrcBlendFactor::InvSrcAlpha:
{
u8 alpha = 0xff - srcClr[ALP_C];
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
return factor;
}
- case BlendMode::DSTALPHA:
+ case SrcBlendFactor::DstAlpha:
{
u8 alpha = dstClr[ALP_C];
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
return factor;
}
- case BlendMode::INVDSTALPHA:
+ case SrcBlendFactor::InvDstAlpha:
{
u8 alpha = 0xff - dstClr[ALP_C];
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
@@ -274,37 +268,37 @@ static u32 GetSourceFactor(u8* srcClr, u8* dstClr, BlendMode::BlendFactor mode)
return 0;
}
-static u32 GetDestinationFactor(u8* srcClr, u8* dstClr, BlendMode::BlendFactor mode)
+static u32 GetDestinationFactor(u8* srcClr, u8* dstClr, DstBlendFactor mode)
{
switch (mode)
{
- case BlendMode::ZERO:
+ case DstBlendFactor::Zero:
return 0;
- case BlendMode::ONE:
+ case DstBlendFactor::One:
return 0xffffffff;
- case BlendMode::SRCCLR:
+ case DstBlendFactor::SrcClr:
return *(u32*)srcClr;
- case BlendMode::INVSRCCLR:
+ case DstBlendFactor::InvSrcClr:
return 0xffffffff - *(u32*)srcClr;
- case BlendMode::SRCALPHA:
+ case DstBlendFactor::SrcAlpha:
{
u8 alpha = srcClr[ALP_C];
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
return factor;
}
- case BlendMode::INVSRCALPHA:
+ case DstBlendFactor::InvSrcAlpha:
{
u8 alpha = 0xff - srcClr[ALP_C];
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
return factor;
}
- case BlendMode::DSTALPHA:
+ case DstBlendFactor::DstAlpha:
{
u8 alpha = dstClr[ALP_C] & 0xff;
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
return factor;
}
- case BlendMode::INVDSTALPHA:
+ case DstBlendFactor::InvDstAlpha:
{
u8 alpha = 0xff - dstClr[ALP_C];
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
@@ -337,56 +331,56 @@ static void BlendColor(u8* srcClr, u8* dstClr)
}
}
-static void LogicBlend(u32 srcClr, u32* dstClr, BlendMode::LogicOp op)
+static void LogicBlend(u32 srcClr, u32* dstClr, LogicOp op)
{
switch (op)
{
- case BlendMode::CLEAR:
+ case LogicOp::Clear:
*dstClr = 0;
break;
- case BlendMode::AND:
+ case LogicOp::And:
*dstClr = srcClr & *dstClr;
break;
- case BlendMode::AND_REVERSE:
+ case LogicOp::AndReverse:
*dstClr = srcClr & (~*dstClr);
break;
- case BlendMode::COPY:
+ case LogicOp::Copy:
*dstClr = srcClr;
break;
- case BlendMode::AND_INVERTED:
+ case LogicOp::AndInverted:
*dstClr = (~srcClr) & *dstClr;
break;
- case BlendMode::NOOP:
+ case LogicOp::NoOp:
// Do nothing
break;
- case BlendMode::XOR:
+ case LogicOp::Xor:
*dstClr = srcClr ^ *dstClr;
break;
- case BlendMode::OR:
+ case LogicOp::Or:
*dstClr = srcClr | *dstClr;
break;
- case BlendMode::NOR:
+ case LogicOp::Nor:
*dstClr = ~(srcClr | *dstClr);
break;
- case BlendMode::EQUIV:
+ case LogicOp::Equiv:
*dstClr = ~(srcClr ^ *dstClr);
break;
- case BlendMode::INVERT:
+ case LogicOp::Invert:
*dstClr = ~*dstClr;
break;
- case BlendMode::OR_REVERSE:
+ case LogicOp::OrReverse:
*dstClr = srcClr | (~*dstClr);
break;
- case BlendMode::COPY_INVERTED:
+ case LogicOp::CopyInverted:
*dstClr = ~srcClr;
break;
- case BlendMode::OR_INVERTED:
+ case LogicOp::OrInverted:
*dstClr = (~srcClr) | *dstClr;
break;
- case BlendMode::NAND:
+ case LogicOp::Nand:
*dstClr = ~(srcClr & *dstClr);
break;
- case BlendMode::SET:
+ case LogicOp::Set:
*dstClr = 0xffffffff;
break;
}
@@ -404,7 +398,7 @@ static void SubtractBlend(u8* srcClr, u8* dstClr)
static void Dither(u16 x, u16 y, u8* color)
{
// No blending for RGB8 mode
- if (!bpmem.blendmode.dither || bpmem.zcontrol.pixel_format != PEControl::PixelFormat::RGBA6_Z24)
+ if (!bpmem.blendmode.dither || bpmem.zcontrol.pixel_format != PixelFormat::RGBA6_Z24)
return;
// Flipper uses a standard 2x2 Bayer Matrix for 6 bit dithering
@@ -662,33 +656,33 @@ bool ZCompare(u16 x, u16 y, u32 z)
switch (bpmem.zmode.func)
{
- case ZMode::NEVER:
+ case CompareMode::Never:
pass = false;
break;
- case ZMode::LESS:
+ case CompareMode::Less:
pass = z < depth;
break;
- case ZMode::EQUAL:
+ case CompareMode::Equal:
pass = z == depth;
break;
- case ZMode::LEQUAL:
+ case CompareMode::LEqual:
pass = z <= depth;
break;
- case ZMode::GREATER:
+ case CompareMode::Greater:
pass = z > depth;
break;
- case ZMode::NEQUAL:
+ case CompareMode::NEqual:
pass = z != depth;
break;
- case ZMode::GEQUAL:
+ case CompareMode::GEqual:
pass = z >= depth;
break;
- case ZMode::ALWAYS:
+ case CompareMode::Always:
pass = true;
break;
default:
pass = false;
- ERROR_LOG_FMT(VIDEO, "Bad Z compare mode {}", static_cast<int>(bpmem.zmode.func));
+ ERROR_LOG_FMT(VIDEO, "Bad Z compare mode {}", bpmem.zmode.func);
break;
}
diff --git a/Source/Core/VideoBackends/Software/Rasterizer.cpp b/Source/Core/VideoBackends/Software/Rasterizer.cpp
index 394bfea41e..e987817c8c 100644
--- a/Source/Core/VideoBackends/Software/Rasterizer.cpp
+++ b/Source/Core/VideoBackends/Software/Rasterizer.cpp
@@ -173,7 +173,7 @@ static inline void CalculateLOD(s32* lodp, bool* linear, u32 texmap, u32 texcoor
const TexMode1& tm1 = texUnit.texMode1[subTexmap];
float sDelta, tDelta;
- if (tm0.diag_lod)
+ if (tm0.diag_lod == LODType::Diagonal)
{
float* uv0 = rasterBlock.Pixel[0][0].Uv[texcoord];
float* uv1 = rasterBlock.Pixel[1][1].Uv[texcoord];
@@ -199,7 +199,8 @@ static inline void CalculateLOD(s32* lodp, bool* linear, u32 texmap, u32 texcoor
bias >>= 1;
lod += bias;
- *linear = ((lod > 0 && (tm0.min_filter & 4)) || (lod <= 0 && tm0.mag_filter));
+ *linear = ((lod > 0 && tm0.min_filter == FilterMode::Linear) ||
+ (lod <= 0 && tm0.mag_filter == FilterMode::Linear));
// NOTE: The order of comparisons for this clamp check matters.
if (lod > static_cast<s32>(tm1.max_lod))
diff --git a/Source/Core/VideoBackends/Software/Tev.cpp b/Source/Core/VideoBackends/Software/Tev.cpp
index fed65d2bec..65227339e4 100644
--- a/Source/Core/VideoBackends/Software/Tev.cpp
+++ b/Source/Core/VideoBackends/Software/Tev.cpp
@@ -172,11 +172,11 @@ static inline s16 Clamp1024(s16 in)
return in > 1023 ? 1023 : (in < -1024 ? -1024 : in);
}
-void Tev::SetRasColor(int colorChan, int swaptable)
+void Tev::SetRasColor(RasColorChan colorChan, int swaptable)
{
switch (colorChan)
{
- case 0: // Color0
+ case RasColorChan::Color0:
{
const u8* color = Color[0];
RasColor[RED_C] = color[bpmem.tevksel[swaptable].swap1];
@@ -186,7 +186,7 @@ void Tev::SetRasColor(int colorChan, int swaptable)
RasColor[ALP_C] = color[bpmem.tevksel[swaptable].swap2];
}
break;
- case 1: // Color1
+ case RasColorChan::Color1:
{
const u8* color = Color[1];
RasColor[RED_C] = color[bpmem.tevksel[swaptable].swap1];
@@ -196,7 +196,7 @@ void Tev::SetRasColor(int colorChan, int swaptable)
RasColor[ALP_C] = color[bpmem.tevksel[swaptable].swap2];
}
break;
- case 5: // alpha bump
+ case RasColorChan::AlphaBump:
{
for (s16& comp : RasColor)
{
@@ -204,7 +204,7 @@ void Tev::SetRasColor(int colorChan, int swaptable)
}
}
break;
- case 6: // alpha bump normalized
+ case RasColorChan::NormalizedAlphaBump:
{
const u8 normalized = AlphaBump | AlphaBump >> 5;
for (s16& comp : RasColor)
@@ -213,8 +213,11 @@ void Tev::SetRasColor(int colorChan, int swaptable)
}
}
break;
- default: // zero
+ default:
{
+ if (colorChan != RasColorChan::Zero)
+ PanicAlertFmt("Invalid ras color channel: {}", colorChan);
+
for (s16& comp : RasColor)
{
comp = 0;
@@ -226,22 +229,24 @@ void Tev::SetRasColor(int colorChan, int swaptable)
void Tev::DrawColorRegular(const TevStageCombiner::ColorCombiner& cc, const InputRegType inputs[4])
{
- for (int i = 0; i < 3; i++)
+ for (int i = BLU_C; i <= RED_C; i++)
{
- const InputRegType& InputReg = inputs[BLU_C + i];
+ const InputRegType& InputReg = inputs[i];
const u16 c = InputReg.c + (InputReg.c >> 7);
s32 temp = InputReg.a * (256 - c) + (InputReg.b * c);
- temp <<= m_ScaleLShiftLUT[cc.shift];
- temp += (cc.shift == 3) ? 0 : (cc.op == 1) ? 127 : 128;
+ temp <<= m_ScaleLShiftLUT[u32(cc.scale.Value())];
+ temp += (cc.scale == TevScale::Divide2) ? 0 : (cc.op == TevOp::Sub) ? 127 : 128;
temp >>= 8;
- temp = cc.op ? -temp : temp;
+ temp = cc.op == TevOp::Sub ? -temp : temp;
- s32 result = ((InputReg.d + m_BiasLUT[cc.bias]) << m_ScaleLShiftLUT[cc.shift]) + temp;
- result = result >> m_ScaleRShiftLUT[cc.shift];
+ s32 result = ((InputReg.d + m_BiasLUT[u32(cc.bias.Value())])
+ << m_ScaleLShiftLUT[u32(cc.scale.Value())]) +
+ temp;
+ result = result >> m_ScaleRShiftLUT[u32(cc.scale.Value())];
- Reg[cc.dest][BLU_C + i] = result;
+ Reg[u32(cc.dest.Value())][i] = result;
}
}
@@ -249,56 +254,38 @@ void Tev::DrawColorCompare(const TevStageCombiner::ColorCombiner& cc, const Inpu
{
for (int i = BLU_C; i <= RED_C; i++)
{
- switch ((cc.shift << 1) | cc.op | 8) // encoded compare mode
+ u32 a, b;
+ switch (cc.compare_mode)
{
- case TEVCMP_R8_GT:
- Reg[cc.dest][i] = inputs[i].d + ((inputs[RED_C].a > inputs[RED_C].b) ? inputs[i].c : 0);
+ case TevCompareMode::R8:
+ a = inputs[RED_C].a;
+ b = inputs[RED_C].b;
break;
- case TEVCMP_R8_EQ:
- Reg[cc.dest][i] = inputs[i].d + ((inputs[RED_C].a == inputs[RED_C].b) ? inputs[i].c : 0);
+ case TevCompareMode::GR16:
+ a = (inputs[GRN_C].a << 8) | inputs[RED_C].a;
+ b = (inputs[GRN_C].b << 8) | inputs[RED_C].b;
break;
- case TEVCMP_GR16_GT:
- {
- const u32 a = (inputs[GRN_C].a << 8) | inputs[RED_C].a;
- const u32 b = (inputs[GRN_C].b << 8) | inputs[RED_C].b;
- Reg[cc.dest][i] = inputs[i].d + ((a > b) ? inputs[i].c : 0);
- }
- break;
-
- case TEVCMP_GR16_EQ:
- {
- const u32 a = (inputs[GRN_C].a << 8) | inputs[RED_C].a;
- const u32 b = (inputs[GRN_C].b << 8) | inputs[RED_C].b;
- Reg[cc.dest][i] = inputs[i].d + ((a == b) ? inputs[i].c : 0);
- }
- break;
-
- case TEVCMP_BGR24_GT:
- {
- const u32 a = (inputs[BLU_C].a << 16) | (inputs[GRN_C].a << 8) | inputs[RED_C].a;
- const u32 b = (inputs[BLU_C].b << 16) | (inputs[GRN_C].b << 8) | inputs[RED_C].b;
- Reg[cc.dest][i] = inputs[i].d + ((a > b) ? inputs[i].c : 0);
- }
- break;
-
- case TEVCMP_BGR24_EQ:
- {
- const u32 a = (inputs[BLU_C].a << 16) | (inputs[GRN_C].a << 8) | inputs[RED_C].a;
- const u32 b = (inputs[BLU_C].b << 16) | (inputs[GRN_C].b << 8) | inputs[RED_C].b;
- Reg[cc.dest][i] = inputs[i].d + ((a == b) ? inputs[i].c : 0);
- }
- break;
-
- case TEVCMP_RGB8_GT:
- Reg[cc.dest][i] = inputs[i].d + ((inputs[i].a > inputs[i].b) ? inputs[i].c : 0);
+ case TevCompareMode::BGR24:
+ a = (inputs[BLU_C].a << 16) | (inputs[GRN_C].a << 8) | inputs[RED_C].a;
+ b = (inputs[BLU_C].b << 16) | (inputs[GRN_C].b << 8) | inputs[RED_C].b;
break;
- case TEVCMP_RGB8_EQ:
- Reg[cc.dest][i] = inputs[i].d + ((inputs[i].a == inputs[i].b) ? inputs[i].c : 0);
+ case TevCompareMode::RGB8:
+ a = inputs[i].a;
+ b = inputs[i].b;
break;
+
+ default:
+ PanicAlertFmt("Invalid compare mode {}", cc.compare_mode);
+ continue;
}
+
+ if (cc.comparison == TevComparison::GT)
+ Reg[u32(cc.dest.Value())][i] = inputs[i].d + ((a > b) ? inputs[i].c : 0);
+ else
+ Reg[u32(cc.dest.Value())][i] = inputs[i].d + ((a == b) ? inputs[i].c : 0);
}
}
@@ -309,95 +296,76 @@ void Tev::DrawAlphaRegular(const TevStageCombiner::AlphaCombiner& ac, const Inpu
const u16 c = InputReg.c + (InputReg.c >> 7);
s32 temp = InputReg.a * (256 - c) + (InputReg.b * c);
- temp <<= m_ScaleLShiftLUT[ac.shift];
- temp += (ac.shift != 3) ? 0 : (ac.op == 1) ? 127 : 128;
- temp = ac.op ? (-temp >> 8) : (temp >> 8);
+ temp <<= m_ScaleLShiftLUT[u32(ac.scale.Value())];
+ temp += (ac.scale != TevScale::Divide2) ? 0 : (ac.op == TevOp::Sub) ? 127 : 128;
+ temp = ac.op == TevOp::Sub ? (-temp >> 8) : (temp >> 8);
- s32 result = ((InputReg.d + m_BiasLUT[ac.bias]) << m_ScaleLShiftLUT[ac.shift]) + temp;
- result = result >> m_ScaleRShiftLUT[ac.shift];
+ s32 result =
+ ((InputReg.d + m_BiasLUT[u32(ac.bias.Value())]) << m_ScaleLShiftLUT[u32(ac.scale.Value())]) +
+ temp;
+ result = result >> m_ScaleRShiftLUT[u32(ac.scale.Value())];
- Reg[ac.dest][ALP_C] = result;
+ Reg[u32(ac.dest.Value())][ALP_C] = result;
}
void Tev::DrawAlphaCompare(const TevStageCombiner::AlphaCombiner& ac, const InputRegType inputs[4])
{
- switch ((ac.shift << 1) | ac.op | 8) // encoded compare mode
+ u32 a, b;
+ switch (ac.compare_mode)
{
- case TEVCMP_R8_GT:
- Reg[ac.dest][ALP_C] =
- inputs[ALP_C].d + ((inputs[RED_C].a > inputs[RED_C].b) ? inputs[ALP_C].c : 0);
+ case TevCompareMode::R8:
+ a = inputs[RED_C].a;
+ b = inputs[RED_C].b;
break;
- case TEVCMP_R8_EQ:
- Reg[ac.dest][ALP_C] =
- inputs[ALP_C].d + ((inputs[RED_C].a == inputs[RED_C].b) ? inputs[ALP_C].c : 0);
+ case TevCompareMode::GR16:
+ a = (inputs[GRN_C].a << 8) | inputs[RED_C].a;
+ b = (inputs[GRN_C].b << 8) | inputs[RED_C].b;
break;
- case TEVCMP_GR16_GT:
- {
- const u32 a = (inputs[GRN_C].a << 8) | inputs[RED_C].a;
- const u32 b = (inputs[GRN_C].b << 8) | inputs[RED_C].b;
- Reg[ac.dest][ALP_C] = inputs[ALP_C].d + ((a > b) ? inputs[ALP_C].c : 0);
- }
- break;
-
- case TEVCMP_GR16_EQ:
- {
- const u32 a = (inputs[GRN_C].a << 8) | inputs[RED_C].a;
- const u32 b = (inputs[GRN_C].b << 8) | inputs[RED_C].b;
- Reg[ac.dest][ALP_C] = inputs[ALP_C].d + ((a == b) ? inputs[ALP_C].c : 0);
- }
- break;
-
- case TEVCMP_BGR24_GT:
- {
- const u32 a = (inputs[BLU_C].a << 16) | (inputs[GRN_C].a << 8) | inputs[RED_C].a;
- const u32 b = (inputs[BLU_C].b << 16) | (inputs[GRN_C].b << 8) | inputs[RED_C].b;
- Reg[ac.dest][ALP_C] = inputs[ALP_C].d + ((a > b) ? inputs[ALP_C].c : 0);
- }
- break;
-
- case TEVCMP_BGR24_EQ:
- {
- const u32 a = (inputs[BLU_C].a << 16) | (inputs[GRN_C].a << 8) | inputs[RED_C].a;
- const u32 b = (inputs[BLU_C].b << 16) | (inputs[GRN_C].b << 8) | inputs[RED_C].b;
- Reg[ac.dest][ALP_C] = inputs[ALP_C].d + ((a == b) ? inputs[ALP_C].c : 0);
- }
- break;
-
- case TEVCMP_A8_GT:
- Reg[ac.dest][ALP_C] =
- inputs[ALP_C].d + ((inputs[ALP_C].a > inputs[ALP_C].b) ? inputs[ALP_C].c : 0);
+ case TevCompareMode::BGR24:
+ a = (inputs[BLU_C].a << 16) | (inputs[GRN_C].a << 8) | inputs[RED_C].a;
+ b = (inputs[BLU_C].b << 16) | (inputs[GRN_C].b << 8) | inputs[RED_C].b;
break;
- case TEVCMP_A8_EQ:
- Reg[ac.dest][ALP_C] =
- inputs[ALP_C].d + ((inputs[ALP_C].a == inputs[ALP_C].b) ? inputs[ALP_C].c : 0);
+ case TevCompareMode::A8:
+ a = inputs[ALP_C].a;
+ b = inputs[ALP_C].b;
break;
+
+ default:
+ PanicAlertFmt("Invalid compare mode {}", ac.compare_mode);
+ return;
}
+
+ if (ac.comparison == TevComparison::GT)
+ Reg[u32(ac.dest.Value())][ALP_C] = inputs[ALP_C].d + ((a > b) ? inputs[ALP_C].c : 0);
+ else
+ Reg[u32(ac.dest.Value())][ALP_C] = inputs[ALP_C].d + ((a == b) ? inputs[ALP_C].c : 0);
}
-static bool AlphaCompare(int alpha, int ref, AlphaTest::CompareMode comp)
+static bool AlphaCompare(int alpha, int ref, CompareMode comp)
{
switch (comp)
{
- case AlphaTest::ALWAYS:
+ case CompareMode::Always:
return true;
- case AlphaTest::NEVER:
+ case CompareMode::Never:
return false;
- case AlphaTest::LEQUAL:
+ case CompareMode::LEqual:
return alpha <= ref;
- case AlphaTest::LESS:
+ case CompareMode::Less:
return alpha < ref;
- case AlphaTest::GEQUAL:
+ case CompareMode::GEqual:
return alpha >= ref;
- case AlphaTest::GREATER:
+ case CompareMode::Greater:
return alpha > ref;
- case AlphaTest::EQUAL:
+ case CompareMode::Equal:
return alpha == ref;
- case AlphaTest::NEQUAL:
+ case CompareMode::NEqual:
return alpha != ref;
default:
+ PanicAlertFmt("Invalid compare mode {}", comp);
return true;
}
}
@@ -409,38 +377,40 @@ static bool TevAlphaTest(int alpha)
switch (bpmem.alpha_test.logic)
{
- case 0:
- return comp0 && comp1; // and
- case 1:
- return comp0 || comp1; // or
- case 2:
- return comp0 ^ comp1; // xor
- case 3:
- return !(comp0 ^ comp1); // xnor
+ case AlphaTestOp::And:
+ return comp0 && comp1;
+ case AlphaTestOp::Or:
+ return comp0 || comp1;
+ case AlphaTestOp::Xor:
+ return comp0 ^ comp1;
+ case AlphaTestOp::Xnor:
+ return !(comp0 ^ comp1);
default:
+ PanicAlertFmt("Invalid AlphaTestOp {}", bpmem.alpha_test.logic);
return true;
}
}
-static inline s32 WrapIndirectCoord(s32 coord, int wrapMode)
+static inline s32 WrapIndirectCoord(s32 coord, IndTexWrap wrapMode)
{
switch (wrapMode)
{
- case ITW_OFF:
+ case IndTexWrap::ITW_OFF:
return coord;
- case ITW_256:
+ case IndTexWrap::ITW_256:
return (coord & ((256 << 7) - 1));
- case ITW_128:
+ case IndTexWrap::ITW_128:
return (coord & ((128 << 7) - 1));
- case ITW_64:
+ case IndTexWrap::ITW_64:
return (coord & ((64 << 7) - 1));
- case ITW_32:
+ case IndTexWrap::ITW_32:
return (coord & ((32 << 7) - 1));
- case ITW_16:
+ case IndTexWrap::ITW_16:
return (coord & ((16 << 7) - 1));
- case ITW_0:
+ case IndTexWrap::ITW_0:
return 0;
default:
+ PanicAlertFmt("Invalid indirect wrap mode {}", wrapMode);
return 0;
}
}
@@ -455,56 +425,59 @@ void Tev::Indirect(unsigned int stageNum, s32 s, s32 t)
// alpha bump select
switch (indirect.bs)
{
- case ITBA_OFF:
+ case IndTexBumpAlpha::Off:
AlphaBump = 0;
break;
- case ITBA_S:
+ case IndTexBumpAlpha::S:
AlphaBump = indmap[TextureSampler::ALP_SMP];
break;
- case ITBA_T:
+ case IndTexBumpAlpha::T:
AlphaBump = indmap[TextureSampler::BLU_SMP];
break;
- case ITBA_U:
+ case IndTexBumpAlpha::U:
AlphaBump = indmap[TextureSampler::GRN_SMP];
break;
+ default:
+ PanicAlertFmt("Invalid alpha bump {}", indirect.bs);
+ return;
}
// bias select
- const s16 biasValue = indirect.fmt == ITF_8 ? -128 : 1;
+ const s16 biasValue = indirect.fmt == IndTexFormat::ITF_8 ? -128 : 1;
s16 bias[3];
- bias[0] = indirect.bias & 1 ? biasValue : 0;
- bias[1] = indirect.bias & 2 ? biasValue : 0;
- bias[2] = indirect.bias & 4 ? biasValue : 0;
+ bias[0] = indirect.bias_s ? biasValue : 0;
+ bias[1] = indirect.bias_t ? biasValue : 0;
+ bias[2] = indirect.bias_u ? biasValue : 0;
// format
switch (indirect.fmt)
{
- case ITF_8:
+ case IndTexFormat::ITF_8:
indcoord[0] = indmap[TextureSampler::ALP_SMP] + bias[0];
indcoord[1] = indmap[TextureSampler::BLU_SMP] + bias[1];
indcoord[2] = indmap[TextureSampler::GRN_SMP] + bias[2];
AlphaBump = AlphaBump & 0xf8;
break;
- case ITF_5:
+ case IndTexFormat::ITF_5:
indcoord[0] = (indmap[TextureSampler::ALP_SMP] & 0x1f) + bias[0];
indcoord[1] = (indmap[TextureSampler::BLU_SMP] & 0x1f) + bias[1];
indcoord[2] = (indmap[TextureSampler::GRN_SMP] & 0x1f) + bias[2];
AlphaBump = AlphaBump & 0xe0;
break;
- case ITF_4:
+ case IndTexFormat::ITF_4:
indcoord[0] = (indmap[TextureSampler::ALP_SMP] & 0x0f) + bias[0];
indcoord[1] = (indmap[TextureSampler::BLU_SMP] & 0x0f) + bias[1];
indcoord[2] = (indmap[TextureSampler::GRN_SMP] & 0x0f) + bias[2];
AlphaBump = AlphaBump & 0xf0;
break;
- case ITF_3:
+ case IndTexFormat::ITF_3:
indcoord[0] = (indmap[TextureSampler::ALP_SMP] & 0x07) + bias[0];
indcoord[1] = (indmap[TextureSampler::BLU_SMP] & 0x07) + bias[1];
indcoord[2] = (indmap[TextureSampler::GRN_SMP] & 0x07) + bias[2];
AlphaBump = AlphaBump & 0xf8;
break;
default:
- PanicAlertFmt("Tev::Indirect");
+ PanicAlertFmt("Invalid indirect format {}", indirect.fmt);
return;
}
@@ -648,8 +621,8 @@ void Tev::Draw()
}
// set konst for this stage
- const int kc = kSel.getKC(stageOdd);
- const int ka = kSel.getKA(stageOdd);
+ const auto kc = u32(kSel.getKC(stageOdd));
+ const auto ka = u32(kSel.getKA(stageOdd));
StageKonst[RED_C] = *(m_KonstLUT[kc][RED_C]);
StageKonst[GRN_C] = *(m_KonstLUT[kc][GRN_C]);
StageKonst[BLU_C] = *(m_KonstLUT[kc][BLU_C]);
@@ -662,43 +635,43 @@ void Tev::Draw()
InputRegType inputs[4];
for (int i = 0; i < 3; i++)
{
- inputs[BLU_C + i].a = *m_ColorInputLUT[cc.a][i];
- inputs[BLU_C + i].b = *m_ColorInputLUT[cc.b][i];
- inputs[BLU_C + i].c = *m_ColorInputLUT[cc.c][i];
- inputs[BLU_C + i].d = *m_ColorInputLUT[cc.d][i];
+ inputs[BLU_C + i].a = *m_ColorInputLUT[u32(cc.a.Value())][i];
+ inputs[BLU_C + i].b = *m_ColorInputLUT[u32(cc.b.Value())][i];
+ inputs[BLU_C + i].c = *m_ColorInputLUT[u32(cc.c.Value())][i];
+ inputs[BLU_C + i].d = *m_ColorInputLUT[u32(cc.d.Value())][i];
}
- inputs[ALP_C].a = *m_AlphaInputLUT[ac.a];
- inputs[ALP_C].b = *m_AlphaInputLUT[ac.b];
- inputs[ALP_C].c = *m_AlphaInputLUT[ac.c];
- inputs[ALP_C].d = *m_AlphaInputLUT[ac.d];
+ inputs[ALP_C].a = *m_AlphaInputLUT[u32(ac.a.Value())];
+ inputs[ALP_C].b = *m_AlphaInputLUT[u32(ac.b.Value())];
+ inputs[ALP_C].c = *m_AlphaInputLUT[u32(ac.c.Value())];
+ inputs[ALP_C].d = *m_AlphaInputLUT[u32(ac.d.Value())];
- if (cc.bias != 3)
+ if (cc.bias != TevBias::Compare)
DrawColorRegular(cc, inputs);
else
DrawColorCompare(cc, inputs);
if (cc.clamp)
{
- Reg[cc.dest][RED_C] = Clamp255(Reg[cc.dest][RED_C]);
- Reg[cc.dest][GRN_C] = Clamp255(Reg[cc.dest][GRN_C]);
- Reg[cc.dest][BLU_C] = Clamp255(Reg[cc.dest][BLU_C]);
+ Reg[u32(cc.dest.Value())][RED_C] = Clamp255(Reg[u32(cc.dest.Value())][RED_C]);
+ Reg[u32(cc.dest.Value())][GRN_C] = Clamp255(Reg[u32(cc.dest.Value())][GRN_C]);
+ Reg[u32(cc.dest.Value())][BLU_C] = Clamp255(Reg[u32(cc.dest.Value())][BLU_C]);
}
else
{
- Reg[cc.dest][RED_C] = Clamp1024(Reg[cc.dest][RED_C]);
- Reg[cc.dest][GRN_C] = Clamp1024(Reg[cc.dest][GRN_C]);
- Reg[cc.dest][BLU_C] = Clamp1024(Reg[cc.dest][BLU_C]);
+ Reg[u32(cc.dest.Value())][RED_C] = Clamp1024(Reg[u32(cc.dest.Value())][RED_C]);
+ Reg[u32(cc.dest.Value())][GRN_C] = Clamp1024(Reg[u32(cc.dest.Value())][GRN_C]);
+ Reg[u32(cc.dest.Value())][BLU_C] = Clamp1024(Reg[u32(cc.dest.Value())][BLU_C]);
}
- if (ac.bias != 3)
+ if (ac.bias != TevBias::Compare)
DrawAlphaRegular(ac, inputs);
else
DrawAlphaCompare(ac, inputs);
if (ac.clamp)
- Reg[ac.dest][ALP_C] = Clamp255(Reg[ac.dest][ALP_C]);
+ Reg[u32(ac.dest.Value())][ALP_C] = Clamp255(Reg[u32(ac.dest.Value())][ALP_C]);
else
- Reg[ac.dest][ALP_C] = Clamp1024(Reg[ac.dest][ALP_C]);
+ Reg[u32(ac.dest.Value())][ALP_C] = Clamp1024(Reg[u32(ac.dest.Value())][ALP_C]);
#if ALLOW_TEV_DUMPS
if (g_ActiveConfig.bDumpTevStages)
@@ -712,8 +685,8 @@ void Tev::Draw()
// convert to 8 bits per component
// the results of the last tev stage are put onto the screen,
// regardless of the used destination register - TODO: Verify!
- const u32 color_index = bpmem.combiners[bpmem.genMode.numtevstages].colorC.dest;
- const u32 alpha_index = bpmem.combiners[bpmem.genMode.numtevstages].alphaC.dest;
+ const u32 color_index = u32(bpmem.combiners[bpmem.genMode.numtevstages].colorC.dest.Value());
+ const u32 alpha_index = u32(bpmem.combiners[bpmem.genMode.numtevstages].alphaC.dest.Value());
u8 output[4] = {(u8)Reg[alpha_index][ALP_C], (u8)Reg[color_index][BLU_C],
(u8)Reg[color_index][GRN_C], (u8)Reg[color_index][RED_C]};
@@ -721,34 +694,36 @@ void Tev::Draw()
return;
// z texture
- if (bpmem.ztex2.op)
+ if (bpmem.ztex2.op != ZTexOp::Disabled)
{
u32 ztex = bpmem.ztex1.bias;
switch (bpmem.ztex2.type)
{
- case 0: // 8 bit
+ case ZTexFormat::U8:
ztex += TexColor[ALP_C];
break;
- case 1: // 16 bit
+ case ZTexFormat::U16:
ztex += TexColor[ALP_C] << 8 | TexColor[RED_C];
break;
- case 2: // 24 bit
+ case ZTexFormat::U24:
ztex += TexColor[RED_C] << 16 | TexColor[GRN_C] << 8 | TexColor[BLU_C];
break;
+ default:
+ PanicAlertFmt("Invalid ztex format {}", bpmem.ztex2.type);
}
- if (bpmem.ztex2.op == ZTEXTURE_ADD)
+ if (bpmem.ztex2.op == ZTexOp::Add)
ztex += Position[2];
Position[2] = ztex & 0x00ffffff;
}
// fog
- if (bpmem.fog.c_proj_fsel.fsel)
+ if (bpmem.fog.c_proj_fsel.fsel != FogType::Off)
{
float ze;
- if (bpmem.fog.c_proj_fsel.proj == 0)
+ if (bpmem.fog.c_proj_fsel.proj == FogProjection::Perspective)
{
// perspective
// ze = A/(B - (Zs >> B_SHF))
@@ -804,17 +779,17 @@ void Tev::Draw()
switch (bpmem.fog.c_proj_fsel.fsel)
{
- case 4: // exp
+ case FogType::Exp:
fog = 1.0f - pow(2.0f, -8.0f * fog);
break;
- case 5: // exp2
+ case FogType::ExpSq:
fog = 1.0f - pow(2.0f, -8.0f * fog * fog);
break;
- case 6: // backward exp
+ case FogType::BackwardsExp:
fog = 1.0f - fog;
fog = pow(2.0f, -8.0f * fog);
break;
- case 7: // backward exp2
+ case FogType::BackwardsExpSq:
fog = 1.0f - fog;
fog = pow(2.0f, -8.0f * fog * fog);
break;
diff --git a/Source/Core/VideoBackends/Software/Tev.h b/Source/Core/VideoBackends/Software/Tev.h
index 41d880be86..119ab91bd1 100644
--- a/Source/Core/VideoBackends/Software/Tev.h
+++ b/Source/Core/VideoBackends/Software/Tev.h
@@ -57,7 +57,7 @@ class Tev
INDIRECT = 32
};
- void SetRasColor(int colorChan, int swaptable);
+ void SetRasColor(RasColorChan colorChan, int swaptable);
void DrawColorRegular(const TevStageCombiner::ColorCombiner& cc, const InputRegType inputs[4]);
void DrawColorCompare(const TevStageCombiner::ColorCombiner& cc, const InputRegType inputs[4]);
diff --git a/Source/Core/VideoBackends/Software/TextureEncoder.cpp b/Source/Core/VideoBackends/Software/TextureEncoder.cpp
index ff1dd97b96..5ca84558dd 100644
--- a/Source/Core/VideoBackends/Software/TextureEncoder.cpp
+++ b/Source/Core/VideoBackends/Software/TextureEncoder.cpp
@@ -504,7 +504,7 @@ static void EncodeRGBA6(u8* dst, const u8* src, EFBCopyFormat format, bool yuv)
break;
default:
- PanicAlertFmt("Unknown texture copy format: {:#x}\n", format);
+ PanicAlertFmt("Unknown texture copy format: {}\n", format);
break;
}
}
@@ -743,7 +743,7 @@ static void EncodeRGBA6halfscale(u8* dst, const u8* src, EFBCopyFormat format, b
break;
default:
- PanicAlertFmt("Unknown texture copy format: {:#x}\n", format);
+ PanicAlertFmt("Unknown texture copy format: {}\n", format);
break;
}
}
@@ -960,7 +960,7 @@ static void EncodeRGB8(u8* dst, const u8* src, EFBCopyFormat format, bool yuv)
break;
default:
- PanicAlertFmt("Unknown texture copy format: {:#x}\n", format);
+ PanicAlertFmt("Unknown texture copy format: {}\n", format);
break;
}
}
@@ -1192,7 +1192,7 @@ static void EncodeRGB8halfscale(u8* dst, const u8* src, EFBCopyFormat format, bo
break;
default:
- PanicAlertFmt("Unknown texture copy format: {:#x}\n", format);
+ PanicAlertFmt("Unknown texture copy format: {}\n", format);
break;
}
}
@@ -1300,7 +1300,7 @@ static void EncodeZ24(u8* dst, const u8* src, EFBCopyFormat format)
break;
default:
- PanicAlertFmt("Unknown texture copy format: {:#x}\n", format);
+ PanicAlertFmt("Unknown texture copy format: {}\n", format);
break;
}
}
@@ -1414,7 +1414,7 @@ static void EncodeZ24halfscale(u8* dst, const u8* src, EFBCopyFormat format)
break;
default:
- PanicAlertFmt("Unknown texture copy format: {:#x}\n", format);
+ PanicAlertFmt("Unknown texture copy format: {}\n", format);
break;
}
}
@@ -1431,16 +1431,16 @@ void EncodeEfbCopy(u8* dst, const EFBCopyParams& params, u32 native_width, u32 b
{
switch (params.efb_format)
{
- case PEControl::RGBA6_Z24:
+ case PixelFormat::RGBA6_Z24:
EncodeRGBA6halfscale(dst, src, params.copy_format, params.yuv);
break;
- case PEControl::RGB8_Z24:
+ case PixelFormat::RGB8_Z24:
EncodeRGB8halfscale(dst, src, params.copy_format, params.yuv);
break;
- case PEControl::RGB565_Z16:
+ case PixelFormat::RGB565_Z16:
EncodeRGB8halfscale(dst, src, params.copy_format, params.yuv);
break;
- case PEControl::Z24:
+ case PixelFormat::Z24:
EncodeZ24halfscale(dst, src, params.copy_format);
break;
default:
@@ -1451,16 +1451,16 @@ void EncodeEfbCopy(u8* dst, const EFBCopyParams& params, u32 native_width, u32 b
{
switch (params.efb_format)
{
- case PEControl::RGBA6_Z24:
+ case PixelFormat::RGBA6_Z24:
EncodeRGBA6(dst, src, params.copy_format, params.yuv);
break;
- case PEControl::RGB8_Z24:
+ case PixelFormat::RGB8_Z24:
EncodeRGB8(dst, src, params.copy_format, params.yuv);
break;
- case PEControl::RGB565_Z16:
+ case PixelFormat::RGB565_Z16:
EncodeRGB8(dst, src, params.copy_format, params.yuv);
break;
- case PEControl::Z24:
+ case PixelFormat::Z24:
EncodeZ24(dst, src, params.copy_format);
break;
default:
diff --git a/Source/Core/VideoBackends/Software/TextureSampler.cpp b/Source/Core/VideoBackends/Software/TextureSampler.cpp
index 93ff4ba44e..799db7c49b 100644
--- a/Source/Core/VideoBackends/Software/TextureSampler.cpp
+++ b/Source/Core/VideoBackends/Software/TextureSampler.cpp
@@ -8,6 +8,7 @@
#include <cmath>
#include "Common/CommonTypes.h"
+#include "Common/MsgHandler.h"
#include "Core/HW/Memmap.h"
#include "VideoCommon/BPMemory.h"
@@ -18,27 +19,29 @@
namespace TextureSampler
{
-static inline void WrapCoord(int* coordp, int wrapMode, int imageSize)
+static inline void WrapCoord(int* coordp, WrapMode wrapMode, int imageSize)
{
int coord = *coordp;
switch (wrapMode)
{
- case 0: // clamp
+ case WrapMode::Clamp:
coord = (coord > imageSize) ? imageSize : (coord < 0) ? 0 : coord;
break;
- case 1: // wrap
+ case WrapMode::Repeat:
coord = coord % (imageSize + 1);
coord = (coord < 0) ? imageSize + coord : coord;
break;
- case 2: // mirror
+ case WrapMode::Mirror:
{
const int sizePlus1 = imageSize + 1;
const int div = coord / sizePlus1;
coord = coord - (div * sizePlus1);
coord = (coord < 0) ? -coord : coord;
coord = (div & 1) ? imageSize - coord : coord;
+ break;
}
- break;
+ default:
+ PanicAlertFmt("Invalid wrap mode: {}", wrapMode);
}
*coordp = coord;
}
@@ -74,10 +77,11 @@ void Sample(s32 s, s32 t, s32 lod, bool linear, u8 texmap, u8* sample)
{
// use mipmap
baseMip = lod >> 4;
- mipLinear = (lodFract && tm0.min_filter & TexMode0::TEXF_LINEAR);
+ mipLinear = (lodFract && tm0.mipmap_filter == MipMode::Linear);
// if using nearest mip filter and lodFract >= 0.5 round up to next mip
- baseMip += (lodFract >> 3) & (tm0.min_filter & TexMode0::TEXF_POINT);
+ if (tm0.mipmap_filter == MipMode::Point && lodFract >= 8)
+ baseMip++;
}
if (mipLinear)
@@ -111,12 +115,12 @@ void SampleMip(s32 s, s32 t, s32 mip, bool linear, u8 texmap, u8* sample)
const TexMode0& tm0 = texUnit.texMode0[subTexmap];
const TexImage0& ti0 = texUnit.texImage0[subTexmap];
const TexTLUT& texTlut = texUnit.texTlut[subTexmap];
- const TextureFormat texfmt = static_cast<TextureFormat>(ti0.format);
- const TLUTFormat tlutfmt = static_cast<TLUTFormat>(texTlut.tlut_format);
+ const TextureFormat texfmt = ti0.format;
+ const TLUTFormat tlutfmt = texTlut.tlut_format;
const u8* imageSrc;
const u8* imageSrcOdd = nullptr;
- if (texUnit.texImage1[subTexmap].image_type)
+ if (texUnit.texImage1[subTexmap].cache_manually_managed)
{
imageSrc = &texMem[texUnit.texImage1[subTexmap].tmem_even * TMEM_LINE_SIZE];
if (texfmt == TextureFormat::RGBA8)
@@ -188,7 +192,7 @@ void SampleMip(s32 s, s32 t, s32 mip, bool linear, u8 texmap, u8* sample)
WrapCoord(&imageSPlus1, tm0.wrap_s, imageWidth);
WrapCoord(&imageTPlus1, tm0.wrap_t, imageHeight);
- if (!(texfmt == TextureFormat::RGBA8 && texUnit.texImage1[subTexmap].image_type))
+ if (!(texfmt == TextureFormat::RGBA8 && texUnit.texImage1[subTexmap].cache_manually_managed))
{
TexDecoder_DecodeTexel(sampledTex, imageSrc, imageS, imageT, imageWidth, texfmt, tlut,
tlutfmt);
@@ -240,7 +244,7 @@ void SampleMip(s32 s, s32 t, s32 mip, bool linear, u8 texmap, u8* sample)
WrapCoord(&imageS, tm0.wrap_s, imageWidth);
WrapCoord(&imageT, tm0.wrap_t, imageHeight);
- if (!(texfmt == TextureFormat::RGBA8 && texUnit.texImage1[subTexmap].image_type))
+ if (!(texfmt == TextureFormat::RGBA8 && texUnit.texImage1[subTexmap].cache_manually_managed))
TexDecoder_DecodeTexel(sample, imageSrc, imageS, imageT, imageWidth, texfmt, tlut, tlutfmt);
else
TexDecoder_DecodeTexelRGBA8FromTmem(sample, imageSrc, imageSrcOdd, imageS, imageT,
diff --git a/Source/Core/VideoBackends/Vulkan/VKPipeline.cpp b/Source/Core/VideoBackends/Vulkan/VKPipeline.cpp
index b7c656bec9..048f84b9b9 100644
--- a/Source/Core/VideoBackends/Vulkan/VKPipeline.cpp
+++ b/Source/Core/VideoBackends/Vulkan/VKPipeline.cpp
@@ -52,13 +52,13 @@ GetVulkanRasterizationState(const RasterizationState& state)
depth_clamp, // VkBool32 depthClampEnable
VK_FALSE, // VkBool32 rasterizerDiscardEnable
VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode
- cull_modes[state.cullmode], // VkCullModeFlags cullMode
- VK_FRONT_FACE_CLOCKWISE, // VkFrontFace frontFace
- VK_FALSE, // VkBool32 depthBiasEnable
- 0.0f, // float depthBiasConstantFactor
- 0.0f, // float depthBiasClamp
- 0.0f, // float depthBiasSlopeFactor
- 1.0f // float lineWidth
+ cull_modes[u32(state.cullmode.Value())], // VkCullModeFlags cullMode
+ VK_FRONT_FACE_CLOCKWISE, // VkFrontFace frontFace
+ VK_FALSE, // VkBool32 depthBiasEnable
+ 0.0f, // float depthBiasConstantFactor
+ 0.0f, // float depthBiasClamp
+ 0.0f, // float depthBiasSlopeFactor
+ 1.0f // float lineWidth
};
}
@@ -85,31 +85,32 @@ static VkPipelineDepthStencilStateCreateInfo GetVulkanDepthStencilState(const De
bool inverted_depth = !g_ActiveConfig.backend_info.bSupportsReversedDepthRange;
switch (state.func)
{
- case ZMode::NEVER:
+ case CompareMode::Never:
compare_op = VK_COMPARE_OP_NEVER;
break;
- case ZMode::LESS:
+ case CompareMode::Less:
compare_op = inverted_depth ? VK_COMPARE_OP_GREATER : VK_COMPARE_OP_LESS;
break;
- case ZMode::EQUAL:
+ case CompareMode::Equal:
compare_op = VK_COMPARE_OP_EQUAL;
break;
- case ZMode::LEQUAL:
+ case CompareMode::LEqual:
compare_op = inverted_depth ? VK_COMPARE_OP_GREATER_OR_EQUAL : VK_COMPARE_OP_LESS_OR_EQUAL;
break;
- case ZMode::GREATER:
+ case CompareMode::Greater:
compare_op = inverted_depth ? VK_COMPARE_OP_LESS : VK_COMPARE_OP_GREATER;
break;
- case ZMode::NEQUAL:
+ case CompareMode::NEqual:
compare_op = VK_COMPARE_OP_NOT_EQUAL;
break;
- case ZMode::GEQUAL:
+ case CompareMode::GEqual:
compare_op = inverted_depth ? VK_COMPARE_OP_LESS_OR_EQUAL : VK_COMPARE_OP_GREATER_OR_EQUAL;
break;
- case ZMode::ALWAYS:
+ case CompareMode::Always:
compare_op = VK_COMPARE_OP_ALWAYS;
break;
default:
+ PanicAlertFmt("Invalid compare mode {}", state.func);
compare_op = VK_COMPARE_OP_ALWAYS;
break;
}
@@ -150,10 +151,10 @@ static VkPipelineColorBlendAttachmentState GetVulkanAttachmentBlendState(const B
VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, VK_BLEND_FACTOR_DST_ALPHA,
VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA}};
- vk_state.srcColorBlendFactor = src_factors[state.srcfactor];
- vk_state.srcAlphaBlendFactor = src_factors[state.srcfactoralpha];
- vk_state.dstColorBlendFactor = dst_factors[state.dstfactor];
- vk_state.dstAlphaBlendFactor = dst_factors[state.dstfactoralpha];
+ vk_state.srcColorBlendFactor = src_factors[u32(state.srcfactor.Value())];
+ vk_state.srcAlphaBlendFactor = src_factors[u32(state.srcfactoralpha.Value())];
+ vk_state.dstColorBlendFactor = dst_factors[u32(state.dstfactor.Value())];
+ vk_state.dstAlphaBlendFactor = dst_factors[u32(state.dstfactoralpha.Value())];
}
else
{
@@ -169,10 +170,10 @@ static VkPipelineColorBlendAttachmentState GetVulkanAttachmentBlendState(const B
VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, VK_BLEND_FACTOR_DST_ALPHA,
VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA}};
- vk_state.srcColorBlendFactor = src_factors[state.srcfactor];
- vk_state.srcAlphaBlendFactor = src_factors[state.srcfactoralpha];
- vk_state.dstColorBlendFactor = dst_factors[state.dstfactor];
- vk_state.dstAlphaBlendFactor = dst_factors[state.dstfactoralpha];
+ vk_state.srcColorBlendFactor = src_factors[u32(state.srcfactor.Value())];
+ vk_state.srcAlphaBlendFactor = src_factors[u32(state.srcfactoralpha.Value())];
+ vk_state.dstColorBlendFactor = dst_factors[u32(state.dstfactor.Value())];
+ vk_state.dstAlphaBlendFactor = dst_factors[u32(state.dstfactoralpha.Value())];
}
if (state.colorupdate)
@@ -211,7 +212,8 @@ GetVulkanColorBlendState(const BlendingState& state,
vk_logic_op_enable = VK_FALSE;
}
- VkLogicOp vk_logic_op = vk_logic_op_enable ? vk_logic_ops[state.logicmode] : VK_LOGIC_OP_CLEAR;
+ VkLogicOp vk_logic_op =
+ vk_logic_op_enable ? vk_logic_ops[u32(state.logicmode.Value())] : VK_LOGIC_OP_CLEAR;
VkPipelineColorBlendStateCreateInfo vk_state = {
VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType
diff --git a/Source/Core/VideoBackends/Vulkan/VKRenderer.cpp b/Source/Core/VideoBackends/Vulkan/VKRenderer.cpp
index b2f3f45072..489ee8b8df 100644
--- a/Source/Core/VideoBackends/Vulkan/VKRenderer.cpp
+++ b/Source/Core/VideoBackends/Vulkan/VKRenderer.cpp
@@ -166,9 +166,9 @@ void Renderer::ClearScreen(const MathUtil::Rectangle<int>& rc, bool color_enable
// Determine whether the EFB has an alpha channel. If it doesn't, we can clear the alpha
// channel to 0xFF. This hopefully allows us to use the fast path in most cases.
- if (bpmem.zcontrol.pixel_format == PEControl::RGB565_Z16 ||
- bpmem.zcontrol.pixel_format == PEControl::RGB8_Z24 ||
- bpmem.zcontrol.pixel_format == PEControl::Z24)
+ if (bpmem.zcontrol.pixel_format == PixelFormat::RGB565_Z16 ||
+ bpmem.zcontrol.pixel_format == PixelFormat::RGB8_Z24 ||
+ bpmem.zcontrol.pixel_format == PixelFormat::Z24)
{
// Force alpha writes, and clear the alpha channel. This is different to the other backends,
// where the existing values of the alpha channel are preserved.
diff --git a/Source/Core/VideoCommon/BPFunctions.cpp b/Source/Core/VideoCommon/BPFunctions.cpp
index 52cd8375fd..1242c8e853 100644
--- a/Source/Core/VideoCommon/BPFunctions.cpp
+++ b/Source/Core/VideoCommon/BPFunctions.cpp
@@ -184,8 +184,8 @@ void ClearScreen(const MathUtil::Rectangle<int>& rc)
auto pixel_format = bpmem.zcontrol.pixel_format;
// (1): Disable unused color channels
- if (pixel_format == PEControl::RGB8_Z24 || pixel_format == PEControl::RGB565_Z16 ||
- pixel_format == PEControl::Z24)
+ if (pixel_format == PixelFormat::RGB8_Z24 || pixel_format == PixelFormat::RGB565_Z16 ||
+ pixel_format == PixelFormat::Z24)
{
alphaEnable = false;
}
@@ -196,11 +196,11 @@ void ClearScreen(const MathUtil::Rectangle<int>& rc)
u32 z = bpmem.clearZValue;
// (2) drop additional accuracy
- if (pixel_format == PEControl::RGBA6_Z24)
+ if (pixel_format == PixelFormat::RGBA6_Z24)
{
color = RGBA8ToRGBA6ToRGBA8(color);
}
- else if (pixel_format == PEControl::RGB565_Z16)
+ else if (pixel_format == PixelFormat::RGB565_Z16)
{
color = RGBA8ToRGB565ToRGBA8(color);
z = Z24ToZ16ToZ24(z);
@@ -228,29 +228,28 @@ void OnPixelFormatChange()
const auto new_format = bpmem.zcontrol.pixel_format;
g_renderer->StorePixelFormat(new_format);
- DEBUG_LOG_FMT(VIDEO, "pixelfmt: pixel={}, zc={}", static_cast<int>(new_format),
- static_cast<int>(bpmem.zcontrol.zformat));
+ DEBUG_LOG_FMT(VIDEO, "pixelfmt: pixel={}, zc={}", new_format, bpmem.zcontrol.zformat);
// no need to reinterpret pixel data in these cases
- if (new_format == old_format || old_format == PEControl::INVALID_FMT)
+ if (new_format == old_format || old_format == PixelFormat::INVALID_FMT)
return;
// Check for pixel format changes
switch (old_format)
{
- case PEControl::RGB8_Z24:
- case PEControl::Z24:
+ case PixelFormat::RGB8_Z24:
+ case PixelFormat::Z24:
{
// Z24 and RGB8_Z24 are treated equal, so just return in this case
- if (new_format == PEControl::RGB8_Z24 || new_format == PEControl::Z24)
+ if (new_format == PixelFormat::RGB8_Z24 || new_format == PixelFormat::Z24)
return;
- if (new_format == PEControl::RGBA6_Z24)
+ if (new_format == PixelFormat::RGBA6_Z24)
{
g_renderer->ReinterpretPixelData(EFBReinterpretType::RGB8ToRGBA6);
return;
}
- else if (new_format == PEControl::RGB565_Z16)
+ else if (new_format == PixelFormat::RGB565_Z16)
{
g_renderer->ReinterpretPixelData(EFBReinterpretType::RGB8ToRGB565);
return;
@@ -258,14 +257,14 @@ void OnPixelFormatChange()
}
break;
- case PEControl::RGBA6_Z24:
+ case PixelFormat::RGBA6_Z24:
{
- if (new_format == PEControl::RGB8_Z24 || new_format == PEControl::Z24)
+ if (new_format == PixelFormat::RGB8_Z24 || new_format == PixelFormat::Z24)
{
g_renderer->ReinterpretPixelData(EFBReinterpretType::RGBA6ToRGB8);
return;
}
- else if (new_format == PEControl::RGB565_Z16)
+ else if (new_format == PixelFormat::RGB565_Z16)
{
g_renderer->ReinterpretPixelData(EFBReinterpretType::RGBA6ToRGB565);
return;
@@ -273,14 +272,14 @@ void OnPixelFormatChange()
}
break;
- case PEControl::RGB565_Z16:
+ case PixelFormat::RGB565_Z16:
{
- if (new_format == PEControl::RGB8_Z24 || new_format == PEControl::Z24)
+ if (new_format == PixelFormat::RGB8_Z24 || new_format == PixelFormat::Z24)
{
g_renderer->ReinterpretPixelData(EFBReinterpretType::RGB565ToRGB8);
return;
}
- else if (new_format == PEControl::RGBA6_Z24)
+ else if (new_format == PixelFormat::RGBA6_Z24)
{
g_renderer->ReinterpretPixelData(EFBReinterpretType::RGB565ToRGBA6);
return;
@@ -292,8 +291,7 @@ void OnPixelFormatChange()
break;
}
- ERROR_LOG_FMT(VIDEO, "Unhandled EFB format change: {} to {}", static_cast<int>(old_format),
- static_cast<int>(new_format));
+ ERROR_LOG_FMT(VIDEO, "Unhandled EFB format change: {} to {}", old_format, new_format);
}
void SetInterlacingMode(const BPCmd& bp)
@@ -305,17 +303,15 @@ void SetInterlacingMode(const BPCmd& bp)
{
// SDK always sets bpmem.lineptwidth.lineaspect via BPMEM_LINEPTWIDTH
// just before this cmd
- static constexpr std::string_view action[] = {"don't adjust", "adjust"};
- DEBUG_LOG_FMT(VIDEO, "BPMEM_FIELDMODE texLOD:{} lineaspect:{}", action[bpmem.fieldmode.texLOD],
- action[bpmem.lineptwidth.lineaspect]);
+ DEBUG_LOG_FMT(VIDEO, "BPMEM_FIELDMODE texLOD:{} lineaspect:{}", bpmem.fieldmode.texLOD,
+ bpmem.lineptwidth.adjust_for_aspect_ratio);
}
break;
case BPMEM_FIELDMASK:
{
// Determines if fields will be written to EFB (always computed)
- static constexpr std::string_view action[] = {"skip", "write"};
- DEBUG_LOG_FMT(VIDEO, "BPMEM_FIELDMASK even:{} odd:{}", action[bpmem.fieldmask.even],
- action[bpmem.fieldmask.odd]);
+ DEBUG_LOG_FMT(VIDEO, "BPMEM_FIELDMASK even:{} odd:{}", bpmem.fieldmask.even,
+ bpmem.fieldmask.odd);
}
break;
default:
diff --git a/Source/Core/VideoCommon/BPMemory.cpp b/Source/Core/VideoCommon/BPMemory.cpp
index e3887327d3..c5749a7bb4 100644
--- a/Source/Core/VideoCommon/BPMemory.cpp
+++ b/Source/Core/VideoCommon/BPMemory.cpp
@@ -17,7 +17,7 @@ bool BlendMode::UseLogicOp() const
return false;
// Fast path for Kirby's Return to Dreamland, they use it with dstAlpha.
- if (logicmode == BlendMode::NOOP)
+ if (logicmode == LogicOp::NoOp)
return false;
return true;
diff --git a/Source/Core/VideoCommon/BPMemory.h b/Source/Core/VideoCommon/BPMemory.h
index f6d54a6e74..2a8d8ba0dd 100644
--- a/Source/Core/VideoCommon/BPMemory.h
+++ b/Source/Core/VideoCommon/BPMemory.h
@@ -9,9 +9,16 @@
#include "Common/BitField.h"
#include "Common/CommonTypes.h"
+#include "Common/EnumFormatter.h"
#include "Common/Inline.h"
+// X.h defines None to be 0 and Always to be 2, which causes problems with some of the enums
+#undef None
+#undef Always
+
+enum class TextureFormat;
enum class EFBCopyFormat;
+enum class TLUTFormat;
#pragma pack(4)
@@ -104,140 +111,209 @@ enum
// Tev/combiner things
// TEV scaling type
-enum : u32
+enum class TevScale : u32
{
- TEVSCALE_1 = 0,
- TEVSCALE_2 = 1,
- TEVSCALE_4 = 2,
- TEVDIVIDE_2 = 3
+ Scale1 = 0,
+ Scale2 = 1,
+ Scale4 = 2,
+ Divide2 = 3
};
-
-enum : u32
+template <>
+struct fmt::formatter<TevScale> : EnumFormatter<TevScale::Divide2>
{
- TEVCMP_R8 = 0,
- TEVCMP_GR16 = 1,
- TEVCMP_BGR24 = 2,
- TEVCMP_RGB8 = 3
+ formatter() : EnumFormatter({"1", "2", "4", "0.5"}) {}
};
// TEV combiner operator
-enum : u32
-{
- TEVOP_ADD = 0,
- TEVOP_SUB = 1,
- TEVCMP_R8_GT = 8,
- TEVCMP_R8_EQ = 9,
- TEVCMP_GR16_GT = 10,
- TEVCMP_GR16_EQ = 11,
- TEVCMP_BGR24_GT = 12,
- TEVCMP_BGR24_EQ = 13,
- TEVCMP_RGB8_GT = 14,
- TEVCMP_RGB8_EQ = 15,
- TEVCMP_A8_GT = TEVCMP_RGB8_GT,
- TEVCMP_A8_EQ = TEVCMP_RGB8_EQ
+enum class TevOp : u32
+{
+ Add = 0,
+ Sub = 1,
+};
+template <>
+struct fmt::formatter<TevOp> : EnumFormatter<TevOp::Sub>
+{
+ formatter() : EnumFormatter({"Add", "Subtract"}) {}
+};
+
+enum class TevCompareMode : u32
+{
+ R8 = 0,
+ GR16 = 1,
+ BGR24 = 2,
+ RGB8 = 3,
+ A8 = RGB8,
+};
+template <>
+struct fmt::formatter<TevCompareMode> : EnumFormatter<TevCompareMode::RGB8>
+{
+ formatter() : EnumFormatter({"R8", "GR16", "BGR24", "RGB8 / A8"}) {}
+};
+
+enum class TevComparison : u32
+{
+ GT = 0,
+ EQ = 1,
+};
+template <>
+struct fmt::formatter<TevComparison> : EnumFormatter<TevComparison::EQ>
+{
+ formatter() : EnumFormatter({"Greater than", "Equal to"}) {}
};
// TEV color combiner input
-enum : u32
-{
- TEVCOLORARG_CPREV = 0,
- TEVCOLORARG_APREV = 1,
- TEVCOLORARG_C0 = 2,
- TEVCOLORARG_A0 = 3,
- TEVCOLORARG_C1 = 4,
- TEVCOLORARG_A1 = 5,
- TEVCOLORARG_C2 = 6,
- TEVCOLORARG_A2 = 7,
- TEVCOLORARG_TEXC = 8,
- TEVCOLORARG_TEXA = 9,
- TEVCOLORARG_RASC = 10,
- TEVCOLORARG_RASA = 11,
- TEVCOLORARG_ONE = 12,
- TEVCOLORARG_HALF = 13,
- TEVCOLORARG_KONST = 14,
- TEVCOLORARG_ZERO = 15
+enum class TevColorArg : u32
+{
+ PrevColor = 0,
+ PrevAlpha = 1,
+ Color0 = 2,
+ Alpha0 = 3,
+ Color1 = 4,
+ Alpha1 = 5,
+ Color2 = 6,
+ Alpha2 = 7,
+ TexColor = 8,
+ TexAlpha = 9,
+ RasColor = 10,
+ RasAlpha = 11,
+ One = 12,
+ Half = 13,
+ Konst = 14,
+ Zero = 15
+};
+template <>
+struct fmt::formatter<TevColorArg> : EnumFormatter<TevColorArg::Zero>
+{
+ static constexpr array_type names = {
+ "prev.rgb", "prev.aaa", "c0.rgb", "c0.aaa", "c1.rgb", "c1.aaa", "c2.rgb", "c2.aaa",
+ "tex.rgb", "tex.aaa", "ras.rgb", "ras.aaa", "ONE", "HALF", "konst.rgb", "ZERO",
+ };
+ formatter() : EnumFormatter(names) {}
};
// TEV alpha combiner input
-enum : u32
+enum class TevAlphaArg : u32
{
- TEVALPHAARG_APREV = 0,
- TEVALPHAARG_A0 = 1,
- TEVALPHAARG_A1 = 2,
- TEVALPHAARG_A2 = 3,
- TEVALPHAARG_TEXA = 4,
- TEVALPHAARG_RASA = 5,
- TEVALPHAARG_KONST = 6,
- TEVALPHAARG_ZERO = 7
+ PrevAlpha = 0,
+ Alpha0 = 1,
+ Alpha1 = 2,
+ Alpha2 = 3,
+ TexAlpha = 4,
+ RasAlpha = 5,
+ Konst = 6,
+ Zero = 7
+};
+template <>
+struct fmt::formatter<TevAlphaArg> : EnumFormatter<TevAlphaArg::Zero>
+{
+ static constexpr array_type names = {
+ "prev", "c0", "c1", "c2", "tex", "ras", "konst", "ZERO",
+ };
+ formatter() : EnumFormatter(names) {}
};
// TEV output registers
-enum : u32
+enum class TevOutput : u32
{
- GX_TEVPREV = 0,
- GX_TEVREG0 = 1,
- GX_TEVREG1 = 2,
- GX_TEVREG2 = 3
+ Prev = 0,
+ Color0 = 1,
+ Color1 = 2,
+ Color2 = 3,
+};
+template <>
+struct fmt::formatter<TevOutput> : EnumFormatter<TevOutput::Color2>
+{
+ formatter() : EnumFormatter({"prev", "c0", "c1", "c2"}) {}
};
// Z-texture formats
-enum : u32
+enum class ZTexFormat : u32
+{
+ U8 = 0,
+ U16 = 1,
+ U24 = 2
+};
+template <>
+struct fmt::formatter<ZTexFormat> : EnumFormatter<ZTexFormat::U24>
{
- TEV_ZTEX_TYPE_U8 = 0,
- TEV_ZTEX_TYPE_U16 = 1,
- TEV_ZTEX_TYPE_U24 = 2
+ formatter() : EnumFormatter({"u8", "u16", "u24"}) {}
};
// Z texture operator
-enum : u32
+enum ZTexOp : u32
{
- ZTEXTURE_DISABLE = 0,
- ZTEXTURE_ADD = 1,
- ZTEXTURE_REPLACE = 2
+ Disabled = 0,
+ Add = 1,
+ Replace = 2
+};
+template <>
+struct fmt::formatter<ZTexOp> : EnumFormatter<ZTexOp::Replace>
+{
+ formatter() : EnumFormatter({"Disabled", "Add", "Replace"}) {}
};
// TEV bias value
-enum : u32
+enum class TevBias : u32
+{
+ Zero = 0,
+ AddHalf = 1,
+ Subhalf = 2,
+ Compare = 3
+};
+template <>
+struct fmt::formatter<TevBias> : EnumFormatter<TevBias::Compare>
{
- TEVBIAS_ZERO = 0,
- TEVBIAS_ADDHALF = 1,
- TEVBIAS_SUBHALF = 2,
- TEVBIAS_COMPARE = 3
+ formatter() : EnumFormatter({"0", "+0.5", "-0.5", "compare"}) {}
};
// Indirect texture format
-enum : u32
+enum class IndTexFormat : u32
{
ITF_8 = 0,
ITF_5 = 1,
ITF_4 = 2,
ITF_3 = 3
};
+template <>
+struct fmt::formatter<IndTexFormat> : EnumFormatter<IndTexFormat::ITF_3>
+{
+ formatter() : EnumFormatter({"ITF_8", "ITF_5", "ITF_4", "ITF_3"}) {}
+};
// Indirect texture bias
-enum : u32
+enum class IndTexBias : u32
+{
+ None = 0,
+ S = 1,
+ T = 2,
+ ST = 3,
+ U = 4,
+ SU = 5,
+ TU_ = 6, // conflicts with define in PowerPC.h
+ STU = 7
+};
+template <>
+struct fmt::formatter<IndTexBias> : EnumFormatter<IndTexBias::STU>
{
- ITB_NONE = 0,
- ITB_S = 1,
- ITB_T = 2,
- ITB_ST = 3,
- ITB_U = 4,
- ITB_SU = 5,
- ITB_TU = 6,
- ITB_STU = 7
+ formatter() : EnumFormatter({"None", "S", "T", "ST", "U", "SU", "TU", "STU"}) {}
};
// Indirect texture bump alpha
-enum : u32
+enum class IndTexBumpAlpha : u32
{
- ITBA_OFF = 0,
- ITBA_S = 1,
- ITBA_T = 2,
- ITBA_U = 3
+ Off = 0,
+ S = 1,
+ T = 2,
+ U = 3
+};
+template <>
+struct fmt::formatter<IndTexBumpAlpha> : EnumFormatter<IndTexBumpAlpha::U>
+{
+ formatter() : EnumFormatter({"Off", "S", "T", "U"}) {}
};
// Indirect texture wrap value
-enum : u32
+enum class IndTexWrap : u32
{
ITW_OFF = 0,
ITW_256 = 1,
@@ -247,40 +323,33 @@ enum : u32
ITW_16 = 5,
ITW_0 = 6
};
+template <>
+struct fmt::formatter<IndTexWrap> : EnumFormatter<IndTexWrap::ITW_0>
+{
+ formatter() : EnumFormatter({"Off", "256", "128", "64", "32", "16", "0"}) {}
+};
union IND_MTXA
{
- struct
- {
- s32 ma : 11;
- s32 mb : 11;
- u32 s0 : 2; // bits 0-1 of scale factor
- u32 rid : 8;
- };
+ BitField<0, 11, s32> ma;
+ BitField<11, 11, s32> mb;
+ BitField<22, 2, u32> s0; // bits 0-1 of scale factor
u32 hex;
};
union IND_MTXB
{
- struct
- {
- s32 mc : 11;
- s32 md : 11;
- u32 s1 : 2; // bits 2-3 of scale factor
- u32 rid : 8;
- };
+ BitField<0, 11, s32> mc;
+ BitField<11, 11, s32> md;
+ BitField<22, 2, u32> s1; // bits 2-3 of scale factor
u32 hex;
};
union IND_MTXC
{
- struct
- {
- s32 me : 11;
- s32 mf : 11;
- u32 s2 : 2; // bits 4-5 of scale factor
- u32 rid : 8;
- };
+ BitField<0, 11, s32> me;
+ BitField<11, 11, s32> mf;
+ BitField<22, 2, u32> s2; // bits 4-5 of scale factor
u32 hex;
};
@@ -293,11 +362,7 @@ struct IND_MTX
union IND_IMASK
{
- struct
- {
- u32 mask : 24;
- u32 rid : 8;
- };
+ BitField<0, 24, u32> mask;
u32 hex;
};
@@ -306,17 +371,19 @@ struct TevStageCombiner
union ColorCombiner
{
// abc=8bit,d=10bit
- BitField<0, 4, u32> d; // TEVSELCC_X
- BitField<4, 4, u32> c; // TEVSELCC_X
- BitField<8, 4, u32> b; // TEVSELCC_X
- BitField<12, 4, u32> a; // TEVSELCC_X
+ BitField<0, 4, TevColorArg> d;
+ BitField<4, 4, TevColorArg> c;
+ BitField<8, 4, TevColorArg> b;
+ BitField<12, 4, TevColorArg> a;
- BitField<16, 2, u32> bias;
- BitField<18, 1, u32> op;
- BitField<19, 1, u32> clamp;
+ BitField<16, 2, TevBias> bias;
+ BitField<18, 1, TevOp> op; // Applies when bias is not compare
+ BitField<18, 1, TevComparison> comparison; // Applies when bias is compare
+ BitField<19, 1, bool, u32> clamp;
- BitField<20, 2, u32> shift;
- BitField<22, 2, u32> dest; // 1,2,3
+ BitField<20, 2, TevScale> scale; // Applies when bias is not compare
+ BitField<20, 2, TevCompareMode> compare_mode; // Applies when bias is compare
+ BitField<22, 2, TevOutput> dest;
u32 hex;
};
@@ -324,17 +391,19 @@ struct TevStageCombiner
{
BitField<0, 2, u32> rswap;
BitField<2, 2, u32> tswap;
- BitField<4, 3, u32> d; // TEVSELCA_
- BitField<7, 3, u32> c; // TEVSELCA_
- BitField<10, 3, u32> b; // TEVSELCA_
- BitField<13, 3, u32> a; // TEVSELCA_
+ BitField<4, 3, TevAlphaArg> d;
+ BitField<7, 3, TevAlphaArg> c;
+ BitField<10, 3, TevAlphaArg> b;
+ BitField<13, 3, TevAlphaArg> a;
- BitField<16, 2, u32> bias; // GXTevBias
- BitField<18, 1, u32> op;
- BitField<19, 1, u32> clamp;
+ BitField<16, 2, TevBias> bias;
+ BitField<18, 1, TevOp> op; // Applies when bias is not compare
+ BitField<18, 1, TevComparison> comparison; // Applies when bias is compare
+ BitField<19, 1, bool, u32> clamp;
- BitField<20, 2, u32> shift;
- BitField<22, 2, u32> dest; // 1,2,3
+ BitField<20, 2, TevScale> scale; // Applies when bias is not compare
+ BitField<20, 2, TevCompareMode> compare_mode; // Applies when bias is compare
+ BitField<22, 2, TevOutput> dest;
u32 hex;
};
@@ -354,17 +423,20 @@ struct TevStageCombiner
union TevStageIndirect
{
- BitField<0, 2, u32> bt; // Indirect tex stage ID
- BitField<2, 2, u32> fmt; // Format: ITF_X
- BitField<4, 3, u32> bias; // ITB_X
- BitField<7, 2, u32> bs; // ITBA_X, indicates which coordinate will become the 'bump alpha'
- BitField<9, 4, u32> mid; // Matrix ID to multiply offsets with
- BitField<13, 3, u32> sw; // ITW_X, wrapping factor for S of regular coord
- BitField<16, 3, u32> tw; // ITW_X, wrapping factor for T of regular coord
- BitField<19, 1, u32> lb_utclod; // Use modified or unmodified texture
- // coordinates for LOD computation
- BitField<20, 1, u32> fb_addprev; // 1 if the texture coordinate results from the previous TEV
- // stage should be added
+ BitField<0, 2, u32> bt; // Indirect tex stage ID
+ BitField<2, 2, IndTexFormat> fmt;
+ BitField<4, 3, IndTexBias> bias;
+ BitField<4, 1, bool, u32> bias_s;
+ BitField<5, 1, bool, u32> bias_t;
+ BitField<6, 1, bool, u32> bias_u;
+ BitField<7, 2, IndTexBumpAlpha> bs; // Indicates which coordinate will become the 'bump alpha'
+ BitField<9, 4, u32> mid; // Matrix ID to multiply offsets with
+ BitField<13, 3, IndTexWrap> sw; // Wrapping factor for S of regular coord
+ BitField<16, 3, IndTexWrap> tw; // Wrapping factor for T of regular coord
+ BitField<19, 1, bool, u32> lb_utclod; // Use modified or unmodified texture
+ // coordinates for LOD computation
+ BitField<20, 1, bool, u32> fb_addprev; // true if the texture coordinate results from the
+ // previous TEV stage should be added
struct
{
@@ -374,58 +446,65 @@ union TevStageIndirect
// If bs and mid are zero, the result of the stage is independent of
// the texture sample data, so we can skip sampling the texture.
- bool IsActive() const { return bs != ITBA_OFF || mid != 0; }
+ bool IsActive() const { return bs != IndTexBumpAlpha::Off || mid != 0; }
+};
+
+enum class RasColorChan : u32
+{
+ Color0 = 0,
+ Color1 = 1,
+ AlphaBump = 5,
+ NormalizedAlphaBump = 6,
+ Zero = 7,
+};
+template <>
+struct fmt::formatter<RasColorChan> : EnumFormatter<RasColorChan::Zero>
+{
+ static constexpr array_type names = {
+ "Color chan 0", "Color chan 1", nullptr, nullptr,
+ nullptr, "Alpha bump", "Norm alpha bump", "Zero",
+ };
+ formatter() : EnumFormatter(names) {}
};
union TwoTevStageOrders
{
BitField<0, 3, u32> texmap0; // Indirect tex stage texmap
BitField<3, 3, u32> texcoord0;
- BitField<6, 1, u32> enable0; // 1 if should read from texture
- BitField<7, 3, u32> colorchan0; // RAS1_CC_X
+ BitField<6, 1, bool, u32> enable0; // true if should read from texture
+ BitField<7, 3, RasColorChan> colorchan0;
BitField<12, 3, u32> texmap1;
BitField<15, 3, u32> texcoord1;
- BitField<18, 1, u32> enable1; // 1 if should read from texture
- BitField<19, 3, u32> colorchan1; // RAS1_CC_X
-
- BitField<24, 8, u32> rid;
+ BitField<18, 1, bool, u32> enable1; // true if should read from texture
+ BitField<19, 3, RasColorChan> colorchan1;
u32 hex;
u32 getTexMap(int i) const { return i ? texmap1.Value() : texmap0.Value(); }
u32 getTexCoord(int i) const { return i ? texcoord1.Value() : texcoord0.Value(); }
u32 getEnable(int i) const { return i ? enable1.Value() : enable0.Value(); }
- u32 getColorChan(int i) const { return i ? colorchan1.Value() : colorchan0.Value(); }
+ RasColorChan getColorChan(int i) const { return i ? colorchan1.Value() : colorchan0.Value(); }
};
union TEXSCALE
{
- struct
- {
- u32 ss0 : 4; // Indirect tex stage 0, 2^(-ss0)
- u32 ts0 : 4; // Indirect tex stage 0
- u32 ss1 : 4; // Indirect tex stage 1
- u32 ts1 : 4; // Indirect tex stage 1
- u32 pad : 8;
- u32 rid : 8;
- };
+ BitField<0, 4, u32> ss0; // Indirect tex stage 0, 2^(-ss0)
+ BitField<4, 4, u32> ts0; // Indirect tex stage 0
+ BitField<8, 4, u32> ss1; // Indirect tex stage 1
+ BitField<12, 4, u32> ts1; // Indirect tex stage 1
u32 hex;
};
union RAS1_IREF
{
- struct
- {
- u32 bi0 : 3; // Indirect tex stage 0 ntexmap
- u32 bc0 : 3; // Indirect tex stage 0 ntexcoord
- u32 bi1 : 3;
- u32 bc1 : 3;
- u32 bi2 : 3;
- u32 bc3 : 3;
- u32 bi4 : 3;
- u32 bc4 : 3;
- u32 rid : 8;
- };
+ BitField<0, 3, u32> bi0; // Indirect tex stage 0 ntexmap
+ BitField<3, 3, u32> bc0; // Indirect tex stage 0 ntexmap
+ BitField<6, 3, u32> bi1;
+ BitField<9, 3, u32> bc1;
+ BitField<12, 3, u32> bi2;
+ BitField<15, 3, u32> bc3; // Typo?
+ BitField<18, 3, u32> bi4;
+ BitField<21, 3, u32> bc4;
u32 hex;
u32 getTexCoord(int i) const { return (hex >> (6 * i + 3)) & 7; }
@@ -433,88 +512,118 @@ union RAS1_IREF
};
// Texture structs
+enum class WrapMode : u32
+{
+ Clamp = 0,
+ Repeat = 1,
+ Mirror = 2,
+};
+template <>
+struct fmt::formatter<WrapMode> : EnumFormatter<WrapMode::Mirror>
+{
+ formatter() : EnumFormatter({"Clamp", "Repeat", "Mirror"}) {}
+};
-union TexMode0
+enum class MipMode : u32
{
- enum TextureFilter : u32
- {
- TEXF_NONE = 0,
- TEXF_POINT = 1,
- TEXF_LINEAR = 2
- };
+ None = 0,
+ Point = 1,
+ Linear = 2,
+};
+template <>
+struct fmt::formatter<MipMode> : EnumFormatter<MipMode::Linear>
+{
+ formatter() : EnumFormatter({"None", "Mip point", "Mip linear"}) {}
+};
- struct
- {
- u32 wrap_s : 2;
- u32 wrap_t : 2;
- u32 mag_filter : 1;
- u32 min_filter : 3;
- u32 diag_lod : 1;
- s32 lod_bias : 8;
- u32 pad0 : 2;
- u32 max_aniso : 2;
- u32 lod_clamp : 1;
- };
+enum class FilterMode : u32
+{
+ Near = 0,
+ Linear = 1,
+};
+template <>
+struct fmt::formatter<FilterMode> : EnumFormatter<FilterMode::Linear>
+{
+ formatter() : EnumFormatter({"Near", "Linear"}) {}
+};
+
+enum class LODType : u32
+{
+ Edge = 0,
+ Diagonal = 1,
+};
+template <>
+struct fmt::formatter<LODType> : EnumFormatter<LODType::Diagonal>
+{
+ formatter() : EnumFormatter({"Edge LOD", "Diagonal LOD"}) {}
+};
+
+enum class MaxAnsio
+{
+ One = 0,
+ Two = 1,
+ Four = 2,
+};
+template <>
+struct fmt::formatter<MaxAnsio> : EnumFormatter<MaxAnsio::Four>
+{
+ formatter() : EnumFormatter({"1", "2 (requires edge LOD)", "4 (requires edge LOD)"}) {}
+};
+
+union TexMode0
+{
+ BitField<0, 2, WrapMode> wrap_s;
+ BitField<2, 2, WrapMode> wrap_t;
+ BitField<4, 1, FilterMode> mag_filter;
+ BitField<5, 2, MipMode> mipmap_filter;
+ BitField<7, 1, FilterMode> min_filter;
+ BitField<8, 1, LODType> diag_lod;
+ BitField<9, 8, s32> lod_bias;
+ BitField<19, 2, MaxAnsio> max_aniso;
+ BitField<21, 1, bool, u32> lod_clamp;
u32 hex;
};
union TexMode1
{
- struct
- {
- u32 min_lod : 8;
- u32 max_lod : 8;
- };
+ BitField<0, 8, u32> min_lod;
+ BitField<8, 8, u32> max_lod;
u32 hex;
};
union TexImage0
{
- struct
- {
- u32 width : 10; // Actually w-1
- u32 height : 10; // Actually h-1
- u32 format : 4;
- };
+ BitField<0, 10, u32> width; // Actually w-1
+ BitField<10, 10, u32> height; // Actually h-1
+ BitField<20, 4, TextureFormat> format;
u32 hex;
};
union TexImage1
{
- struct
- {
- u32 tmem_even : 15; // TMEM line index for even LODs
- u32 cache_width : 3;
- u32 cache_height : 3;
- u32 image_type : 1; // 1 if this texture is managed manually (0 means we'll autofetch the
- // texture data whenever it changes)
- };
+ BitField<0, 15, u32> tmem_even; // TMEM line index for even LODs
+ BitField<15, 3, u32> cache_width;
+ BitField<18, 3, u32> cache_height;
+ // true if this texture is managed manually (false means we'll
+ // autofetch the texture data whenever it changes)
+ BitField<21, 1, bool, u32> cache_manually_managed;
u32 hex;
};
union TexImage2
{
- struct
- {
- u32 tmem_odd : 15; // tmem line index for odd LODs
- u32 cache_width : 3;
- u32 cache_height : 3;
- };
+ BitField<0, 15, u32> tmem_odd; // tmem line index for odd LODs
+ BitField<15, 3, u32> cache_width;
+ BitField<18, 3, u32> cache_height;
u32 hex;
};
union TexImage3
{
- struct
- {
- u32 image_base : 24; // address in memory >> 5 (was 20 for GC)
- };
+ BitField<0, 24, u32> image_base; // address in memory >> 5 (was 20 for GC)
u32 hex;
};
union TexTLUT
{
- struct
- {
- u32 tmem_offset : 10;
- u32 tlut_format : 2;
- };
+ BitField<0, 10, u32> tmem_offset;
+ BitField<10, 2, TLUTFormat> tlut_format;
u32 hex;
};
@@ -526,8 +635,8 @@ union ZTex1
union ZTex2
{
- BitField<0, 2, u32> type; // TEV_Z_TYPE_X
- BitField<2, 2, u32> op; // GXZTexOp
+ BitField<0, 2, ZTexFormat> type;
+ BitField<2, 2, ZTexOp> op;
u32 hex;
};
@@ -544,109 +653,167 @@ struct FourTexUnits
};
// Geometry/other structs
-
-union GenMode
+enum class CullMode : u32
{
- enum CullMode : u32
- {
- CULL_NONE = 0,
- CULL_BACK = 1, // cull back-facing primitives
- CULL_FRONT = 2, // cull front-facing primitives
- CULL_ALL = 3, // cull all primitives
+ None = 0,
+ Back = 1, // cull back-facing primitives
+ Front = 2, // cull front-facing primitives
+ All = 3, // cull all primitives
+};
+template <>
+struct fmt::formatter<CullMode> : EnumFormatter<CullMode::All>
+{
+ static constexpr array_type names = {
+ "None",
+ "Back-facing primitives only",
+ "Front-facing primitives only",
+ "All primitives",
};
+ formatter() : EnumFormatter(names) {}
+};
+union GenMode
+{
BitField<0, 4, u32> numtexgens;
BitField<4, 3, u32> numcolchans;
- // 1 bit unused?
- BitField<8, 1, u32> flat_shading; // unconfirmed
- BitField<9, 1, u32> multisampling;
+ BitField<7, 1, u32> unused; // 1 bit unused?
+ BitField<8, 1, bool, u32> flat_shading; // unconfirmed
+ BitField<9, 1, bool, u32> multisampling;
BitField<10, 4, u32> numtevstages;
BitField<14, 2, CullMode> cullmode;
BitField<16, 3, u32> numindstages;
- BitField<19, 1, u32> zfreeze;
+ BitField<19, 1, bool, u32> zfreeze;
u32 hex;
};
+enum class AspectRatioAdjustment
+{
+ DontAdjust = 0,
+ Adjust = 1,
+};
+template <>
+struct fmt::formatter<AspectRatioAdjustment> : EnumFormatter<AspectRatioAdjustment::Adjust>
+{
+ formatter() : EnumFormatter({"Don't adjust", "Adjust"}) {}
+};
+
union LPSize
{
- struct
- {
- u32 linesize : 8; // in 1/6th pixels
- u32 pointsize : 8; // in 1/6th pixels
- u32 lineoff : 3;
- u32 pointoff : 3;
- u32 lineaspect : 1; // interlacing: adjust for pixels having AR of 1/2
- u32 padding : 1;
- };
+ BitField<0, 8, u32> linesize; // in 1/6th pixels
+ BitField<8, 8, u32> pointsize; // in 1/6th pixels
+ BitField<16, 3, u32> lineoff;
+ BitField<19, 3, u32> pointoff;
+ // interlacing: adjust for pixels having AR of 1/2
+ BitField<22, 1, AspectRatioAdjustment> adjust_for_aspect_ratio;
u32 hex;
};
union X12Y12
{
- struct
- {
- u32 y : 12;
- u32 x : 12;
- };
+ BitField<0, 12, u32> y;
+ BitField<12, 12, u32> x;
u32 hex;
};
union X10Y10
{
- struct
- {
- u32 x : 10;
- u32 y : 10;
- };
+ BitField<0, 10, u32> x;
+ BitField<10, 10, u32> y;
u32 hex;
};
// Framebuffer/pixel stuff (incl fog)
+enum class SrcBlendFactor : u32
+{
+ Zero = 0,
+ One = 1,
+ DstClr = 2,
+ InvDstClr = 3,
+ SrcAlpha = 4,
+ InvSrcAlpha = 5,
+ DstAlpha = 6,
+ InvDstAlpha = 7
+};
+template <>
+struct fmt::formatter<SrcBlendFactor> : EnumFormatter<SrcBlendFactor::InvDstAlpha>
+{
+ static constexpr array_type names = {"0", "1", "dst_color", "1-dst_color",
+ "src_alpha", "1-src_alpha", "dst_alpha", "1-dst_alpha"};
+ formatter() : EnumFormatter(names) {}
+};
-union BlendMode
+enum class DstBlendFactor : u32
{
- enum BlendFactor : u32
- {
- ZERO = 0,
- ONE = 1,
- SRCCLR = 2, // for dst factor
- INVSRCCLR = 3, // for dst factor
- DSTCLR = SRCCLR, // for src factor
- INVDSTCLR = INVSRCCLR, // for src factor
- SRCALPHA = 4,
- INVSRCALPHA = 5,
- DSTALPHA = 6,
- INVDSTALPHA = 7
- };
+ Zero = 0,
+ One = 1,
+ SrcClr = 2,
+ InvSrcClr = 3,
+ SrcAlpha = 4,
+ InvSrcAlpha = 5,
+ DstAlpha = 6,
+ InvDstAlpha = 7
+};
+template <>
+struct fmt::formatter<DstBlendFactor> : EnumFormatter<DstBlendFactor::InvDstAlpha>
+{
+ static constexpr array_type names = {"0", "1", "src_color", "1-src_color",
+ "src_alpha", "1-src_alpha", "dst_alpha", "1-dst_alpha"};
+ formatter() : EnumFormatter(names) {}
+};
- enum LogicOp : u32
- {
- CLEAR = 0,
- AND = 1,
- AND_REVERSE = 2,
- COPY = 3,
- AND_INVERTED = 4,
- NOOP = 5,
- XOR = 6,
- OR = 7,
- NOR = 8,
- EQUIV = 9,
- INVERT = 10,
- OR_REVERSE = 11,
- COPY_INVERTED = 12,
- OR_INVERTED = 13,
- NAND = 14,
- SET = 15
+enum class LogicOp : u32
+{
+ 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
+};
+template <>
+struct fmt::formatter<LogicOp> : EnumFormatter<LogicOp::Set>
+{
+ static constexpr array_type names = {
+ "Clear (0)",
+ "And (src & dst)",
+ "And Reverse (src & ~dst)",
+ "Copy (src)",
+ "And Inverted (~src & dst)",
+ "NoOp (dst)",
+ "Xor (src ^ dst)",
+ "Or (src | dst)",
+ "Nor (~(src | dst))",
+ "Equiv (~(src ^ dst))",
+ "Invert (~dst)",
+ "Or Reverse (src | ~dst)",
+ "Copy Inverted (~src)",
+ "Or Inverted (~src | dst)",
+ "Nand (~(src & dst))",
+ "Set (1)",
};
+ formatter() : EnumFormatter(names) {}
+};
- BitField<0, 1, u32> blendenable;
- BitField<1, 1, u32> logicopenable;
- BitField<2, 1, u32> dither;
- BitField<3, 1, u32> colorupdate;
- BitField<4, 1, u32> alphaupdate;
- BitField<5, 3, BlendFactor> dstfactor;
- BitField<8, 3, BlendFactor> srcfactor;
- BitField<11, 1, u32> subtract;
+union BlendMode
+{
+ BitField<0, 1, bool, u32> blendenable;
+ BitField<1, 1, bool, u32> logicopenable;
+ BitField<2, 1, bool, u32> dither;
+ BitField<3, 1, bool, u32> colorupdate;
+ BitField<4, 1, bool, u32> alphaupdate;
+ BitField<5, 3, DstBlendFactor> dstfactor;
+ BitField<8, 3, SrcBlendFactor> srcfactor;
+ BitField<11, 1, bool, u32> subtract;
BitField<12, 4, LogicOp> logicmode;
u32 hex;
@@ -664,14 +831,49 @@ union FogParam0
float FloatValue() const;
};
+enum class FogProjection : u32
+{
+ Perspective = 0,
+ Orthographic = 1,
+};
+template <>
+struct fmt::formatter<FogProjection> : EnumFormatter<FogProjection::Orthographic>
+{
+ formatter() : EnumFormatter({"Perspective", "Orthographic"}) {}
+};
+
+enum class FogType : u32
+{
+ Off = 0,
+ Linear = 2,
+ Exp = 4,
+ ExpSq = 5,
+ BackwardsExp = 6,
+ BackwardsExpSq = 7,
+};
+template <>
+struct fmt::formatter<FogType> : EnumFormatter<FogType::BackwardsExpSq>
+{
+ static constexpr array_type names = {
+ "Off (no fog)",
+ nullptr,
+ "Linear fog",
+ nullptr,
+ "Exponential fog",
+ "Exponential-squared fog",
+ "Backwards exponential fog",
+ "Backwards exponenential-sequared fog",
+ };
+ formatter() : EnumFormatter(names) {}
+};
+
union FogParam3
{
BitField<0, 11, u32> c_mant;
BitField<11, 8, u32> c_exp;
BitField<19, 1, u32> c_sign;
- BitField<20, 1, u32> proj; // 0 - perspective, 1 - orthographic
- BitField<21, 3, u32> fsel; // 0 - off, 2 - linear, 4 - exp, 5 - exp2, 6 -
- // backward exp, 7 - backward exp2
+ BitField<20, 1, FogProjection> proj;
+ BitField<21, 3, FogType> fsel;
u32 hex;
float FloatValue() const;
@@ -681,7 +883,6 @@ union FogRangeKElement
{
BitField<0, 12, u32> HI;
BitField<12, 12, u32> LO;
- BitField<24, 8, u32> regid;
// TODO: Which scaling coefficient should we use here? This is just a guess!
float GetValue(int i) const { return (i ? HI.Value() : LO.Value()) / 256.f; }
@@ -693,8 +894,7 @@ struct FogRangeParams
union RangeBase
{
BitField<0, 10, u32> Center; // viewport center + 342
- BitField<10, 1, u32> Enabled;
- BitField<24, 8, u32> regid;
+ BitField<10, 1, bool, u32> Enabled;
u32 hex;
};
RangeBase Base;
@@ -726,23 +926,30 @@ struct FogParams
float GetC() const;
};
-union ZMode
+enum class CompareMode : u32
{
- enum CompareMode : u32
- {
- NEVER = 0,
- LESS = 1,
- EQUAL = 2,
- LEQUAL = 3,
- GREATER = 4,
- NEQUAL = 5,
- GEQUAL = 6,
- ALWAYS = 7
- };
+ Never = 0,
+ Less = 1,
+ Equal = 2,
+ LEqual = 3,
+ Greater = 4,
+ NEqual = 5,
+ GEqual = 6,
+ Always = 7
+};
+template <>
+struct fmt::formatter<CompareMode> : EnumFormatter<CompareMode::Always>
+{
+ static constexpr array_type names = {"Never", "Less", "Equal", "LEqual",
+ "Greater", "NEqual", "GEqual", "Always"};
+ formatter() : EnumFormatter(names) {}
+};
- BitField<0, 1, u32> testenable;
+union ZMode
+{
+ BitField<0, 1, bool, u32> testenable;
BitField<1, 3, CompareMode> func;
- BitField<4, 1, u32> updateenable;
+ BitField<4, 1, bool, u32> updateenable;
u32 hex;
};
@@ -750,62 +957,84 @@ union ZMode
union ConstantAlpha
{
BitField<0, 8, u32> alpha;
- BitField<8, 1, u32> enable;
+ BitField<8, 1, bool, u32> enable;
u32 hex;
};
union FieldMode
{
- struct
- {
- u32 texLOD : 1; // adjust vert tex LOD computation to account for interlacing
- };
+ // adjust vertex tex LOD computation to account for interlacing
+ BitField<0, 1, AspectRatioAdjustment> texLOD;
u32 hex;
};
+enum class FieldMaskState : u32
+{
+ Skip = 0,
+ Write = 1,
+};
+template <>
+struct fmt::formatter<FieldMaskState> : EnumFormatter<FieldMaskState::Write>
+{
+ formatter() : EnumFormatter({"Skipped", "Written"}) {}
+};
+
union FieldMask
{
- struct
- {
- // If bit is not set, do not write field to EFB
- u32 odd : 1;
- u32 even : 1;
- };
+ // Fields are written to the EFB only if their bit is set to write.
+ BitField<0, 1, FieldMaskState> odd;
+ BitField<1, 1, FieldMaskState> even;
u32 hex;
};
-union PEControl
+enum class PixelFormat : u32
{
- enum PixelFormat : u32
- {
- RGB8_Z24 = 0,
- RGBA6_Z24 = 1,
- RGB565_Z16 = 2,
- Z24 = 3,
- Y8 = 4,
- U8 = 5,
- V8 = 6,
- YUV420 = 7,
- INVALID_FMT = 0xffffffff, // Used by Dolphin to represent a missing value.
- };
+ RGB8_Z24 = 0,
+ RGBA6_Z24 = 1,
+ RGB565_Z16 = 2,
+ Z24 = 3,
+ Y8 = 4,
+ U8 = 5,
+ V8 = 6,
+ YUV420 = 7,
+ INVALID_FMT = 0xffffffff, // Used by Dolphin to represent a missing value.
+};
+template <>
+struct fmt::formatter<PixelFormat> : EnumFormatter<PixelFormat::YUV420>
+{
+ static constexpr array_type names = {"RGB8_Z24", "RGBA6_Z24", "RGB565_Z16", "Z24",
+ "Y8", "U8", "V8", "YUV420"};
+ formatter() : EnumFormatter(names) {}
+};
- enum DepthFormat : u32
- {
- ZLINEAR = 0,
- ZNEAR = 1,
- ZMID = 2,
- ZFAR = 3,
-
- // It seems these Z formats aren't supported/were removed ?
- ZINV_LINEAR = 4,
- ZINV_NEAR = 5,
- ZINV_MID = 6,
- ZINV_FAR = 7
+enum class DepthFormat : u32
+{
+ ZLINEAR = 0,
+ ZNEAR = 1,
+ ZMID = 2,
+ ZFAR = 3,
+
+ // It seems these Z formats aren't supported/were removed ?
+ ZINV_LINEAR = 4,
+ ZINV_NEAR = 5,
+ ZINV_MID = 6,
+ ZINV_FAR = 7
+};
+template <>
+struct fmt::formatter<DepthFormat> : EnumFormatter<DepthFormat::ZINV_FAR>
+{
+ static constexpr array_type names = {
+ "linear", "compressed (near)", "compressed (mid)", "compressed (far)",
+ "inv linear", "compressed (inv near)", "compressed (inv mid)", "compressed (inv far)",
};
+ formatter() : EnumFormatter(names) {}
+};
+union PEControl
+{
BitField<0, 3, PixelFormat> pixel_format;
BitField<3, 3, DepthFormat> zformat;
- BitField<6, 1, u32> early_ztest;
+ BitField<6, 1, bool, u32> early_ztest;
u32 hex;
};
@@ -814,15 +1043,12 @@ union PEControl
union TCInfo
{
- struct
- {
- u32 scale_minus_1 : 16;
- u32 range_bias : 1;
- u32 cylindric_wrap : 1;
- // These bits only have effect in the s field of TCoordInfo
- u32 line_offset : 1;
- u32 point_offset : 1;
- };
+ BitField<0, 16, u32> scale_minus_1;
+ BitField<16, 1, bool, u32> range_bias;
+ BitField<17, 1, bool, u32> cylindric_wrap;
+ // These bits only have effect in the s field of TCoordInfo
+ BitField<18, 1, bool, u32> line_offset;
+ BitField<19, 1, bool, u32> point_offset;
u32 hex;
};
struct TCoordInfo
@@ -831,139 +1057,229 @@ struct TCoordInfo
TCInfo t;
};
-union TevReg
+enum class TevRegType : u32
{
- u64 hex;
-
- // Access to individual registers
- BitField<0, 32, u64> low;
- BitField<32, 32, u64> high;
+ Color = 0,
+ Constant = 1,
+};
+struct TevReg
+{
// TODO: Check if Konst uses all 11 bits or just 8
+ union RA
+ {
+ u32 hex;
- // Low register
- BitField<0, 11, s64> red;
+ BitField<0, 11, s32> red;
+ BitField<12, 11, s32> alpha;
+ BitField<23, 1, TevRegType, u32> type;
+ };
+ union BG
+ {
+ u32 hex;
- BitField<12, 11, s64> alpha;
- BitField<23, 1, u64> type_ra;
+ BitField<0, 11, s32> blue;
+ BitField<12, 11, s32> green;
+ BitField<23, 1, TevRegType, u32> type;
+ };
- // High register
- BitField<32, 11, s64> blue;
+ RA ra;
+ BG bg;
+};
- BitField<44, 11, s64> green;
- BitField<55, 1, u64> type_bg;
+enum class KonstSel : u32
+{
+ V1 = 0,
+ V7_8 = 1,
+ V3_4 = 2,
+ V5_8 = 3,
+ V1_2 = 4,
+ V3_8 = 5,
+ V1_4 = 6,
+ V1_8 = 7,
+ // 8-11 are invalid values that output 0 (8-15 for alpha)
+ K0 = 12, // Color only
+ K1 = 13, // Color only
+ K2 = 14, // Color only
+ K3 = 15, // Color only
+ K0_R = 16,
+ K1_R = 17,
+ K2_R = 18,
+ K3_R = 19,
+ K0_G = 20,
+ K1_G = 21,
+ K2_G = 22,
+ K3_G = 23,
+ K0_B = 24,
+ K1_B = 25,
+ K2_B = 26,
+ K3_B = 27,
+ K0_A = 28,
+ K1_A = 29,
+ K2_A = 30,
+ K3_A = 31,
+};
+template <>
+struct fmt::formatter<KonstSel> : EnumFormatter<KonstSel::K3_A>
+{
+ static constexpr array_type names = {
+ "1",
+ "7/8",
+ "3/4",
+ "5/8",
+ "1/2",
+ "3/8",
+ "1/4",
+ "1/8",
+ nullptr,
+ nullptr,
+ nullptr,
+ nullptr,
+ "Konst 0 RGB (invalid for alpha)",
+ "Konst 1 RGB (invalid for alpha)",
+ "Konst 2 RGB (invalid for alpha)",
+ "Konst 3 RGB (invalid for alpha)",
+ "Konst 0 Red",
+ "Konst 1 Red",
+ "Konst 2 Red",
+ "Konst 3 Red",
+ "Konst 0 Green",
+ "Konst 1 Green",
+ "Konst 2 Green",
+ "Konst 3 Green",
+ "Konst 0 Blue",
+ "Konst 1 Blue",
+ "Konst 2 Blue",
+ "Konst 3 Blue",
+ "Konst 0 Alpha",
+ "Konst 1 Alpha",
+ "Konst 2 Alpha",
+ "Konst 3 Alpha",
+ };
+ formatter() : EnumFormatter(names) {}
};
union TevKSel
{
BitField<0, 2, u32> swap1;
BitField<2, 2, u32> swap2;
- BitField<4, 5, u32> kcsel0;
- BitField<9, 5, u32> kasel0;
- BitField<14, 5, u32> kcsel1;
- BitField<19, 5, u32> kasel1;
+ BitField<4, 5, KonstSel> kcsel0;
+ BitField<9, 5, KonstSel> kasel0;
+ BitField<14, 5, KonstSel> kcsel1;
+ BitField<19, 5, KonstSel> kasel1;
u32 hex;
- u32 getKC(int i) const { return i ? kcsel1.Value() : kcsel0.Value(); }
- u32 getKA(int i) const { return i ? kasel1.Value() : kasel0.Value(); }
+ KonstSel getKC(int i) const { return i ? kcsel1.Value() : kcsel0.Value(); }
+ KonstSel getKA(int i) const { return i ? kasel1.Value() : kasel0.Value(); }
};
-union AlphaTest
+enum class AlphaTestOp : u32
{
- enum CompareMode : u32
- {
- NEVER = 0,
- LESS = 1,
- EQUAL = 2,
- LEQUAL = 3,
- GREATER = 4,
- NEQUAL = 5,
- GEQUAL = 6,
- ALWAYS = 7
- };
+ And = 0,
+ Or = 1,
+ Xor = 2,
+ Xnor = 3
+};
+template <>
+struct fmt::formatter<AlphaTestOp> : EnumFormatter<AlphaTestOp::Xnor>
+{
+ formatter() : EnumFormatter({"And", "Or", "Xor", "Xnor"}) {}
+};
- enum Op : u32
- {
- AND = 0,
- OR = 1,
- XOR = 2,
- XNOR = 3
- };
+enum class AlphaTestResult
+{
+ Undetermined = 0,
+ Fail = 1,
+ Pass = 2,
+};
+union AlphaTest
+{
BitField<0, 8, u32> ref0;
BitField<8, 8, u32> ref1;
BitField<16, 3, CompareMode> comp0;
BitField<19, 3, CompareMode> comp1;
- BitField<22, 2, Op> logic;
+ BitField<22, 2, AlphaTestOp> logic;
u32 hex;
- enum TEST_RESULT
- {
- UNDETERMINED = 0,
- FAIL = 1,
- PASS = 2,
- };
-
- DOLPHIN_FORCE_INLINE TEST_RESULT TestResult() const
+ DOLPHIN_FORCE_INLINE AlphaTestResult TestResult() const
{
switch (logic)
{
- case AND:
- if (comp0 == ALWAYS && comp1 == ALWAYS)
- return PASS;
- if (comp0 == NEVER || comp1 == NEVER)
- return FAIL;
+ case AlphaTestOp::And:
+ if (comp0 == CompareMode::Always && comp1 == CompareMode::Always)
+ return AlphaTestResult::Pass;
+ if (comp0 == CompareMode::Never || comp1 == CompareMode::Never)
+ return AlphaTestResult::Fail;
break;
- case OR:
- if (comp0 == ALWAYS || comp1 == ALWAYS)
- return PASS;
- if (comp0 == NEVER && comp1 == NEVER)
- return FAIL;
+ case AlphaTestOp::Or:
+ if (comp0 == CompareMode::Always || comp1 == CompareMode::Always)
+ return AlphaTestResult::Pass;
+ if (comp0 == CompareMode::Never && comp1 == CompareMode::Never)
+ return AlphaTestResult::Fail;
break;
- case XOR:
- if ((comp0 == ALWAYS && comp1 == NEVER) || (comp0 == NEVER && comp1 == ALWAYS))
- return PASS;
- if ((comp0 == ALWAYS && comp1 == ALWAYS) || (comp0 == NEVER && comp1 == NEVER))
- return FAIL;
+ case AlphaTestOp::Xor:
+ if ((comp0 == CompareMode::Always && comp1 == CompareMode::Never) ||
+ (comp0 == CompareMode::Never && comp1 == CompareMode::Always))
+ return AlphaTestResult::Pass;
+ if ((comp0 == CompareMode::Always && comp1 == CompareMode::Always) ||
+ (comp0 == CompareMode::Never && comp1 == CompareMode::Never))
+ return AlphaTestResult::Fail;
break;
- case XNOR:
- if ((comp0 == ALWAYS && comp1 == NEVER) || (comp0 == NEVER && comp1 == ALWAYS))
- return FAIL;
- if ((comp0 == ALWAYS && comp1 == ALWAYS) || (comp0 == NEVER && comp1 == NEVER))
- return PASS;
+ case AlphaTestOp::Xnor:
+ if ((comp0 == CompareMode::Always && comp1 == CompareMode::Never) ||
+ (comp0 == CompareMode::Never && comp1 == CompareMode::Always))
+ return AlphaTestResult::Fail;
+ if ((comp0 == CompareMode::Always && comp1 == CompareMode::Always) ||
+ (comp0 == CompareMode::Never && comp1 == CompareMode::Never))
+ return AlphaTestResult::Pass;
break;
default:
- return UNDETERMINED;
+ return AlphaTestResult::Undetermined;
}
- return UNDETERMINED;
+ return AlphaTestResult::Undetermined;
}
};
+enum class FrameToField : u32
+{
+ Progressive = 0,
+ InterlacedEven = 2,
+ InterlacedOdd = 3,
+};
+template <>
+struct fmt::formatter<FrameToField> : EnumFormatter<FrameToField::InterlacedOdd>
+{
+ static constexpr array_type names = {"Progressive", nullptr, "Interlaced (even lines)",
+ "Interlaced (odd lines)"};
+ formatter() : EnumFormatter(names) {}
+};
+
union UPE_Copy
{
u32 Hex;
- BitField<0, 1, u32> clamp_top; // if set clamp top
- BitField<1, 1, u32> clamp_bottom; // if set clamp bottom
- BitField<2, 1, u32> yuv; // if set, color conversion from RGB to YUV
+ BitField<0, 1, bool, u32> clamp_top; // if set clamp top
+ BitField<1, 1, bool, u32> clamp_bottom; // if set clamp bottom
+ BitField<2, 1, bool, u32> yuv; // if set, color conversion from RGB to YUV
BitField<3, 4, u32> target_pixel_format; // realformat is (fmt/2)+((fmt&1)*8).... for some reason
// the msb is the lsb (pattern: cycling right shift)
- BitField<7, 2, u32> gamma; // gamma correction.. 0 = 1.0 ; 1 = 1.7 ; 2 = 2.2 ; 3 is reserved
- BitField<9, 1, u32>
- half_scale; // "mipmap" filter... 0 = no filter (scale 1:1) ; 1 = box filter (scale 2:1)
- BitField<10, 1, u32> scale_invert; // if set vertical scaling is on
- BitField<11, 1, u32> clear;
- BitField<12, 2, u32> frame_to_field; // 0 progressive ; 1 is reserved ; 2 = interlaced (even
- // lines) ; 3 = interlaced 1 (odd lines)
- BitField<14, 1, u32> copy_to_xfb;
- BitField<15, 1, u32> intensity_fmt; // if set, is an intensity format (I4,I8,IA4,IA8)
- BitField<16, 1, u32>
- auto_conv; // if 0 automatic color conversion by texture format and pixel type
+ // gamma correction.. 0 = 1.0 ; 1 = 1.7 ; 2 = 2.2 ; 3 is reserved
+ BitField<7, 2, u32> gamma;
+ // "mipmap" filter... false = no filter (scale 1:1) ; true = box filter (scale 2:1)
+ BitField<9, 1, bool, u32> half_scale;
+ BitField<10, 1, bool, u32> scale_invert; // if set vertical scaling is on
+ BitField<11, 1, bool, u32> clear;
+ BitField<12, 2, FrameToField> frame_to_field;
+ BitField<14, 1, bool, u32> copy_to_xfb;
+ BitField<15, 1, bool, u32> intensity_fmt; // if set, is an intensity format (I4,I8,IA4,IA8)
+ // if false automatic color conversion by texture format and pixel type
+ BitField<16, 1, bool, u32> auto_conv;
EFBCopyFormat tp_realFormat() const
{
@@ -1001,12 +1317,9 @@ union CopyFilterCoefficients
union BPU_PreloadTileInfo
{
+ BitField<0, 15, u32> count;
+ BitField<15, 2, u32> type;
u32 hex;
- struct
- {
- u32 count : 15;
- u32 type : 2;
- };
};
struct BPS_TmemConfig
diff --git a/Source/Core/VideoCommon/BPStructs.cpp b/Source/Core/VideoCommon/BPStructs.cpp
index 896aafca30..d0418e9289 100644
--- a/Source/Core/VideoCommon/BPStructs.cpp
+++ b/Source/Core/VideoCommon/BPStructs.cpp
@@ -91,10 +91,9 @@ static void BPWritten(const BPCmd& bp)
{
case BPMEM_GENMODE: // Set the Generation Mode
PRIM_LOG("genmode: texgen={}, col={}, multisampling={}, tev={}, cullmode={}, ind={}, zfeeze={}",
- bpmem.genMode.numtexgens.Value(), bpmem.genMode.numcolchans.Value(),
- bpmem.genMode.multisampling.Value(), bpmem.genMode.numtevstages.Value() + 1,
- static_cast<u32>(bpmem.genMode.cullmode), bpmem.genMode.numindstages.Value(),
- bpmem.genMode.zfreeze.Value());
+ bpmem.genMode.numtexgens, bpmem.genMode.numcolchans, bpmem.genMode.multisampling,
+ bpmem.genMode.numtevstages + 1, bpmem.genMode.cullmode, bpmem.genMode.numindstages,
+ bpmem.genMode.zfreeze);
if (bp.changes)
PixelShaderManager::SetGenModeChanged();
@@ -138,8 +137,8 @@ static void BPWritten(const BPCmd& bp)
GeometryShaderManager::SetLinePtWidthChanged();
return;
case BPMEM_ZMODE: // Depth Control
- PRIM_LOG("zmode: test={}, func={}, upd={}", bpmem.zmode.testenable.Value(),
- bpmem.zmode.func.Value(), bpmem.zmode.updateenable.Value());
+ PRIM_LOG("zmode: test={}, func={}, upd={}", bpmem.zmode.testenable, bpmem.zmode.func,
+ bpmem.zmode.updateenable);
SetDepthMode();
PixelShaderManager::SetZModeControl();
return;
@@ -147,10 +146,9 @@ static void BPWritten(const BPCmd& bp)
if (bp.changes & 0xFFFF)
{
PRIM_LOG("blendmode: en={}, open={}, colupd={}, alphaupd={}, dst={}, src={}, sub={}, mode={}",
- bpmem.blendmode.blendenable.Value(), bpmem.blendmode.logicopenable.Value(),
- bpmem.blendmode.colorupdate.Value(), bpmem.blendmode.alphaupdate.Value(),
- bpmem.blendmode.dstfactor.Value(), bpmem.blendmode.srcfactor.Value(),
- bpmem.blendmode.subtract.Value(), bpmem.blendmode.logicmode.Value());
+ bpmem.blendmode.blendenable, bpmem.blendmode.logicopenable,
+ bpmem.blendmode.colorupdate, bpmem.blendmode.alphaupdate, bpmem.blendmode.dstfactor,
+ bpmem.blendmode.srcfactor, bpmem.blendmode.subtract, bpmem.blendmode.logicmode);
SetBlendMode();
@@ -158,8 +156,7 @@ static void BPWritten(const BPCmd& bp)
}
return;
case BPMEM_CONSTANTALPHA: // Set Destination Alpha
- PRIM_LOG("constalpha: alp={}, en={}", bpmem.dstalpha.alpha.Value(),
- bpmem.dstalpha.enable.Value());
+ PRIM_LOG("constalpha: alp={}, en={}", bpmem.dstalpha.alpha, bpmem.dstalpha.enable);
if (bp.changes)
{
PixelShaderManager::SetAlpha();
@@ -264,14 +261,14 @@ static void BPWritten(const BPCmd& bp)
const UPE_Copy PE_copy = bpmem.triggerEFBCopy;
if (PE_copy.copy_to_xfb == 0)
{
- // bpmem.zcontrol.pixel_format to PEControl::Z24 is when the game wants to copy from ZBuffer
+ // bpmem.zcontrol.pixel_format to PixelFormat::Z24 is when the game wants to copy from ZBuffer
// (Zbuffer uses 24-bit Format)
static constexpr CopyFilterCoefficients::Values filter_coefficients = {
{0, 0, 21, 22, 21, 0, 0}};
- bool is_depth_copy = bpmem.zcontrol.pixel_format == PEControl::Z24;
+ bool is_depth_copy = bpmem.zcontrol.pixel_format == PixelFormat::Z24;
g_texture_cache->CopyRenderTargetToTexture(
destAddr, PE_copy.tp_realFormat(), copy_width, copy_height, destStride, is_depth_copy,
- srcRect, !!PE_copy.intensity_fmt, !!PE_copy.half_scale, 1.0f, 1.0f,
+ srcRect, PE_copy.intensity_fmt, PE_copy.half_scale, 1.0f, 1.0f,
bpmem.triggerEFBCopy.clamp_top, bpmem.triggerEFBCopy.clamp_bottom, filter_coefficients);
}
else
@@ -297,7 +294,7 @@ static void BPWritten(const BPCmd& bp)
destAddr, srcRect.left, srcRect.top, srcRect.right, srcRect.bottom,
bpmem.copyTexSrcWH.x + 1, destStride, height, yScale);
- bool is_depth_copy = bpmem.zcontrol.pixel_format == PEControl::Z24;
+ bool is_depth_copy = bpmem.zcontrol.pixel_format == PixelFormat::Z24;
g_texture_cache->CopyRenderTargetToTexture(
destAddr, EFBCopyFormat::XFB, copy_width, height, destStride, is_depth_copy, srcRect,
false, false, yScale, s_gammaLUT[PE_copy.gamma], bpmem.triggerEFBCopy.clamp_top,
@@ -370,10 +367,9 @@ static void BPWritten(const BPCmd& bp)
PixelShaderManager::SetFogColorChanged();
return;
case BPMEM_ALPHACOMPARE: // Compare Alpha Values
- PRIM_LOG("alphacmp: ref0={}, ref1={}, comp0={}, comp1={}, logic={}",
- bpmem.alpha_test.ref0.Value(), bpmem.alpha_test.ref1.Value(),
- static_cast<int>(bpmem.alpha_test.comp0), static_cast<int>(bpmem.alpha_test.comp1),
- static_cast<int>(bpmem.alpha_test.logic));
+ PRIM_LOG("alphacmp: ref0={}, ref1={}, comp0={}, comp1={}, logic={}", bpmem.alpha_test.ref0,
+ bpmem.alpha_test.ref1, bpmem.alpha_test.comp0, bpmem.alpha_test.comp1,
+ bpmem.alpha_test.logic);
if (bp.changes & 0xFFFF)
PixelShaderManager::SetAlpha();
if (bp.changes)
@@ -383,7 +379,7 @@ static void BPWritten(const BPCmd& bp)
}
return;
case BPMEM_BIAS: // BIAS
- PRIM_LOG("ztex bias={:#x}", bpmem.ztex1.bias.Value());
+ PRIM_LOG("ztex bias={:#x}", bpmem.ztex1.bias);
if (bp.changes)
PixelShaderManager::SetZTextureBias();
return;
@@ -393,11 +389,7 @@ static void BPWritten(const BPCmd& bp)
PixelShaderManager::SetZTextureTypeChanged();
if (bp.changes & 12)
PixelShaderManager::SetZTextureOpChanged();
-#if defined(_DEBUG) || defined(DEBUGFAST)
- static constexpr std::string_view pzop[] = {"DISABLE", "ADD", "REPLACE", "?"};
- static constexpr std::string_view pztype[] = {"Z8", "Z16", "Z24", "?"};
- PRIM_LOG("ztex op={}, type={}", pzop[bpmem.ztex2.op], pztype[bpmem.ztex2.type]);
-#endif
+ PRIM_LOG("ztex op={}, type={}", bpmem.ztex2.op, bpmem.ztex2.type);
}
return;
// ----------------------------------
@@ -588,15 +580,15 @@ static void BPWritten(const BPCmd& bp)
case BPMEM_TEV_COLOR_RA + 6:
{
int num = (bp.address >> 1) & 0x3;
- if (bpmem.tevregs[num].type_ra)
+ if (bpmem.tevregs[num].ra.type == TevRegType::Constant)
{
- PixelShaderManager::SetTevKonstColor(num, 0, (s32)bpmem.tevregs[num].red);
- PixelShaderManager::SetTevKonstColor(num, 3, (s32)bpmem.tevregs[num].alpha);
+ PixelShaderManager::SetTevKonstColor(num, 0, bpmem.tevregs[num].ra.red);
+ PixelShaderManager::SetTevKonstColor(num, 3, bpmem.tevregs[num].ra.alpha);
}
else
{
- PixelShaderManager::SetTevColor(num, 0, (s32)bpmem.tevregs[num].red);
- PixelShaderManager::SetTevColor(num, 3, (s32)bpmem.tevregs[num].alpha);
+ PixelShaderManager::SetTevColor(num, 0, bpmem.tevregs[num].ra.red);
+ PixelShaderManager::SetTevColor(num, 3, bpmem.tevregs[num].ra.alpha);
}
return;
}
@@ -607,15 +599,15 @@ static void BPWritten(const BPCmd& bp)
case BPMEM_TEV_COLOR_BG + 6:
{
int num = (bp.address >> 1) & 0x3;
- if (bpmem.tevregs[num].type_bg)
+ if (bpmem.tevregs[num].bg.type == TevRegType::Constant)
{
- PixelShaderManager::SetTevKonstColor(num, 1, (s32)bpmem.tevregs[num].green);
- PixelShaderManager::SetTevKonstColor(num, 2, (s32)bpmem.tevregs[num].blue);
+ PixelShaderManager::SetTevKonstColor(num, 1, bpmem.tevregs[num].bg.green);
+ PixelShaderManager::SetTevKonstColor(num, 2, bpmem.tevregs[num].bg.blue);
}
else
{
- PixelShaderManager::SetTevColor(num, 1, (s32)bpmem.tevregs[num].green);
- PixelShaderManager::SetTevColor(num, 2, (s32)bpmem.tevregs[num].blue);
+ PixelShaderManager::SetTevColor(num, 1, bpmem.tevregs[num].bg.green);
+ PixelShaderManager::SetTevColor(num, 2, bpmem.tevregs[num].bg.blue);
}
return;
}
@@ -915,26 +907,18 @@ void GetBPRegInfo(const u8* data, std::string* name, std::string* desc)
SetRegName(BPMEM_BLENDMODE);
BlendMode mode;
mode.hex = cmddata;
- const char* dstfactors[] = {"0", "1", "src_color", "1-src_color",
- "src_alpha", "1-src_alpha", "dst_alpha", "1-dst_alpha"};
- const char* srcfactors[] = {"0", "1", "dst_color", "1-dst_color",
- "src_alpha", "1-src_alpha", "dst_alpha", "1-dst_alpha"};
- const char* logicmodes[] = {"0", "s & d", "s & ~d", "s", "~s & d", "d",
- "s ^ d", "s | d", "~(s | d)", "~(s ^ d)", "~d", "s | ~d",
- "~s", "~s | d", "~(s & d)", "1"};
- *desc =
- fmt::format("Enable: {}\n"
- "Logic ops: {}\n"
- "Dither: {}\n"
- "Color write: {}\n"
- "Alpha write: {}\n"
- "Dest factor: {}\n"
- "Source factor: {}\n"
- "Subtract: {}\n"
- "Logic mode: {}\n",
- no_yes[mode.blendenable], no_yes[mode.logicopenable], no_yes[mode.dither],
- no_yes[mode.colorupdate], no_yes[mode.alphaupdate], dstfactors[mode.dstfactor],
- srcfactors[mode.srcfactor], no_yes[mode.subtract], logicmodes[mode.logicmode]);
+ *desc = fmt::format("Enable: {}\n"
+ "Logic ops: {}\n"
+ "Dither: {}\n"
+ "Color write: {}\n"
+ "Alpha write: {}\n"
+ "Dest factor: {}\n"
+ "Source factor: {}\n"
+ "Subtract: {}\n"
+ "Logic mode: {}\n",
+ no_yes[mode.blendenable], no_yes[mode.logicopenable], no_yes[mode.dither],
+ no_yes[mode.colorupdate], no_yes[mode.alphaupdate], mode.dstfactor,
+ mode.srcfactor, no_yes[mode.subtract], mode.logicmode);
}
break;
@@ -948,16 +932,10 @@ void GetBPRegInfo(const u8* data, std::string* name, std::string* desc)
SetRegName(BPMEM_ZCOMPARE);
PEControl config;
config.hex = cmddata;
- const char* pixel_formats[] = {"RGB8_Z24", "RGBA6_Z24", "RGB565_Z16", "Z24",
- "Y8", "U8", "V8", "YUV420"};
- const char* zformats[] = {
- "linear", "compressed (near)", "compressed (mid)", "compressed (far)",
- "inv linear", "compressed (inv near)", "compressed (inv mid)", "compressed (inv far)"};
*desc = fmt::format("EFB pixel format: {}\n"
"Depth format: {}\n"
"Early depth test: {}\n",
- pixel_formats[config.pixel_format], zformats[config.zformat],
- no_yes[config.early_ztest]);
+ config.pixel_format, config.zformat, no_yes[config.early_ztest]);
}
break;
@@ -1048,7 +1026,7 @@ void GetBPRegInfo(const u8* data, std::string* name, std::string* desc)
"Mipmap filter: {}\n"
"Vertical scaling: {}\n"
"Clear: {}\n"
- "Frame to field: 0x{:01X}\n"
+ "Frame to field: {}\n"
"Copy to XFB: {}\n"
"Intensity format: {}\n"
"Automatic color conversion: {}",
@@ -1059,9 +1037,8 @@ void GetBPRegInfo(const u8* data, std::string* name, std::string* desc)
(copy.gamma == 0) ?
"1.0" :
(copy.gamma == 1) ? "1.7" : (copy.gamma == 2) ? "2.2" : "Invalid value 0x3?",
- no_yes[copy.half_scale], no_yes[copy.scale_invert], no_yes[copy.clear],
- static_cast<u32>(copy.frame_to_field), no_yes[copy.copy_to_xfb], no_yes[copy.intensity_fmt],
- no_yes[copy.auto_conv]);
+ no_yes[copy.half_scale], no_yes[copy.scale_invert], no_yes[copy.clear], copy.frame_to_field,
+ no_yes[copy.copy_to_xfb], no_yes[copy.intensity_fmt], no_yes[copy.auto_conv]);
}
break;
@@ -1183,8 +1160,8 @@ void GetBPRegInfo(const u8* data, std::string* name, std::string* desc)
*desc = fmt::format("Texture Unit: {}\n"
"Width: {}\n"
"Height: {}\n"
- "Format: {:x}\n",
- texnum, u32(teximg.width) + 1, u32(teximg.height) + 1, u32(teximg.format));
+ "Format: {}\n",
+ texnum, u32(teximg.width) + 1, u32(teximg.height) + 1, teximg.format);
}
break;
@@ -1208,7 +1185,7 @@ void GetBPRegInfo(const u8* data, std::string* name, std::string* desc)
"Even TMEM Height: {}\n"
"Cache is manually managed: {}\n",
texnum, u32(teximg.tmem_even), u32(teximg.cache_width),
- u32(teximg.cache_height), no_yes[teximg.image_type]);
+ u32(teximg.cache_height), no_yes[teximg.cache_manually_managed]);
}
break;
@@ -1285,14 +1262,6 @@ void GetBPRegInfo(const u8* data, std::string* name, std::string* desc)
SetRegName(BPMEM_TEV_COLOR_ENV);
TevStageCombiner::ColorCombiner cc;
cc.hex = cmddata;
- const char* tevin[] = {
- "prev.rgb", "prev.aaa", "c0.rgb", "c0.aaa", "c1.rgb", "c1.aaa", "c2.rgb", "c2.aaa",
- "tex.rgb", "tex.aaa", "ras.rgb", "ras.aaa", "ONE", "HALF", "konst.rgb", "ZERO",
- };
- const char* tevbias[] = {"0", "+0.5", "-0.5", "compare"};
- const char* tevop[] = {"add", "sub"};
- const char* tevscale[] = {"1", "2", "4", "0.5"};
- const char* tevout[] = {"prev.rgb", "c0.rgb", "c1.rgb", "c2.rgb"};
*desc = fmt::format("Tev stage: {}\n"
"a: {}\n"
"b: {}\n"
@@ -1303,9 +1272,8 @@ void GetBPRegInfo(const u8* data, std::string* name, std::string* desc)
"Clamp: {}\n"
"Scale factor: {}\n"
"Dest: {}\n",
- (data[0] - BPMEM_TEV_COLOR_ENV) / 2, tevin[cc.a], tevin[cc.b], tevin[cc.c],
- tevin[cc.d], tevbias[cc.bias], tevop[cc.op], no_yes[cc.clamp],
- tevscale[cc.shift], tevout[cc.dest]);
+ (data[0] - BPMEM_TEV_COLOR_ENV) / 2, cc.a, cc.b, cc.c, cc.d, cc.bias, cc.op,
+ no_yes[cc.clamp], cc.scale, cc.dest);
break;
}
@@ -1329,13 +1297,6 @@ void GetBPRegInfo(const u8* data, std::string* name, std::string* desc)
SetRegName(BPMEM_TEV_ALPHA_ENV);
TevStageCombiner::AlphaCombiner ac;
ac.hex = cmddata;
- const char* tevin[] = {
- "prev", "c0", "c1", "c2", "tex", "ras", "konst", "ZERO",
- };
- const char* tevbias[] = {"0", "+0.5", "-0.5", "compare"};
- const char* tevop[] = {"add", "sub"};
- const char* tevscale[] = {"1", "2", "4", "0.5"};
- const char* tevout[] = {"prev", "c0", "c1", "c2"};
*desc = fmt::format("Tev stage: {}\n"
"a: {}\n"
"b: {}\n"
@@ -1348,9 +1309,8 @@ void GetBPRegInfo(const u8* data, std::string* name, std::string* desc)
"Dest: {}\n"
"Ras sel: {}\n"
"Tex sel: {}\n",
- (data[0] - BPMEM_TEV_ALPHA_ENV) / 2, tevin[ac.a], tevin[ac.b], tevin[ac.c],
- tevin[ac.d], tevbias[ac.bias], tevop[ac.op], no_yes[ac.clamp],
- tevscale[ac.shift], tevout[ac.dest], ac.rswap.Value(), ac.tswap.Value());
+ (data[0] - BPMEM_TEV_ALPHA_ENV) / 2, ac.a, ac.b, ac.c, ac.d, ac.bias, ac.op,
+ no_yes[ac.clamp], ac.scale, ac.dest, ac.rswap.Value(), ac.tswap.Value());
break;
}
@@ -1410,14 +1370,10 @@ void GetBPRegInfo(const u8* data, std::string* name, std::string* desc)
SetRegName(BPMEM_ALPHACOMPARE);
AlphaTest test;
test.hex = cmddata;
- const char* functions[] = {"NEVER", "LESS", "EQUAL", "LEQUAL",
- "GREATER", "NEQUAL", "GEQUAL", "ALWAYS"};
- const char* logic[] = {"AND", "OR", "XOR", "XNOR"};
*desc = fmt::format("Test 1: {} (ref: 0x{:02x})\n"
"Test 2: {} (ref: 0x{:02x})\n"
"Logic: {}\n",
- functions[test.comp0], test.ref0.Value(), functions[test.comp1],
- test.ref1.Value(), logic[test.logic]);
+ test.comp0, test.ref0.Value(), test.comp1, test.ref1.Value(), test.logic);
break;
}
diff --git a/Source/Core/VideoCommon/ConstantManager.h b/Source/Core/VideoCommon/ConstantManager.h
index 1ad385b0ee..ad21821052 100644
--- a/Source/Core/VideoCommon/ConstantManager.h
+++ b/Source/Core/VideoCommon/ConstantManager.h
@@ -13,6 +13,9 @@ using float4 = std::array<float, 4>;
using uint4 = std::array<u32, 4>;
using int4 = std::array<s32, 4>;
+enum class SrcBlendFactor : u32;
+enum class DstBlendFactor : u32;
+
struct PixelShaderConstants
{
std::array<int4, 4> colors;
@@ -45,10 +48,10 @@ struct PixelShaderConstants
std::array<int4, 32> konst; // .rgba
// The following are used in ubershaders when using shader_framebuffer_fetch blending
u32 blend_enable;
- u32 blend_src_factor;
- u32 blend_src_factor_alpha;
- u32 blend_dst_factor;
- u32 blend_dst_factor_alpha;
+ SrcBlendFactor blend_src_factor;
+ SrcBlendFactor blend_src_factor_alpha;
+ DstBlendFactor blend_dst_factor;
+ DstBlendFactor blend_dst_factor_alpha;
u32 blend_subtract;
u32 blend_subtract_alpha;
};
diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp
index fe5fcd1190..b4e99cd3c6 100644
--- a/Source/Core/VideoCommon/PixelShaderGen.cpp
+++ b/Source/Core/VideoCommon/PixelShaderGen.cpp
@@ -174,14 +174,14 @@ PixelShaderUid GetPixelShaderUid()
pixel_shader_uid_data* const uid_data = out.GetUidData();
uid_data->useDstAlpha = bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate &&
- bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24;
+ bpmem.zcontrol.pixel_format == PixelFormat::RGBA6_Z24;
uid_data->genMode_numindstages = bpmem.genMode.numindstages;
uid_data->genMode_numtevstages = bpmem.genMode.numtevstages;
uid_data->genMode_numtexgens = bpmem.genMode.numtexgens;
uid_data->bounding_box = g_ActiveConfig.bBBoxEnable && BoundingBox::IsEnabled();
uid_data->rgba6_format =
- bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24 && !g_ActiveConfig.bForceTrueColor;
+ bpmem.zcontrol.pixel_format == PixelFormat::RGBA6_Z24 && !g_ActiveConfig.bForceTrueColor;
uid_data->dither = bpmem.blendmode.dither && uid_data->rgba6_format;
uid_data->uint_output = bpmem.blendmode.UseLogicOp();
@@ -189,12 +189,13 @@ PixelShaderUid GetPixelShaderUid()
const bool forced_early_z =
bpmem.UseEarlyDepthTest() &&
- (g_ActiveConfig.bFastDepthCalc || bpmem.alpha_test.TestResult() == AlphaTest::UNDETERMINED)
+ (g_ActiveConfig.bFastDepthCalc ||
+ bpmem.alpha_test.TestResult() == AlphaTestResult::Undetermined)
// We can't allow early_ztest for zfreeze because depth is overridden per-pixel.
// This means it's impossible for zcomploc to be emulated on a zfrozen polygon.
&& !(bpmem.zmode.testenable && bpmem.genMode.zfreeze);
const bool per_pixel_depth =
- (bpmem.ztex2.op != ZTEXTURE_DISABLE && bpmem.UseLateDepthTest()) ||
+ (bpmem.ztex2.op != ZTexOp::Disabled && bpmem.UseLateDepthTest()) ||
(!g_ActiveConfig.bFastDepthCalc && bpmem.zmode.testenable && !forced_early_z) ||
(bpmem.zmode.testenable && bpmem.genMode.zfreeze);
@@ -253,10 +254,12 @@ PixelShaderUid GetPixelShaderUid()
uid_data->stagehash[n].cc = cc.hex & 0xFFFFFF;
uid_data->stagehash[n].ac = ac.hex & 0xFFFFF0; // Storing rswap and tswap later
- if (cc.a == TEVCOLORARG_RASA || cc.a == TEVCOLORARG_RASC || cc.b == TEVCOLORARG_RASA ||
- cc.b == TEVCOLORARG_RASC || cc.c == TEVCOLORARG_RASA || cc.c == TEVCOLORARG_RASC ||
- cc.d == TEVCOLORARG_RASA || cc.d == TEVCOLORARG_RASC || ac.a == TEVALPHAARG_RASA ||
- ac.b == TEVALPHAARG_RASA || ac.c == TEVALPHAARG_RASA || ac.d == TEVALPHAARG_RASA)
+ if (cc.a == TevColorArg::RasAlpha || cc.a == TevColorArg::RasColor ||
+ cc.b == TevColorArg::RasAlpha || cc.b == TevColorArg::RasColor ||
+ cc.c == TevColorArg::RasAlpha || cc.c == TevColorArg::RasColor ||
+ cc.d == TevColorArg::RasAlpha || cc.d == TevColorArg::RasColor ||
+ ac.a == TevAlphaArg::RasAlpha || ac.b == TevAlphaArg::RasAlpha ||
+ ac.c == TevAlphaArg::RasAlpha || ac.d == TevAlphaArg::RasAlpha)
{
const int i = bpmem.combiners[n].alphaC.rswap;
uid_data->stagehash[n].tevksel_swap1a = bpmem.tevksel[i * 2].swap1;
@@ -277,9 +280,9 @@ PixelShaderUid GetPixelShaderUid()
uid_data->stagehash[n].tevorders_texmap = bpmem.tevorders[n / 2].getTexMap(n & 1);
}
- if (cc.a == TEVCOLORARG_KONST || cc.b == TEVCOLORARG_KONST || cc.c == TEVCOLORARG_KONST ||
- cc.d == TEVCOLORARG_KONST || ac.a == TEVALPHAARG_KONST || ac.b == TEVALPHAARG_KONST ||
- ac.c == TEVALPHAARG_KONST || ac.d == TEVALPHAARG_KONST)
+ if (cc.a == TevColorArg::Konst || cc.b == TevColorArg::Konst || cc.c == TevColorArg::Konst ||
+ cc.d == TevColorArg::Konst || ac.a == TevAlphaArg::Konst || ac.b == TevAlphaArg::Konst ||
+ ac.c == TevAlphaArg::Konst || ac.d == TevAlphaArg::Konst)
{
uid_data->stagehash[n].tevksel_kc = bpmem.tevksel[n / 2].getKC(n & 1);
uid_data->stagehash[n].tevksel_ka = bpmem.tevksel[n / 2].getKA(n & 1);
@@ -291,15 +294,14 @@ PixelShaderUid GetPixelShaderUid()
sizeof(*uid_data) :
MY_STRUCT_OFFSET(*uid_data, stagehash[numStages]);
- AlphaTest::TEST_RESULT Pretest = bpmem.alpha_test.TestResult();
- uid_data->Pretest = Pretest;
+ uid_data->Pretest = bpmem.alpha_test.TestResult();
uid_data->late_ztest = bpmem.UseLateDepthTest();
// NOTE: Fragment may not be discarded if alpha test always fails and early depth test is enabled
// (in this case we need to write a depth value if depth test passes regardless of the alpha
// testing result)
- if (uid_data->Pretest == AlphaTest::UNDETERMINED ||
- (uid_data->Pretest == AlphaTest::FAIL && uid_data->late_ztest))
+ if (uid_data->Pretest == AlphaTestResult::Undetermined ||
+ (uid_data->Pretest == AlphaTestResult::Fail && uid_data->late_ztest))
{
uid_data->alpha_test_comp0 = bpmem.alpha_test.comp0;
uid_data->alpha_test_comp1 = bpmem.alpha_test.comp1;
@@ -320,7 +322,7 @@ PixelShaderUid GetPixelShaderUid()
uid_data->zfreeze = bpmem.genMode.zfreeze;
uid_data->ztex_op = bpmem.ztex2.op;
uid_data->early_ztest = bpmem.UseEarlyDepthTest();
- uid_data->fog_fsel = bpmem.fog.c_proj_fsel.fsel;
+
uid_data->fog_fsel = bpmem.fog.c_proj_fsel.fsel;
uid_data->fog_proj = bpmem.fog.c_proj_fsel.proj;
uid_data->fog_RangeBaseEnabled = bpmem.fogRange.Base.Enabled;
@@ -517,8 +519,8 @@ void UpdateBoundingBox(float2 rawpos) {{
static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, int n,
APIType api_type, bool stereo);
-static void WriteTevRegular(ShaderCode& out, std::string_view components, int bias, int op,
- int clamp, int shift, bool alpha);
+static void WriteTevRegular(ShaderCode& out, std::string_view components, TevBias bias, TevOp op,
+ bool clamp, TevScale scale, bool alpha);
static void SampleTexture(ShaderCode& out, std::string_view texcoords, std::string_view texswap,
int texmap, bool stereo, APIType api_type);
static void WriteAlphaTest(ShaderCode& out, const pixel_shader_uid_data* uid_data, APIType api_type,
@@ -826,13 +828,13 @@ ShaderCode GeneratePixelShaderCode(APIType api_type, const ShaderHostConfig& hos
TevStageCombiner::AlphaCombiner last_ac;
last_cc.hex = uid_data->stagehash[uid_data->genMode_numtevstages].cc;
last_ac.hex = uid_data->stagehash[uid_data->genMode_numtevstages].ac;
- if (last_cc.dest != 0)
+ if (last_cc.dest != TevOutput::Prev)
{
- out.Write("\tprev.rgb = {};\n", tev_c_output_table[last_cc.dest]);
+ out.Write("\tprev.rgb = {};\n", tev_c_output_table[u32(last_cc.dest.Value())]);
}
- if (last_ac.dest != 0)
+ if (last_ac.dest != TevOutput::Prev)
{
- out.Write("\tprev.a = {};\n", tev_a_output_table[last_ac.dest]);
+ out.Write("\tprev.a = {};\n", tev_a_output_table[u32(last_ac.dest.Value())]);
}
}
out.Write("\tprev = prev & 255;\n");
@@ -840,8 +842,8 @@ ShaderCode GeneratePixelShaderCode(APIType api_type, const ShaderHostConfig& hos
// NOTE: Fragment may not be discarded if alpha test always fails and early depth test is enabled
// (in this case we need to write a depth value if depth test passes regardless of the alpha
// testing result)
- if (uid_data->Pretest == AlphaTest::UNDETERMINED ||
- (uid_data->Pretest == AlphaTest::FAIL && uid_data->late_ztest))
+ if (uid_data->Pretest == AlphaTestResult::Undetermined ||
+ (uid_data->Pretest == AlphaTestResult::Fail && uid_data->late_ztest))
{
WriteAlphaTest(out, uid_data, api_type, uid_data->per_pixel_depth,
use_dual_source || use_shader_blend);
@@ -884,7 +886,7 @@ ShaderCode GeneratePixelShaderCode(APIType api_type, const ShaderHostConfig& hos
// depth texture can safely be ignored if the result won't be written to the depth buffer
// (early_ztest) and isn't used for fog either
- const bool skip_ztexture = !uid_data->per_pixel_depth && !uid_data->fog_fsel;
+ const bool skip_ztexture = !uid_data->per_pixel_depth && uid_data->fog_fsel == FogType::Off;
// Note: z-textures are not written to depth buffer if early depth test is used
if (uid_data->per_pixel_depth && uid_data->early_ztest)
@@ -898,13 +900,13 @@ ShaderCode GeneratePixelShaderCode(APIType api_type, const ShaderHostConfig& hos
// Note: depth texture output is only written to depth buffer if late depth test is used
// theoretical final depth value is used for fog calculation, though, so we have to emulate
// ztextures anyway
- if (uid_data->ztex_op != ZTEXTURE_DISABLE && !skip_ztexture)
+ if (uid_data->ztex_op != ZTexOp::Disabled && !skip_ztexture)
{
// use the texture input of the last texture stage (textemp), hopefully this has been read and
// is in correct format...
out.SetConstantsUsed(C_ZBIAS, C_ZBIAS + 1);
out.Write("\tzCoord = idot(" I_ZBIAS "[0].xyzw, textemp.xyzw) + " I_ZBIAS "[1].w {};\n",
- (uid_data->ztex_op == ZTEXTURE_ADD) ? "+ zCoord" : "");
+ (uid_data->ztex_op == ZTexOp::Add) ? "+ zCoord" : "");
out.Write("\tzCoord = zCoord & 0xFFFFFF;\n");
}
@@ -963,7 +965,7 @@ static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, i
// Perform the indirect op on the incoming regular coordinates
// using iindtex{} as the offset coords
- if (tevind.bs != ITBA_OFF)
+ if (tevind.bs != IndTexBumpAlpha::Off)
{
static constexpr std::array<const char*, 4> tev_ind_alpha_sel{
"",
@@ -980,8 +982,9 @@ static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, i
"248",
};
- out.Write("alphabump = iindtex{}.{} & {};\n", tevind.bt.Value(), tev_ind_alpha_sel[tevind.bs],
- tev_ind_alpha_mask[tevind.fmt]);
+ out.Write("alphabump = iindtex{}.{} & {};\n", tevind.bt.Value(),
+ tev_ind_alpha_sel[u32(tevind.bs.Value())],
+ tev_ind_alpha_mask[u32(tevind.fmt.Value())]);
}
else
{
@@ -998,7 +1001,7 @@ static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, i
"7",
};
out.Write("\tint3 iindtevcrd{} = iindtex{} & {};\n", n, tevind.bt.Value(),
- tev_ind_fmt_mask[tevind.fmt]);
+ tev_ind_fmt_mask[u32(tevind.fmt.Value())]);
// bias - TODO: Check if this needs to be this complicated...
// indexed by bias
@@ -1014,21 +1017,25 @@ static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, i
"1",
};
- if (tevind.bias == ITB_S || tevind.bias == ITB_T || tevind.bias == ITB_U)
+ if (tevind.bias == IndTexBias::S || tevind.bias == IndTexBias::T ||
+ tevind.bias == IndTexBias::U)
{
- out.Write("\tiindtevcrd{}.{} += int({});\n", n, tev_ind_bias_field[tevind.bias],
- tev_ind_bias_add[tevind.fmt]);
+ out.Write("\tiindtevcrd{}.{} += int({});\n", n,
+ tev_ind_bias_field[u32(tevind.bias.Value())],
+ tev_ind_bias_add[u32(tevind.fmt.Value())]);
}
- else if (tevind.bias == ITB_ST || tevind.bias == ITB_SU || tevind.bias == ITB_TU)
+ else if (tevind.bias == IndTexBias::ST || tevind.bias == IndTexBias::SU ||
+ tevind.bias == IndTexBias::TU_)
{
- out.Write("\tiindtevcrd{}.{} += int2({}, {});\n", n, tev_ind_bias_field[tevind.bias],
- tev_ind_bias_add[tevind.fmt], tev_ind_bias_add[tevind.fmt]);
+ out.Write("\tiindtevcrd{0}.{1} += int2({2}, {2});\n", n,
+ tev_ind_bias_field[u32(tevind.bias.Value())],
+ tev_ind_bias_add[u32(tevind.fmt.Value())]);
}
- else if (tevind.bias == ITB_STU)
+ else if (tevind.bias == IndTexBias::STU)
{
- out.Write("\tiindtevcrd{}.{} += int3({}, {}, {});\n", n, tev_ind_bias_field[tevind.bias],
- tev_ind_bias_add[tevind.fmt], tev_ind_bias_add[tevind.fmt],
- tev_ind_bias_add[tevind.fmt]);
+ out.Write("\tiindtevcrd{0}.{1} += int3({2}, {2}, {2});\n", n,
+ tev_ind_bias_field[u32(tevind.bias.Value())],
+ tev_ind_bias_add[u32(tevind.fmt.Value())]);
}
// multiply by offset matrix and scale - calculations are likely to overflow badly,
@@ -1122,33 +1129,33 @@ static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, i
};
// wrap S
- if (tevind.sw == ITW_OFF)
+ if (tevind.sw == IndTexWrap::ITW_OFF)
{
out.Write("\twrappedcoord.x = fixpoint_uv{}.x;\n", texcoord);
}
- else if (tevind.sw == ITW_0)
+ else if (tevind.sw == IndTexWrap::ITW_0)
{
out.Write("\twrappedcoord.x = 0;\n");
}
else
{
out.Write("\twrappedcoord.x = fixpoint_uv{}.x & ({} - 1);\n", texcoord,
- tev_ind_wrap_start[tevind.sw]);
+ tev_ind_wrap_start[u32(tevind.sw.Value())]);
}
// wrap T
- if (tevind.tw == ITW_OFF)
+ if (tevind.tw == IndTexWrap::ITW_OFF)
{
out.Write("\twrappedcoord.y = fixpoint_uv{}.y;\n", texcoord);
}
- else if (tevind.tw == ITW_0)
+ else if (tevind.tw == IndTexWrap::ITW_0)
{
out.Write("\twrappedcoord.y = 0;\n");
}
else
{
out.Write("\twrappedcoord.y = fixpoint_uv{}.y & ({} - 1);\n", texcoord,
- tev_ind_wrap_start[tevind.tw]);
+ tev_ind_wrap_start[u32(tevind.tw.Value())]);
}
if (tevind.fb_addprev) // add previous tevcoord
@@ -1165,10 +1172,12 @@ static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, i
cc.hex = stage.cc;
ac.hex = stage.ac;
- if (cc.a == TEVCOLORARG_RASA || cc.a == TEVCOLORARG_RASC || cc.b == TEVCOLORARG_RASA ||
- cc.b == TEVCOLORARG_RASC || cc.c == TEVCOLORARG_RASA || cc.c == TEVCOLORARG_RASC ||
- cc.d == TEVCOLORARG_RASA || cc.d == TEVCOLORARG_RASC || ac.a == TEVALPHAARG_RASA ||
- ac.b == TEVALPHAARG_RASA || ac.c == TEVALPHAARG_RASA || ac.d == TEVALPHAARG_RASA)
+ if (cc.a == TevColorArg::RasAlpha || cc.a == TevColorArg::RasColor ||
+ cc.b == TevColorArg::RasAlpha || cc.b == TevColorArg::RasColor ||
+ cc.c == TevColorArg::RasAlpha || cc.c == TevColorArg::RasColor ||
+ cc.d == TevColorArg::RasAlpha || cc.d == TevColorArg::RasColor ||
+ ac.a == TevAlphaArg::RasAlpha || ac.b == TevAlphaArg::RasAlpha ||
+ ac.c == TevAlphaArg::RasAlpha || ac.d == TevAlphaArg::RasAlpha)
{
// Generate swizzle string to represent the Ras color channel swapping
const char rasswap[5] = {
@@ -1179,7 +1188,7 @@ static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, i
'\0',
};
- out.Write("\trastemp = {}.{};\n", tev_ras_table[stage.tevorders_colorchan], rasswap);
+ out.Write("\trastemp = {}.{};\n", tev_ras_table[u32(stage.tevorders_colorchan)], rasswap);
}
if (stage.tevorders_enable)
@@ -1209,72 +1218,73 @@ static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, i
out.Write("\ttextemp = int4(255, 255, 255, 255);\n");
}
- if (cc.a == TEVCOLORARG_KONST || cc.b == TEVCOLORARG_KONST || cc.c == TEVCOLORARG_KONST ||
- cc.d == TEVCOLORARG_KONST || ac.a == TEVALPHAARG_KONST || ac.b == TEVALPHAARG_KONST ||
- ac.c == TEVALPHAARG_KONST || ac.d == TEVALPHAARG_KONST)
+ if (cc.a == TevColorArg::Konst || cc.b == TevColorArg::Konst || cc.c == TevColorArg::Konst ||
+ cc.d == TevColorArg::Konst || ac.a == TevAlphaArg::Konst || ac.b == TevAlphaArg::Konst ||
+ ac.c == TevAlphaArg::Konst || ac.d == TevAlphaArg::Konst)
{
- out.Write("\tkonsttemp = int4({}, {});\n", tev_ksel_table_c[stage.tevksel_kc],
- tev_ksel_table_a[stage.tevksel_ka]);
+ out.Write("\tkonsttemp = int4({}, {});\n", tev_ksel_table_c[u32(stage.tevksel_kc)],
+ tev_ksel_table_a[u32(stage.tevksel_ka)]);
- if (stage.tevksel_kc > 7)
+ if (u32(stage.tevksel_kc) > 7)
{
- out.SetConstantsUsed(C_KCOLORS + ((stage.tevksel_kc - 0xc) % 4),
- C_KCOLORS + ((stage.tevksel_kc - 0xc) % 4));
+ out.SetConstantsUsed(C_KCOLORS + ((u32(stage.tevksel_kc) - 0xc) % 4),
+ C_KCOLORS + ((u32(stage.tevksel_kc) - 0xc) % 4));
}
- if (stage.tevksel_ka > 7)
+ if (u32(stage.tevksel_ka) > 7)
{
- out.SetConstantsUsed(C_KCOLORS + ((stage.tevksel_ka - 0xc) % 4),
- C_KCOLORS + ((stage.tevksel_ka - 0xc) % 4));
+ out.SetConstantsUsed(C_KCOLORS + ((u32(stage.tevksel_ka) - 0xc) % 4),
+ C_KCOLORS + ((u32(stage.tevksel_ka) - 0xc) % 4));
}
}
- if (cc.d == TEVCOLORARG_C0 || cc.d == TEVCOLORARG_A0 || ac.d == TEVALPHAARG_A0)
+ if (cc.d == TevColorArg::Color0 || cc.d == TevColorArg::Alpha0 || ac.d == TevAlphaArg::Alpha0)
out.SetConstantsUsed(C_COLORS + 1, C_COLORS + 1);
- if (cc.d == TEVCOLORARG_C1 || cc.d == TEVCOLORARG_A1 || ac.d == TEVALPHAARG_A1)
+ if (cc.d == TevColorArg::Color1 || cc.d == TevColorArg::Alpha1 || ac.d == TevAlphaArg::Alpha1)
out.SetConstantsUsed(C_COLORS + 2, C_COLORS + 2);
- if (cc.d == TEVCOLORARG_C2 || cc.d == TEVCOLORARG_A2 || ac.d == TEVALPHAARG_A2)
+ if (cc.d == TevColorArg::Color2 || cc.d == TevColorArg::Alpha2 || ac.d == TevAlphaArg::Alpha2)
out.SetConstantsUsed(C_COLORS + 3, C_COLORS + 3);
- if (cc.dest >= GX_TEVREG0)
- out.SetConstantsUsed(C_COLORS + cc.dest, C_COLORS + cc.dest);
+ if (cc.dest >= TevOutput::Color0)
+ out.SetConstantsUsed(C_COLORS + u32(cc.dest.Value()), C_COLORS + u32(cc.dest.Value()));
- if (ac.dest >= GX_TEVREG0)
- out.SetConstantsUsed(C_COLORS + ac.dest, C_COLORS + ac.dest);
+ if (ac.dest >= TevOutput::Color0)
+ out.SetConstantsUsed(C_COLORS + u32(ac.dest.Value()), C_COLORS + u32(ac.dest.Value()));
- out.Write("\ttevin_a = int4({}, {})&int4(255, 255, 255, 255);\n", tev_c_input_table[cc.a],
- tev_a_input_table[ac.a]);
- out.Write("\ttevin_b = int4({}, {})&int4(255, 255, 255, 255);\n", tev_c_input_table[cc.b],
- tev_a_input_table[ac.b]);
- out.Write("\ttevin_c = int4({}, {})&int4(255, 255, 255, 255);\n", tev_c_input_table[cc.c],
- tev_a_input_table[ac.c]);
- out.Write("\ttevin_d = int4({}, {});\n", tev_c_input_table[cc.d], tev_a_input_table[ac.d]);
+ out.Write("\ttevin_a = int4({}, {})&int4(255, 255, 255, 255);\n",
+ tev_c_input_table[u32(cc.a.Value())], tev_a_input_table[u32(ac.a.Value())]);
+ out.Write("\ttevin_b = int4({}, {})&int4(255, 255, 255, 255);\n",
+ tev_c_input_table[u32(cc.b.Value())], tev_a_input_table[u32(ac.b.Value())]);
+ out.Write("\ttevin_c = int4({}, {})&int4(255, 255, 255, 255);\n",
+ tev_c_input_table[u32(cc.c.Value())], tev_a_input_table[u32(ac.c.Value())]);
+ out.Write("\ttevin_d = int4({}, {});\n", tev_c_input_table[u32(cc.d.Value())],
+ tev_a_input_table[u32(ac.d.Value())]);
out.Write("\t// color combine\n");
- out.Write("\t{} = clamp(", tev_c_output_table[cc.dest]);
- if (cc.bias != TEVBIAS_COMPARE)
+ out.Write("\t{} = clamp(", tev_c_output_table[u32(cc.dest.Value())]);
+ if (cc.bias != TevBias::Compare)
{
- WriteTevRegular(out, "rgb", cc.bias, cc.op, cc.clamp, cc.shift, false);
+ WriteTevRegular(out, "rgb", cc.bias, cc.op, cc.clamp, cc.scale, false);
}
else
{
static constexpr std::array<const char*, 8> function_table{
- "((tevin_a.r > tevin_b.r) ? tevin_c.rgb : int3(0,0,0))", // TEVCMP_R8_GT
- "((tevin_a.r == tevin_b.r) ? tevin_c.rgb : int3(0,0,0))", // TEVCMP_R8_EQ
+ "((tevin_a.r > tevin_b.r) ? tevin_c.rgb : int3(0,0,0))", // TevCompareMode::R8, GT
+ "((tevin_a.r == tevin_b.r) ? tevin_c.rgb : int3(0,0,0))", // R8, TevComparison::EQ
"((idot(tevin_a.rgb, comp16) > idot(tevin_b.rgb, comp16)) ? tevin_c.rgb : "
- "int3(0,0,0))", // TEVCMP_GR16_GT
+ "int3(0,0,0))", // GR16, GT
"((idot(tevin_a.rgb, comp16) == idot(tevin_b.rgb, comp16)) ? tevin_c.rgb : "
- "int3(0,0,0))", // TEVCMP_GR16_EQ
+ "int3(0,0,0))", // GR16, EQ
"((idot(tevin_a.rgb, comp24) > idot(tevin_b.rgb, comp24)) ? tevin_c.rgb : "
- "int3(0,0,0))", // TEVCMP_BGR24_GT
+ "int3(0,0,0))", // BGR24, GT
"((idot(tevin_a.rgb, comp24) == idot(tevin_b.rgb, comp24)) ? tevin_c.rgb : "
- "int3(0,0,0))", // TEVCMP_BGR24_EQ
- "(max(sign(tevin_a.rgb - tevin_b.rgb), int3(0,0,0)) * tevin_c.rgb)", // TEVCMP_RGB8_GT
- "((int3(1,1,1) - sign(abs(tevin_a.rgb - tevin_b.rgb))) * tevin_c.rgb)" // TEVCMP_RGB8_EQ
+ "int3(0,0,0))", // BGR24, EQ
+ "(max(sign(tevin_a.rgb - tevin_b.rgb), int3(0,0,0)) * tevin_c.rgb)", // RGB8, GT
+ "((int3(1,1,1) - sign(abs(tevin_a.rgb - tevin_b.rgb))) * tevin_c.rgb)" // RGB8, EQ
};
- const u32 mode = (cc.shift << 1) | cc.op;
+ const u32 mode = (u32(cc.compare_mode.Value()) << 1) | u32(cc.comparison.Value());
out.Write(" tevin_d.rgb + ");
out.Write("{}", function_table[mode]);
}
@@ -1285,25 +1295,25 @@ static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, i
out.Write(";\n");
out.Write("\t// alpha combine\n");
- out.Write("\t{} = clamp(", tev_a_output_table[ac.dest]);
- if (ac.bias != TEVBIAS_COMPARE)
+ out.Write("\t{} = clamp(", tev_a_output_table[u32(ac.dest.Value())]);
+ if (ac.bias != TevBias::Compare)
{
- WriteTevRegular(out, "a", ac.bias, ac.op, ac.clamp, ac.shift, true);
+ WriteTevRegular(out, "a", ac.bias, ac.op, ac.clamp, ac.scale, true);
}
else
{
static constexpr std::array<const char*, 8> function_table{
- "((tevin_a.r > tevin_b.r) ? tevin_c.a : 0)", // TEVCMP_R8_GT
- "((tevin_a.r == tevin_b.r) ? tevin_c.a : 0)", // TEVCMP_R8_EQ
- "((idot(tevin_a.rgb, comp16) > idot(tevin_b.rgb, comp16)) ? tevin_c.a : 0)", // TEVCMP_GR16_GT
- "((idot(tevin_a.rgb, comp16) == idot(tevin_b.rgb, comp16)) ? tevin_c.a : 0)", // TEVCMP_GR16_EQ
- "((idot(tevin_a.rgb, comp24) > idot(tevin_b.rgb, comp24)) ? tevin_c.a : 0)", // TEVCMP_BGR24_GT
- "((idot(tevin_a.rgb, comp24) == idot(tevin_b.rgb, comp24)) ? tevin_c.a : 0)", // TEVCMP_BGR24_EQ
- "((tevin_a.a > tevin_b.a) ? tevin_c.a : 0)", // TEVCMP_A8_GT
- "((tevin_a.a == tevin_b.a) ? tevin_c.a : 0)" // TEVCMP_A8_EQ
+ "((tevin_a.r > tevin_b.r) ? tevin_c.a : 0)", // TevCompareMode::R8, GT
+ "((tevin_a.r == tevin_b.r) ? tevin_c.a : 0)", // R8, TevComparison::EQ
+ "((idot(tevin_a.rgb, comp16) > idot(tevin_b.rgb, comp16)) ? tevin_c.a : 0)", // GR16, GT
+ "((idot(tevin_a.rgb, comp16) == idot(tevin_b.rgb, comp16)) ? tevin_c.a : 0)", // GR16, EQ
+ "((idot(tevin_a.rgb, comp24) > idot(tevin_b.rgb, comp24)) ? tevin_c.a : 0)", // BGR24, GT
+ "((idot(tevin_a.rgb, comp24) == idot(tevin_b.rgb, comp24)) ? tevin_c.a : 0)", // BGR24, EQ
+ "((tevin_a.a > tevin_b.a) ? tevin_c.a : 0)", // A8, GT
+ "((tevin_a.a == tevin_b.a) ? tevin_c.a : 0)" // A8, EQ
};
- const u32 mode = (ac.shift << 1) | ac.op;
+ const u32 mode = (u32(ac.compare_mode.Value()) << 1) | u32(ac.comparison.Value());
out.Write(" tevin_d.a + ");
out.Write("{}", function_table[mode]);
}
@@ -1315,24 +1325,24 @@ static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, i
out.Write(";\n");
}
-static void WriteTevRegular(ShaderCode& out, std::string_view components, int bias, int op,
- int clamp, int shift, bool alpha)
+static void WriteTevRegular(ShaderCode& out, std::string_view components, TevBias bias, TevOp op,
+ bool clamp, TevScale scale, bool alpha)
{
static constexpr std::array<const char*, 4> tev_scale_table_left{
- "", // SCALE_1
- " << 1", // SCALE_2
- " << 2", // SCALE_4
- "", // DIVIDE_2
+ "", // Scale1
+ " << 1", // Scale2
+ " << 2", // Scale4
+ "", // Divide2
};
static constexpr std::array<const char*, 4> tev_scale_table_right{
- "", // SCALE_1
- "", // SCALE_2
- "", // SCALE_4
- " >> 1", // DIVIDE_2
+ "", // Scale1
+ "", // Scale2
+ "", // Scale4
+ " >> 1", // Divide2
};
- // indexed by 2*op+(shift==3)
+ // indexed by 2*op+(scale==Divide2)
static constexpr std::array<const char*, 4> tev_lerp_bias{
"",
" + 128",
@@ -1341,15 +1351,15 @@ static void WriteTevRegular(ShaderCode& out, std::string_view components, int bi
};
static constexpr std::array<const char*, 4> tev_bias_table{
- "", // ZERO,
- " + 128", // ADDHALF,
- " - 128", // SUBHALF,
+ "", // Zero,
+ " + 128", // AddHalf,
+ " - 128", // SubHalf,
"",
};
static constexpr std::array<char, 2> tev_op_table{
- '+', // TEVOP_ADD = 0,
- '-', // TEVOP_SUB = 1,
+ '+', // TevOp::Add = 0,
+ '-', // TevOp::Sub = 1,
};
// Regular TEV stage: (d + bias + lerp(a,b,c)) * scale
@@ -1357,12 +1367,14 @@ static void WriteTevRegular(ShaderCode& out, std::string_view components, int bi
// - c is scaled from 0..255 to 0..256, which allows dividing the result by 256 instead of 255
// - if scale is bigger than one, it is moved inside the lerp calculation for increased accuracy
// - a rounding bias is added before dividing by 256
- out.Write("(((tevin_d.{}{}){})", components, tev_bias_table[bias], tev_scale_table_left[shift]);
- out.Write(" {} ", tev_op_table[op]);
+ out.Write("(((tevin_d.{}{}){})", components, tev_bias_table[u32(bias)],
+ tev_scale_table_left[u32(scale)]);
+ out.Write(" {} ", tev_op_table[u32(op)]);
out.Write("(((((tevin_a.{}<<8) + (tevin_b.{}-tevin_a.{})*(tevin_c.{}+(tevin_c.{}>>7))){}){})>>8)",
- components, components, components, components, components, tev_scale_table_left[shift],
- tev_lerp_bias[2 * op + ((shift == 3) == alpha)]);
- out.Write("){}", tev_scale_table_right[shift]);
+ components, components, components, components, components,
+ tev_scale_table_left[u32(scale)],
+ tev_lerp_bias[2 * u32(op) + ((scale == TevScale::Divide2) == alpha)]);
+ out.Write("){}", tev_scale_table_right[u32(scale)]);
}
static void SampleTexture(ShaderCode& out, std::string_view texcoords, std::string_view texswap,
@@ -1384,14 +1396,14 @@ static void SampleTexture(ShaderCode& out, std::string_view texcoords, std::stri
}
constexpr std::array<const char*, 8> tev_alpha_funcs_table{
- "(false)", // NEVER
- "(prev.a < {})", // LESS
- "(prev.a == {})", // EQUAL
- "(prev.a <= {})", // LEQUAL
- "(prev.a > {})", // GREATER
- "(prev.a != {})", // NEQUAL
- "(prev.a >= {})", // GEQUAL
- "(true)" // ALWAYS
+ "(false)", // CompareMode::Never
+ "(prev.a < {})", // CompareMode::Less
+ "(prev.a == {})", // CompareMode::Equal
+ "(prev.a <= {})", // CompareMode::LEqual
+ "(prev.a > {})", // CompareMode::Greater
+ "(prev.a != {})", // CompareMode::NEqual
+ "(prev.a >= {})", // CompareMode::GEqual
+ "(true)" // CompareMode::Always
};
constexpr std::array<const char*, 4> tev_alpha_funclogic_table{
@@ -1409,12 +1421,12 @@ static void WriteAlphaTest(ShaderCode& out, const pixel_shader_uid_data* uid_dat
I_ALPHA ".g",
};
- const auto write_alpha_func = [&out](int index, std::string_view ref) {
- const bool has_no_arguments = index == 0 || index == tev_alpha_funcs_table.size() - 1;
+ const auto write_alpha_func = [&out](CompareMode mode, std::string_view ref) {
+ const bool has_no_arguments = mode == CompareMode::Never || mode == CompareMode::Always;
if (has_no_arguments)
- out.Write("{}", tev_alpha_funcs_table[index]);
+ out.Write("{}", tev_alpha_funcs_table[u32(mode)]);
else
- out.Write(tev_alpha_funcs_table[index], ref);
+ out.Write(tev_alpha_funcs_table[u32(mode)], ref);
};
out.SetConstantsUsed(C_ALPHA, C_ALPHA);
@@ -1425,15 +1437,13 @@ static void WriteAlphaTest(ShaderCode& out, const pixel_shader_uid_data* uid_dat
out.Write("\tif(!( ");
// Lookup the first component from the alpha function table
- const int comp0_index = uid_data->alpha_test_comp0;
- write_alpha_func(comp0_index, alpha_ref[0]);
+ write_alpha_func(uid_data->alpha_test_comp0, alpha_ref[0]);
// Lookup the logic op
- out.Write("{}", tev_alpha_funclogic_table[uid_data->alpha_test_logic]);
+ out.Write("{}", tev_alpha_funclogic_table[u32(uid_data->alpha_test_logic)]);
// Lookup the second component from the alpha function table
- const int comp1_index = uid_data->alpha_test_comp1;
- write_alpha_func(comp1_index, alpha_ref[1]);
+ write_alpha_func(uid_data->alpha_test_comp1, alpha_ref[1]);
if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_NEGATED_BOOLEAN))
out.Write(") == false) {{\n");
@@ -1473,13 +1483,13 @@ constexpr std::array<const char*, 8> tev_fog_funcs_table{
static void WriteFog(ShaderCode& out, const pixel_shader_uid_data* uid_data)
{
- if (uid_data->fog_fsel == 0)
+ if (uid_data->fog_fsel == FogType::Off)
return; // no Fog
out.SetConstantsUsed(C_FOGCOLOR, C_FOGCOLOR);
out.SetConstantsUsed(C_FOGI, C_FOGI);
out.SetConstantsUsed(C_FOGF, C_FOGF + 1);
- if (uid_data->fog_proj == 0)
+ if (uid_data->fog_proj == FogProjection::Perspective)
{
// perspective
// ze = A/(B - (Zs >> B_SHF)
@@ -1515,14 +1525,14 @@ static void WriteFog(ShaderCode& out, const pixel_shader_uid_data* uid_data)
out.Write("\tfloat fog = clamp(ze - " I_FOGF ".y, 0.0, 1.0);\n");
- if (uid_data->fog_fsel > 3)
+ if (uid_data->fog_fsel >= FogType::Exp)
{
- out.Write("{}", tev_fog_funcs_table[uid_data->fog_fsel]);
+ out.Write("{}", tev_fog_funcs_table[u32(uid_data->fog_fsel)]);
}
else
{
- if (uid_data->fog_fsel != 2)
- WARN_LOG_FMT(VIDEO, "Unknown Fog Type! {:08x}", uid_data->fog_fsel);
+ if (uid_data->fog_fsel != FogType::Linear)
+ WARN_LOG_FMT(VIDEO, "Unknown Fog Type! {}", uid_data->fog_fsel);
}
out.Write("\tint ifog = iround(fog * 256.0);\n");
@@ -1611,11 +1621,13 @@ static void WriteBlend(ShaderCode& out, const pixel_shader_uid_data* uid_data)
"1.0 - initial_ocol0.a;", // INVDSTALPHA
};
out.Write("\tfloat4 blend_src;\n");
- out.Write("\tblend_src.rgb = {}\n", blend_src_factor[uid_data->blend_src_factor]);
- out.Write("\tblend_src.a = {}\n", blend_src_factor_alpha[uid_data->blend_src_factor_alpha]);
+ out.Write("\tblend_src.rgb = {}\n", blend_src_factor[u32(uid_data->blend_src_factor)]);
+ out.Write("\tblend_src.a = {}\n",
+ blend_src_factor_alpha[u32(uid_data->blend_src_factor_alpha)]);
out.Write("\tfloat4 blend_dst;\n");
- out.Write("\tblend_dst.rgb = {}\n", blend_dst_factor[uid_data->blend_dst_factor]);
- out.Write("\tblend_dst.a = {}\n", blend_dst_factor_alpha[uid_data->blend_dst_factor_alpha]);
+ out.Write("\tblend_dst.rgb = {}\n", blend_dst_factor[u32(uid_data->blend_dst_factor)]);
+ out.Write("\tblend_dst.a = {}\n",
+ blend_dst_factor_alpha[u32(uid_data->blend_dst_factor_alpha)]);
out.Write("\tfloat4 blend_result;\n");
if (uid_data->blend_subtract)
diff --git a/Source/Core/VideoCommon/PixelShaderGen.h b/Source/Core/VideoCommon/PixelShaderGen.h
index 08704bda0a..a9ffa25498 100644
--- a/Source/Core/VideoCommon/PixelShaderGen.h
+++ b/Source/Core/VideoCommon/PixelShaderGen.h
@@ -9,6 +9,15 @@
#include "VideoCommon/ShaderGenCommon.h"
enum class APIType;
+enum class AlphaTestResult;
+enum class SrcBlendFactor : u32;
+enum class DstBlendFactor : u32;
+enum class CompareMode : u32;
+enum class AlphaTestOp : u32;
+enum class RasColorChan : u32;
+enum class KonstSel : u32;
+enum class FogProjection : u32;
+enum class FogType : u32;
#pragma pack(1)
struct pixel_shader_uid_data
@@ -19,18 +28,18 @@ struct pixel_shader_uid_data
u32 NumValues() const { return num_values; }
u32 pad0 : 4;
u32 useDstAlpha : 1;
- u32 Pretest : 2;
+ AlphaTestResult Pretest : 2;
u32 nIndirectStagesUsed : 4;
u32 genMode_numtexgens : 4;
u32 genMode_numtevstages : 4;
u32 genMode_numindstages : 3;
- u32 alpha_test_comp0 : 3;
- u32 alpha_test_comp1 : 3;
- u32 alpha_test_logic : 2;
+ CompareMode alpha_test_comp0 : 3;
+ CompareMode alpha_test_comp1 : 3;
+ AlphaTestOp alpha_test_logic : 2;
u32 alpha_test_use_zcomploc_hack : 1;
- u32 fog_proj : 1;
+ FogProjection fog_proj : 1;
- u32 fog_fsel : 3;
+ FogType fog_fsel : 3;
u32 fog_RangeBaseEnabled : 1;
u32 ztex_op : 2;
u32 per_pixel_depth : 1;
@@ -43,13 +52,13 @@ struct pixel_shader_uid_data
u32 rgba6_format : 1;
u32 dither : 1;
u32 uint_output : 1;
- u32 blend_enable : 1; // Only used with shader_framebuffer_fetch blend
- u32 blend_src_factor : 3; // Only used with shader_framebuffer_fetch blend
- u32 blend_src_factor_alpha : 3; // Only used with shader_framebuffer_fetch blend
- u32 blend_dst_factor : 3; // Only used with shader_framebuffer_fetch blend
- u32 blend_dst_factor_alpha : 3; // Only used with shader_framebuffer_fetch blend
- u32 blend_subtract : 1; // Only used with shader_framebuffer_fetch blend
- u32 blend_subtract_alpha : 1; // Only used with shader_framebuffer_fetch blend
+ u32 blend_enable : 1; // Only used with shader_framebuffer_fetch blend
+ SrcBlendFactor blend_src_factor : 3; // Only used with shader_framebuffer_fetch blend
+ SrcBlendFactor blend_src_factor_alpha : 3; // Only used with shader_framebuffer_fetch blend
+ DstBlendFactor blend_dst_factor : 3; // Only used with shader_framebuffer_fetch blend
+ DstBlendFactor blend_dst_factor_alpha : 3; // Only used with shader_framebuffer_fetch blend
+ u32 blend_subtract : 1; // Only used with shader_framebuffer_fetch blend
+ u32 blend_subtract_alpha : 1; // Only used with shader_framebuffer_fetch blend
u32 texMtxInfo_n_projection : 8; // 8x1 bit
u32 tevindref_bi0 : 3;
@@ -136,7 +145,7 @@ struct pixel_shader_uid_data
u32 tevorders_texmap : 3;
u32 tevorders_texcoord : 3;
u32 tevorders_enable : 1;
- u32 tevorders_colorchan : 3;
+ RasColorChan tevorders_colorchan : 3;
u32 pad1 : 6;
// TODO: Clean up the swapXY mess
@@ -152,8 +161,8 @@ struct pixel_shader_uid_data
u32 tevksel_swap2c : 2;
u32 tevksel_swap1d : 2;
u32 tevksel_swap2d : 2;
- u32 tevksel_kc : 5;
- u32 tevksel_ka : 5;
+ KonstSel tevksel_kc : 5;
+ KonstSel tevksel_ka : 5;
u32 pad3 : 14;
} stagehash[16];
diff --git a/Source/Core/VideoCommon/PixelShaderManager.cpp b/Source/Core/VideoCommon/PixelShaderManager.cpp
index c2aca3e2f6..bae48623c7 100644
--- a/Source/Core/VideoCommon/PixelShaderManager.cpp
+++ b/Source/Core/VideoCommon/PixelShaderManager.cpp
@@ -182,7 +182,7 @@ void PixelShaderManager::SetConstants()
// Destination alpha is only enabled if alpha writes are enabled. Force entire uniform to zero
// when disabled.
u32 dstalpha = bpmem.blendmode.alphaupdate && bpmem.dstalpha.enable &&
- bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24 ?
+ bpmem.zcontrol.pixel_format == PixelFormat::RGBA6_Z24 ?
bpmem.dstalpha.hex :
0;
@@ -270,7 +270,7 @@ void PixelShaderManager::SetAlphaTestChanged()
// TODO: we could optimize this further and check the actual constants,
// i.e. "a <= 0" and "a >= 255" will always pass.
u32 alpha_test =
- bpmem.alpha_test.TestResult() != AlphaTest::PASS ? bpmem.alpha_test.hex | 1 << 31 : 0;
+ bpmem.alpha_test.TestResult() != AlphaTestResult::Pass ? bpmem.alpha_test.hex | 1 << 31 : 0;
if (constants.alphaTest != alpha_test)
{
constants.alphaTest = alpha_test;
@@ -362,25 +362,26 @@ void PixelShaderManager::SetZTextureTypeChanged()
{
switch (bpmem.ztex2.type)
{
- case TEV_ZTEX_TYPE_U8:
+ case ZTexFormat::U8:
constants.zbias[0][0] = 0;
constants.zbias[0][1] = 0;
constants.zbias[0][2] = 0;
constants.zbias[0][3] = 1;
break;
- case TEV_ZTEX_TYPE_U16:
+ case ZTexFormat::U16:
constants.zbias[0][0] = 1;
constants.zbias[0][1] = 0;
constants.zbias[0][2] = 0;
constants.zbias[0][3] = 256;
break;
- case TEV_ZTEX_TYPE_U24:
+ case ZTexFormat::U24:
constants.zbias[0][0] = 65536;
constants.zbias[0][1] = 256;
constants.zbias[0][2] = 1;
constants.zbias[0][3] = 0;
break;
default:
+ PanicAlertFmt("Invalid ztex format {}", bpmem.ztex2.type);
break;
}
dirty = true;
@@ -457,8 +458,9 @@ void PixelShaderManager::SetZModeControl()
{
u32 late_ztest = bpmem.UseLateDepthTest();
u32 rgba6_format =
- (bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24 && !g_ActiveConfig.bForceTrueColor) ? 1 :
- 0;
+ (bpmem.zcontrol.pixel_format == PixelFormat::RGBA6_Z24 && !g_ActiveConfig.bForceTrueColor) ?
+ 1 :
+ 0;
u32 dither = rgba6_format && bpmem.blendmode.dither;
if (constants.late_ztest != late_ztest || constants.rgba6_format != rgba6_format ||
constants.dither != dither)
diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp
index 1a9af2f232..ba91c0551e 100644
--- a/Source/Core/VideoCommon/RenderBase.cpp
+++ b/Source/Core/VideoCommon/RenderBase.cpp
@@ -171,7 +171,7 @@ void Renderer::SetAndClearFramebuffer(AbstractFramebuffer* framebuffer,
bool Renderer::EFBHasAlphaChannel() const
{
- return m_prev_efb_format == PEControl::RGBA6_Z24;
+ return m_prev_efb_format == PixelFormat::RGBA6_Z24;
}
void Renderer::ClearScreen(const MathUtil::Rectangle<int>& rc, bool colorEnable, bool alphaEnable,
@@ -197,15 +197,15 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
// check what to do with the alpha channel (GX_PokeAlphaRead)
PixelEngine::UPEAlphaReadReg alpha_read_mode = PixelEngine::GetAlphaReadMode();
- if (bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24)
+ if (bpmem.zcontrol.pixel_format == PixelFormat::RGBA6_Z24)
{
color = RGBA8ToRGBA6ToRGBA8(color);
}
- else if (bpmem.zcontrol.pixel_format == PEControl::RGB565_Z16)
+ else if (bpmem.zcontrol.pixel_format == PixelFormat::RGB565_Z16)
{
color = RGBA8ToRGB565ToRGBA8(color);
}
- if (bpmem.zcontrol.pixel_format != PEControl::RGBA6_Z24)
+ if (bpmem.zcontrol.pixel_format != PixelFormat::RGBA6_Z24)
{
color |= 0xFF000000;
}
@@ -231,7 +231,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
depth = 1.0f - depth;
u32 ret = 0;
- if (bpmem.zcontrol.pixel_format == PEControl::RGB565_Z16)
+ if (bpmem.zcontrol.pixel_format == PixelFormat::RGB565_Z16)
{
// if Z is in 16 bit format you must return a 16 bit integer
ret = std::clamp<u32>(static_cast<u32>(depth * 65536.0f), 0, 0xFFFF);
@@ -994,10 +994,10 @@ bool Renderer::RecompileImGuiPipeline()
pconfig.depth_state = RenderState::GetNoDepthTestingDepthState();
pconfig.blending_state = RenderState::GetNoBlendingBlendState();
pconfig.blending_state.blendenable = true;
- pconfig.blending_state.srcfactor = BlendMode::SRCALPHA;
- pconfig.blending_state.dstfactor = BlendMode::INVSRCALPHA;
- pconfig.blending_state.srcfactoralpha = BlendMode::ZERO;
- pconfig.blending_state.dstfactoralpha = BlendMode::ONE;
+ pconfig.blending_state.srcfactor = SrcBlendFactor::SrcAlpha;
+ pconfig.blending_state.dstfactor = DstBlendFactor::InvSrcAlpha;
+ pconfig.blending_state.srcfactoralpha = SrcBlendFactor::Zero;
+ pconfig.blending_state.dstfactoralpha = DstBlendFactor::One;
pconfig.framebuffer_state.color_texture_format = m_backbuffer_format;
pconfig.framebuffer_state.depth_texture_format = AbstractTextureFormat::Undefined;
pconfig.framebuffer_state.samples = 1;
@@ -1697,7 +1697,7 @@ bool Renderer::UseVertexDepthRange() const
return false;
// We need a full depth range if a ztexture is used.
- if (bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.early_ztest)
+ if (bpmem.ztex2.op != ZTexOp::Disabled && !bpmem.zcontrol.early_ztest)
return true;
// If an inverted depth range is unsupported, we also need to check if the range is inverted.
diff --git a/Source/Core/VideoCommon/RenderBase.h b/Source/Core/VideoCommon/RenderBase.h
index 91be0e358c..48cef0bdad 100644
--- a/Source/Core/VideoCommon/RenderBase.h
+++ b/Source/Core/VideoCommon/RenderBase.h
@@ -232,8 +232,8 @@ public:
// Called when the configuration changes, and backend structures need to be updated.
virtual void OnConfigChanged(u32 bits) {}
- PEControl::PixelFormat GetPrevPixelFormat() const { return m_prev_efb_format; }
- void StorePixelFormat(PEControl::PixelFormat new_format) { m_prev_efb_format = new_format; }
+ PixelFormat GetPrevPixelFormat() const { return m_prev_efb_format; }
+ void StorePixelFormat(PixelFormat new_format) { m_prev_efb_format = new_format; }
bool EFBHasAlphaChannel() const;
VideoCommon::PostProcessing* GetPostProcessor() const { return m_post_processor.get(); }
// Final surface changing
@@ -343,7 +343,7 @@ protected:
private:
std::tuple<int, int> CalculateOutputDimensions(int width, int height) const;
- PEControl::PixelFormat m_prev_efb_format = PEControl::INVALID_FMT;
+ PixelFormat m_prev_efb_format = PixelFormat::INVALID_FMT;
unsigned int m_efb_scale = 1;
// These will be set on the first call to SetWindowSize.
diff --git a/Source/Core/VideoCommon/RenderState.cpp b/Source/Core/VideoCommon/RenderState.cpp
index 6d6f892979..2cf339d397 100644
--- a/Source/Core/VideoCommon/RenderState.cpp
+++ b/Source/Core/VideoCommon/RenderState.cpp
@@ -15,7 +15,7 @@ void RasterizationState::Generate(const BPMemory& bp, PrimitiveType primitive_ty
// Back-face culling should be disabled for points/lines.
if (primitive_type != PrimitiveType::Triangles && primitive_type != PrimitiveType::TriangleStrip)
- cullmode = GenMode::CULL_NONE;
+ cullmode = CullMode::None;
}
RasterizationState& RasterizationState::operator=(const RasterizationState& rhs)
@@ -47,14 +47,27 @@ DepthState& DepthState::operator=(const DepthState& rhs)
// ONE on blending. As the backends may emulate this framebuffer
// configuration with an alpha channel, we just drop all references
// to the destination alpha channel.
-static BlendMode::BlendFactor RemoveDstAlphaUsage(BlendMode::BlendFactor factor)
+static SrcBlendFactor RemoveDstAlphaUsage(SrcBlendFactor factor)
{
switch (factor)
{
- case BlendMode::DSTALPHA:
- return BlendMode::ONE;
- case BlendMode::INVDSTALPHA:
- return BlendMode::ZERO;
+ case SrcBlendFactor::DstAlpha:
+ return SrcBlendFactor::One;
+ case SrcBlendFactor::InvDstAlpha:
+ return SrcBlendFactor::Zero;
+ default:
+ return factor;
+ }
+}
+
+static DstBlendFactor RemoveDstAlphaUsage(DstBlendFactor factor)
+{
+ switch (factor)
+ {
+ case DstBlendFactor::DstAlpha:
+ return DstBlendFactor::One;
+ case DstBlendFactor::InvDstAlpha:
+ return DstBlendFactor::Zero;
default:
return factor;
}
@@ -64,14 +77,14 @@ static BlendMode::BlendFactor RemoveDstAlphaUsage(BlendMode::BlendFactor factor)
// the alpha component, CLR and ALPHA are indentical. So just always
// use ALPHA as this makes it easier for the backends to use the second
// alpha value of dual source blending.
-static BlendMode::BlendFactor RemoveSrcColorUsage(BlendMode::BlendFactor factor)
+static DstBlendFactor RemoveSrcColorUsage(DstBlendFactor factor)
{
switch (factor)
{
- case BlendMode::SRCCLR:
- return BlendMode::SRCALPHA;
- case BlendMode::INVSRCCLR:
- return BlendMode::INVSRCALPHA;
+ case DstBlendFactor::SrcClr:
+ return DstBlendFactor::SrcAlpha;
+ case DstBlendFactor::InvSrcClr:
+ return DstBlendFactor::InvSrcAlpha;
default:
return factor;
}
@@ -79,14 +92,14 @@ static BlendMode::BlendFactor RemoveSrcColorUsage(BlendMode::BlendFactor factor)
// Same as RemoveSrcColorUsage, but because of the overlapping enum,
// this must be written as another function.
-static BlendMode::BlendFactor RemoveDstColorUsage(BlendMode::BlendFactor factor)
+static SrcBlendFactor RemoveDstColorUsage(SrcBlendFactor factor)
{
switch (factor)
{
- case BlendMode::DSTCLR:
- return BlendMode::DSTALPHA;
- case BlendMode::INVDSTCLR:
- return BlendMode::INVDSTALPHA;
+ case SrcBlendFactor::DstClr:
+ return SrcBlendFactor::DstAlpha;
+ case SrcBlendFactor::InvDstClr:
+ return SrcBlendFactor::InvDstAlpha;
default:
return factor;
}
@@ -97,11 +110,11 @@ void BlendingState::Generate(const BPMemory& bp)
// Start with everything disabled.
hex = 0;
- bool target_has_alpha = bp.zcontrol.pixel_format == PEControl::RGBA6_Z24;
- bool alpha_test_may_success = bp.alpha_test.TestResult() != AlphaTest::FAIL;
+ bool target_has_alpha = bp.zcontrol.pixel_format == PixelFormat::RGBA6_Z24;
+ bool alpha_test_may_succeed = bp.alpha_test.TestResult() != AlphaTestResult::Fail;
- colorupdate = bp.blendmode.colorupdate && alpha_test_may_success;
- alphaupdate = bp.blendmode.alphaupdate && target_has_alpha && alpha_test_may_success;
+ colorupdate = bp.blendmode.colorupdate && alpha_test_may_succeed;
+ alphaupdate = bp.blendmode.alphaupdate && target_has_alpha && alpha_test_may_succeed;
dstalpha = bp.dstalpha.enable && alphaupdate;
usedualsrc = true;
@@ -110,14 +123,14 @@ void BlendingState::Generate(const BPMemory& bp)
{
blendenable = true;
subtractAlpha = subtract = true;
- srcfactoralpha = srcfactor = BlendMode::ONE;
- dstfactoralpha = dstfactor = BlendMode::ONE;
+ srcfactoralpha = srcfactor = SrcBlendFactor::One;
+ dstfactoralpha = dstfactor = DstBlendFactor::One;
if (dstalpha)
{
subtractAlpha = false;
- srcfactoralpha = BlendMode::ONE;
- dstfactoralpha = BlendMode::ZERO;
+ srcfactoralpha = SrcBlendFactor::One;
+ dstfactoralpha = DstBlendFactor::Zero;
}
}
@@ -133,22 +146,22 @@ void BlendingState::Generate(const BPMemory& bp)
srcfactor = RemoveDstAlphaUsage(srcfactor);
dstfactor = RemoveDstAlphaUsage(dstfactor);
}
- // replaces SRCCLR with SRCALPHA and DSTCLR with DSTALPHA, it is important to
+ // replaces SrcClr with SrcAlpha and DstClr with DstAlpha, it is important to
// use the dst function for the src factor and vice versa
srcfactoralpha = RemoveDstColorUsage(srcfactor);
dstfactoralpha = RemoveSrcColorUsage(dstfactor);
if (dstalpha)
{
- srcfactoralpha = BlendMode::ONE;
- dstfactoralpha = BlendMode::ZERO;
+ srcfactoralpha = SrcBlendFactor::One;
+ dstfactoralpha = DstBlendFactor::Zero;
}
}
// The logicop bit has the lowest priority
else if (bp.blendmode.logicopenable)
{
- if (bp.blendmode.logicmode == BlendMode::NOOP)
+ if (bp.blendmode.logicmode == LogicOp::NoOp)
{
// Fast path for Kirby's Return to Dreamland, they use it with dstAlpha.
colorupdate = false;
@@ -169,38 +182,39 @@ void BlendingState::Generate(const BPMemory& bp)
void BlendingState::ApproximateLogicOpWithBlending()
{
- // Any of these which use SRC as srcFactor or DST as dstFactor won't be correct.
- // This is because the two are aliased to one another (see the enum).
struct LogicOpApproximation
{
bool subtract;
- BlendMode::BlendFactor srcfactor;
- BlendMode::BlendFactor dstfactor;
+ SrcBlendFactor srcfactor;
+ DstBlendFactor dstfactor;
};
+ // TODO: This previously had a warning about SRC and DST being aliased and not to mix them,
+ // but INVSRCCLR and INVDSTCLR were also aliased and were mixed.
+ // Thus, NOR, EQUIV, INVERT, COPY_INVERTED, and OR_INVERTED duplicate(d) other values.
static constexpr std::array<LogicOpApproximation, 16> approximations = {{
- {false, BlendMode::ZERO, BlendMode::ZERO}, // CLEAR
- {false, BlendMode::DSTCLR, BlendMode::ZERO}, // AND
- {true, BlendMode::ONE, BlendMode::INVSRCCLR}, // AND_REVERSE
- {false, BlendMode::ONE, BlendMode::ZERO}, // COPY
- {true, BlendMode::DSTCLR, BlendMode::ONE}, // AND_INVERTED
- {false, BlendMode::ZERO, BlendMode::ONE}, // NOOP
- {false, BlendMode::INVDSTCLR, BlendMode::INVSRCCLR}, // XOR
- {false, BlendMode::INVDSTCLR, BlendMode::ONE}, // OR
- {false, BlendMode::INVSRCCLR, BlendMode::INVDSTCLR}, // NOR
- {false, BlendMode::INVSRCCLR, BlendMode::ZERO}, // EQUIV
- {false, BlendMode::INVDSTCLR, BlendMode::INVDSTCLR}, // INVERT
- {false, BlendMode::ONE, BlendMode::INVDSTALPHA}, // OR_REVERSE
- {false, BlendMode::INVSRCCLR, BlendMode::INVSRCCLR}, // COPY_INVERTED
- {false, BlendMode::INVSRCCLR, BlendMode::ONE}, // OR_INVERTED
- {false, BlendMode::INVDSTCLR, BlendMode::INVSRCCLR}, // NAND
- {false, BlendMode::ONE, BlendMode::ONE}, // SET
+ {false, SrcBlendFactor::Zero, DstBlendFactor::Zero}, // CLEAR
+ {false, SrcBlendFactor::DstClr, DstBlendFactor::Zero}, // AND
+ {true, SrcBlendFactor::One, DstBlendFactor::InvSrcClr}, // AND_REVERSE
+ {false, SrcBlendFactor::One, DstBlendFactor::Zero}, // COPY
+ {true, SrcBlendFactor::DstClr, DstBlendFactor::One}, // AND_INVERTED
+ {false, SrcBlendFactor::Zero, DstBlendFactor::One}, // NOOP
+ {false, SrcBlendFactor::InvDstClr, DstBlendFactor::InvSrcClr}, // XOR
+ {false, SrcBlendFactor::InvDstClr, DstBlendFactor::One}, // OR
+ {false, SrcBlendFactor::InvDstClr, DstBlendFactor::InvSrcClr}, // NOR
+ {false, SrcBlendFactor::InvDstClr, DstBlendFactor::Zero}, // EQUIV
+ {false, SrcBlendFactor::InvDstClr, DstBlendFactor::InvSrcClr}, // INVERT
+ {false, SrcBlendFactor::One, DstBlendFactor::InvDstAlpha}, // OR_REVERSE
+ {false, SrcBlendFactor::InvDstClr, DstBlendFactor::InvSrcClr}, // COPY_INVERTED
+ {false, SrcBlendFactor::InvDstClr, DstBlendFactor::One}, // OR_INVERTED
+ {false, SrcBlendFactor::InvDstClr, DstBlendFactor::InvSrcClr}, // NAND
+ {false, SrcBlendFactor::One, DstBlendFactor::One}, // SET
}};
logicopenable = false;
blendenable = true;
- subtract = approximations[logicmode].subtract;
- srcfactor = approximations[logicmode].srcfactor;
- dstfactor = approximations[logicmode].dstfactor;
+ subtract = approximations[u32(logicmode.Value())].subtract;
+ srcfactor = approximations[u32(logicmode.Value())].srcfactor;
+ dstfactor = approximations[u32(logicmode.Value())].dstfactor;
}
BlendingState& BlendingState::operator=(const BlendingState& rhs)
@@ -217,20 +231,20 @@ void SamplerState::Generate(const BPMemory& bp, u32 index)
// GX can configure the mip filter to none. However, D3D and Vulkan can't express this in their
// sampler states. Therefore, we set the min/max LOD to zero if this option is used.
- min_filter = (tm0.min_filter & 4) != 0 ? Filter::Linear : Filter::Point;
- mipmap_filter = (tm0.min_filter & 3) == TexMode0::TEXF_LINEAR ? Filter::Linear : Filter::Point;
- mag_filter = tm0.mag_filter != 0 ? Filter::Linear : Filter::Point;
+ min_filter = tm0.min_filter == FilterMode::Linear ? Filter::Linear : Filter::Point;
+ mipmap_filter = tm0.mipmap_filter == MipMode::Linear ? Filter::Linear : Filter::Point;
+ mag_filter = tm0.mag_filter == FilterMode::Linear ? Filter::Linear : Filter::Point;
// If mipmaps are disabled, clamp min/max lod
- max_lod = SamplerCommon::AreBpTexMode0MipmapsEnabled(tm0) ? tm1.max_lod : 0;
+ max_lod = SamplerCommon::AreBpTexMode0MipmapsEnabled(tm0) ? tm1.max_lod.Value() : 0;
min_lod = std::min(max_lod.Value(), static_cast<u64>(tm1.min_lod));
lod_bias = SamplerCommon::AreBpTexMode0MipmapsEnabled(tm0) ? tm0.lod_bias * (256 / 32) : 0;
// Address modes
static constexpr std::array<AddressMode, 4> address_modes = {
{AddressMode::Clamp, AddressMode::Repeat, AddressMode::MirroredRepeat, AddressMode::Repeat}};
- wrap_u = address_modes[tm0.wrap_s];
- wrap_v = address_modes[tm0.wrap_t];
+ wrap_u = address_modes[u32(tm0.wrap_s.Value())];
+ wrap_v = address_modes[u32(tm0.wrap_t.Value())];
anisotropic_filtering = 0;
}
@@ -252,7 +266,7 @@ RasterizationState GetInvalidRasterizationState()
RasterizationState GetNoCullRasterizationState(PrimitiveType primitive)
{
RasterizationState state = {};
- state.cullmode = GenMode::CULL_NONE;
+ state.cullmode = CullMode::None;
state.primitive = primitive;
return state;
}
@@ -260,7 +274,7 @@ RasterizationState GetNoCullRasterizationState(PrimitiveType primitive)
RasterizationState GetCullBackFaceRasterizationState(PrimitiveType primitive)
{
RasterizationState state = {};
- state.cullmode = GenMode::CULL_BACK;
+ state.cullmode = CullMode::Back;
state.primitive = primitive;
return state;
}
@@ -277,7 +291,7 @@ DepthState GetNoDepthTestingDepthState()
DepthState state = {};
state.testenable = false;
state.updateenable = false;
- state.func = ZMode::ALWAYS;
+ state.func = CompareMode::Always;
return state;
}
@@ -286,7 +300,7 @@ DepthState GetAlwaysWriteDepthState()
DepthState state = {};
state.testenable = true;
state.updateenable = true;
- state.func = ZMode::ALWAYS;
+ state.func = CompareMode::Always;
return state;
}
@@ -302,10 +316,10 @@ BlendingState GetNoBlendingBlendState()
BlendingState state = {};
state.usedualsrc = false;
state.blendenable = false;
- state.srcfactor = BlendMode::ONE;
- state.srcfactoralpha = BlendMode::ONE;
- state.dstfactor = BlendMode::ZERO;
- state.dstfactoralpha = BlendMode::ZERO;
+ state.srcfactor = SrcBlendFactor::One;
+ state.srcfactoralpha = SrcBlendFactor::One;
+ state.dstfactor = DstBlendFactor::Zero;
+ state.dstfactoralpha = DstBlendFactor::Zero;
state.logicopenable = false;
state.colorupdate = true;
state.alphaupdate = true;
@@ -317,10 +331,10 @@ BlendingState GetNoColorWriteBlendState()
BlendingState state = {};
state.usedualsrc = false;
state.blendenable = false;
- state.srcfactor = BlendMode::ONE;
- state.srcfactoralpha = BlendMode::ONE;
- state.dstfactor = BlendMode::ZERO;
- state.dstfactoralpha = BlendMode::ZERO;
+ state.srcfactor = SrcBlendFactor::One;
+ state.srcfactoralpha = SrcBlendFactor::One;
+ state.dstfactor = DstBlendFactor::Zero;
+ state.dstfactoralpha = DstBlendFactor::Zero;
state.logicopenable = false;
state.colorupdate = false;
state.alphaupdate = false;
diff --git a/Source/Core/VideoCommon/RenderState.h b/Source/Core/VideoCommon/RenderState.h
index f5bf085d72..1cc87eea51 100644
--- a/Source/Core/VideoCommon/RenderState.h
+++ b/Source/Core/VideoCommon/RenderState.h
@@ -28,7 +28,7 @@ union RasterizationState
bool operator==(const RasterizationState& rhs) const { return hex == rhs.hex; }
bool operator!=(const RasterizationState& rhs) const { return hex != rhs.hex; }
bool operator<(const RasterizationState& rhs) const { return hex < rhs.hex; }
- BitField<0, 2, GenMode::CullMode> cullmode;
+ BitField<0, 2, CullMode> cullmode;
BitField<3, 2, PrimitiveType> primitive;
u32 hex;
@@ -59,7 +59,7 @@ union DepthState
bool operator<(const DepthState& rhs) const { return hex < rhs.hex; }
BitField<0, 1, u32> testenable;
BitField<1, 1, u32> updateenable;
- BitField<2, 3, ZMode::CompareMode> func;
+ BitField<2, 3, CompareMode> func;
u32 hex;
};
@@ -85,11 +85,11 @@ union BlendingState
BitField<5, 1, u32> subtract;
BitField<6, 1, u32> subtractAlpha;
BitField<7, 1, u32> usedualsrc;
- BitField<8, 3, BlendMode::BlendFactor> dstfactor;
- BitField<11, 3, BlendMode::BlendFactor> srcfactor;
- BitField<14, 3, BlendMode::BlendFactor> dstfactoralpha;
- BitField<17, 3, BlendMode::BlendFactor> srcfactoralpha;
- BitField<20, 4, BlendMode::LogicOp> logicmode;
+ BitField<8, 3, DstBlendFactor> dstfactor;
+ BitField<11, 3, SrcBlendFactor> srcfactor;
+ BitField<14, 3, DstBlendFactor> dstfactoralpha;
+ BitField<17, 3, SrcBlendFactor> srcfactoralpha;
+ BitField<20, 4, LogicOp> logicmode;
u32 hex;
};
diff --git a/Source/Core/VideoCommon/SamplerCommon.h b/Source/Core/VideoCommon/SamplerCommon.h
index a16ba0fcd4..3b36eab09c 100644
--- a/Source/Core/VideoCommon/SamplerCommon.h
+++ b/Source/Core/VideoCommon/SamplerCommon.h
@@ -16,13 +16,13 @@ namespace SamplerCommon
template <class T>
constexpr bool IsBpTexMode0PointFiltering(const T& tm0)
{
- return tm0.min_filter < 4 && !tm0.mag_filter;
+ return tm0.min_filter == FilterMode::Near && tm0.mag_filter == FilterMode::Near;
}
// Check if the minification filter has mipmap based filtering modes enabled.
template <class T>
constexpr bool AreBpTexMode0MipmapsEnabled(const T& tm0)
{
- return (tm0.min_filter & 3) != 0;
+ return tm0.mipmap_filter != MipMode::None;
}
} // namespace SamplerCommon
diff --git a/Source/Core/VideoCommon/ShaderCache.cpp b/Source/Core/VideoCommon/ShaderCache.cpp
index 7383dc6595..a0b809adf0 100644
--- a/Source/Core/VideoCommon/ShaderCache.cpp
+++ b/Source/Core/VideoCommon/ShaderCache.cpp
@@ -1115,7 +1115,7 @@ void ShaderCache::QueueUberShaderPipelines()
{
// uint_output is only ever enabled when logic ops are enabled.
config.blending_state.logicopenable = true;
- config.blending_state.logicmode = BlendMode::AND;
+ config.blending_state.logicmode = LogicOp::And;
}
auto iter = m_gx_uber_pipeline_cache.find(config);
diff --git a/Source/Core/VideoCommon/TextureCacheBase.cpp b/Source/Core/VideoCommon/TextureCacheBase.cpp
index ed9450465a..b791d259f1 100644
--- a/Source/Core/VideoCommon/TextureCacheBase.cpp
+++ b/Source/Core/VideoCommon/TextureCacheBase.cpp
@@ -1187,12 +1187,12 @@ TextureCacheBase::TCacheEntry* TextureCacheBase::Load(const u32 stage)
const u32 address = (tex.texImage3[id].image_base /* & 0x1FFFFF*/) << 5;
u32 width = tex.texImage0[id].width + 1;
u32 height = tex.texImage0[id].height + 1;
- const TextureFormat texformat = static_cast<TextureFormat>(tex.texImage0[id].format);
+ const TextureFormat texformat = tex.texImage0[id].format;
const u32 tlutaddr = tex.texTlut[id].tmem_offset << 9;
- const TLUTFormat tlutfmt = static_cast<TLUTFormat>(tex.texTlut[id].tlut_format);
+ const TLUTFormat tlutfmt = tex.texTlut[id].tlut_format;
const bool use_mipmaps = SamplerCommon::AreBpTexMode0MipmapsEnabled(tex.texMode0[id]);
u32 tex_levels = use_mipmaps ? ((tex.texMode1[id].max_lod + 0xf) / 0x10 + 1) : 1;
- const bool from_tmem = tex.texImage1[id].image_type != 0;
+ const bool from_tmem = tex.texImage1[id].cache_manually_managed != 0;
const u32 tmem_address_even = from_tmem ? tex.texImage1[id].tmem_even * TMEM_LINE_SIZE : 0;
const u32 tmem_address_odd = from_tmem ? tex.texImage2[id].tmem_odd * TMEM_LINE_SIZE : 0;
@@ -2204,7 +2204,7 @@ void TextureCacheBase::CopyRenderTargetToTexture(
if (copy_to_ram)
{
EFBCopyFilterCoefficients coefficients = GetRAMCopyFilterCoefficients(filter_coefficients);
- PEControl::PixelFormat srcFormat = bpmem.zcontrol.pixel_format;
+ PixelFormat srcFormat = bpmem.zcontrol.pixel_format;
EFBCopyParams format(srcFormat, dstFormat, is_depth_copy, isIntensity,
NeedsCopyFilterInShader(coefficients));
diff --git a/Source/Core/VideoCommon/TextureCacheBase.h b/Source/Core/VideoCommon/TextureCacheBase.h
index 9245f7bf3f..599f1c2a79 100644
--- a/Source/Core/VideoCommon/TextureCacheBase.h
+++ b/Source/Core/VideoCommon/TextureCacheBase.h
@@ -50,8 +50,8 @@ struct TextureAndTLUTFormat
struct EFBCopyParams
{
- EFBCopyParams(PEControl::PixelFormat efb_format_, EFBCopyFormat copy_format_, bool depth_,
- bool yuv_, bool copy_filter_)
+ EFBCopyParams(PixelFormat efb_format_, EFBCopyFormat copy_format_, bool depth_, bool yuv_,
+ bool copy_filter_)
: efb_format(efb_format_), copy_format(copy_format_), depth(depth_), yuv(yuv_),
copy_filter(copy_filter_)
{
@@ -63,7 +63,7 @@ struct EFBCopyParams
std::tie(rhs.efb_format, rhs.copy_format, rhs.depth, rhs.yuv, rhs.copy_filter);
}
- PEControl::PixelFormat efb_format;
+ PixelFormat efb_format;
EFBCopyFormat copy_format;
bool depth;
bool yuv;
diff --git a/Source/Core/VideoCommon/TextureConversionShader.cpp b/Source/Core/VideoCommon/TextureConversionShader.cpp
index 66607da4dc..1bddf9cf30 100644
--- a/Source/Core/VideoCommon/TextureConversionShader.cpp
+++ b/Source/Core/VideoCommon/TextureConversionShader.cpp
@@ -127,13 +127,13 @@ static void WriteSampleFunction(ShaderCode& code, const EFBCopyParams& params, A
{
switch (params.efb_format)
{
- case PEControl::RGB8_Z24:
+ case PixelFormat::RGB8_Z24:
code.Write("RGBA8ToRGB8(");
break;
- case PEControl::RGBA6_Z24:
+ case PixelFormat::RGBA6_Z24:
code.Write("RGBA8ToRGBA6(");
break;
- case PEControl::RGB565_Z16:
+ case PixelFormat::RGB565_Z16:
code.Write("RGBA8ToRGB565(");
break;
default:
diff --git a/Source/Core/VideoCommon/TextureConverterShaderGen.cpp b/Source/Core/VideoCommon/TextureConverterShaderGen.cpp
index 9c0ccfe268..5dfae8212d 100644
--- a/Source/Core/VideoCommon/TextureConverterShaderGen.cpp
+++ b/Source/Core/VideoCommon/TextureConverterShaderGen.cpp
@@ -19,7 +19,7 @@ TCShaderUid GetShaderUid(EFBCopyFormat dst_format, bool is_depth_copy, bool is_i
UidData* const uid_data = out.GetUidData();
uid_data->dst_format = dst_format;
- uid_data->efb_has_alpha = bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24;
+ uid_data->efb_has_alpha = bpmem.zcontrol.pixel_format == PixelFormat::RGBA6_Z24;
uid_data->is_depth_copy = is_depth_copy;
uid_data->is_intensity = is_intensity;
uid_data->scale_by_half = scale_by_half;
diff --git a/Source/Core/VideoCommon/TextureDecoder.h b/Source/Core/VideoCommon/TextureDecoder.h
index 7a08a6514a..e4b25e50ec 100644
--- a/Source/Core/VideoCommon/TextureDecoder.h
+++ b/Source/Core/VideoCommon/TextureDecoder.h
@@ -6,6 +6,7 @@
#include <tuple>
#include "Common/CommonTypes.h"
+#include "Common/EnumFormatter.h"
enum
{
@@ -32,8 +33,17 @@ enum class TextureFormat
// Special texture format used to represent YUVY xfb copies.
// They aren't really textures, but they share so much hardware and usecases that it makes sense
// to emulate them as part of texture cache.
+ // This isn't a real value that can be used on console; it only exists for ease of implementation.
XFB = 0xF,
};
+template <>
+struct fmt::formatter<TextureFormat> : EnumFormatter<TextureFormat::CMPR>
+{
+ static constexpr array_type names = {"I4", "I8", "IA4", "IA8", "RGB565",
+ "RGB5A3", "RGBA8", nullptr, "C4", "C8",
+ "C14X2", nullptr, nullptr, nullptr, "CMPR"};
+ formatter() : EnumFormatter(names) {}
+};
static inline bool IsColorIndexed(TextureFormat format)
{
@@ -82,8 +92,20 @@ enum class EFBCopyFormat
// Special texture format used to represent YUVY xfb copies.
// They aren't really textures, but they share so much hardware and usecases that it makes sense
// to emulate them as part of texture cache.
+ // This isn't a real value that can be used on console; it only exists for ease of implementation.
XFB = 0xF,
};
+template <>
+struct fmt::formatter<EFBCopyFormat> : EnumFormatter<EFBCopyFormat::GB8>
+{
+ static constexpr array_type names = {
+ "R4/I4/Z4", "R8/I8/Z8H (?)", "RA4/IA4", "RA8/IA8 (Z16 too?)",
+ "RGB565", "RGB5A3", "RGBA8", "A8",
+ "R8/I8/Z8H", "G8/Z8M", "B8/Z8L", "RG8/Z16R (Note: G and R are reversed)",
+ "GB8/Z16L",
+ };
+ formatter() : EnumFormatter(names) {}
+};
enum class TLUTFormat
{
@@ -92,6 +114,11 @@ enum class TLUTFormat
RGB565 = 0x1,
RGB5A3 = 0x2,
};
+template <>
+struct fmt::formatter<TLUTFormat> : EnumFormatter<TLUTFormat::RGB5A3>
+{
+ formatter() : EnumFormatter({"IA8", "RGB565", "RGB5A3"}) {}
+};
static inline bool IsValidTLUTFormat(TLUTFormat tlutfmt)
{
diff --git a/Source/Core/VideoCommon/UberShaderPixel.cpp b/Source/Core/VideoCommon/UberShaderPixel.cpp
index 721912a3f3..c15ab12cc8 100644
--- a/Source/Core/VideoCommon/UberShaderPixel.cpp
+++ b/Source/Core/VideoCommon/UberShaderPixel.cpp
@@ -22,12 +22,12 @@ PixelShaderUid GetPixelShaderUid()
pixel_ubershader_uid_data* const uid_data = out.GetUidData();
uid_data->num_texgens = xfmem.numTexGen.numTexGens;
- uid_data->early_depth =
- bpmem.UseEarlyDepthTest() &&
- (g_ActiveConfig.bFastDepthCalc || bpmem.alpha_test.TestResult() == AlphaTest::UNDETERMINED) &&
- !(bpmem.zmode.testenable && bpmem.genMode.zfreeze);
+ uid_data->early_depth = bpmem.UseEarlyDepthTest() &&
+ (g_ActiveConfig.bFastDepthCalc ||
+ bpmem.alpha_test.TestResult() == AlphaTestResult::Undetermined) &&
+ !(bpmem.zmode.testenable && bpmem.genMode.zfreeze);
uid_data->per_pixel_depth =
- (bpmem.ztex2.op != ZTEXTURE_DISABLE && bpmem.UseLateDepthTest()) ||
+ (bpmem.ztex2.op != ZTexOp::Disabled && bpmem.UseLateDepthTest()) ||
(!g_ActiveConfig.bFastDepthCalc && bpmem.zmode.testenable && !uid_data->early_depth) ||
(bpmem.zmode.testenable && bpmem.genMode.zfreeze);
uid_data->uint_output = bpmem.blendmode.UseLogicOp();
@@ -367,21 +367,21 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
"// which are common to both color and alpha channels\n"
"bool tevCompare(uint op, int3 color_A, int3 color_B) {{\n"
" switch (op) {{\n"
- " case 0u: // TEVCMP_R8_GT\n"
+ " case 0u: // TevCompareMode::R8, TevComparison::GT\n"
" return (color_A.r > color_B.r);\n"
- " case 1u: // TEVCMP_R8_EQ\n"
+ " case 1u: // TevCompareMode::R8, TevComparison::EQ\n"
" return (color_A.r == color_B.r);\n"
- " case 2u: // TEVCMP_GR16_GT\n"
+ " case 2u: // TevCompareMode::GR16, TevComparison::GT\n"
" int A_16 = (color_A.r | (color_A.g << 8));\n"
" int B_16 = (color_B.r | (color_B.g << 8));\n"
" return A_16 > B_16;\n"
- " case 3u: // TEVCMP_GR16_EQ\n"
+ " case 3u: // TevCompareMode::GR16, TevComparison::EQ\n"
" return (color_A.r == color_B.r && color_A.g == color_B.g);\n"
- " case 4u: // TEVCMP_BGR24_GT\n"
+ " case 4u: // TevCompareMode::BGR24, TevComparison::GT\n"
" int A_24 = (color_A.r | (color_A.g << 8) | (color_A.b << 16));\n"
" int B_24 = (color_B.r | (color_B.g << 8) | (color_B.b << 16));\n"
" return A_24 > B_24;\n"
- " case 5u: // TEVCMP_BGR24_EQ\n"
+ " case 5u: // TevCompareMode::BGR24, TevComparison::EQ\n"
" return (color_A.r == color_B.r && color_A.g == color_B.g && color_A.b == color_B.b);\n"
" default:\n"
" return false;\n"
@@ -814,29 +814,29 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
" s.AlphaBump = indcoord[bs - 1u];\n"
" switch(fmt)\n"
" {{\n"
- " case {}u:\n",
- ITF_8);
+ " case {:s}:\n",
+ IndTexFormat::ITF_8);
out.Write(" indcoord.x = indcoord.x + ((bias & 1u) != 0u ? -128 : 0);\n"
" indcoord.y = indcoord.y + ((bias & 2u) != 0u ? -128 : 0);\n"
" indcoord.z = indcoord.z + ((bias & 4u) != 0u ? -128 : 0);\n"
" s.AlphaBump = s.AlphaBump & 0xf8;\n"
" break;\n"
- " case {}u:\n",
- ITF_5);
+ " case {:s}:\n",
+ IndTexFormat::ITF_5);
out.Write(" indcoord.x = (indcoord.x & 0x1f) + ((bias & 1u) != 0u ? 1 : 0);\n"
" indcoord.y = (indcoord.y & 0x1f) + ((bias & 2u) != 0u ? 1 : 0);\n"
" indcoord.z = (indcoord.z & 0x1f) + ((bias & 4u) != 0u ? 1 : 0);\n"
" s.AlphaBump = s.AlphaBump & 0xe0;\n"
" break;\n"
- " case {}u:\n",
- ITF_4);
+ " case {:s}:\n",
+ IndTexFormat::ITF_4);
out.Write(" indcoord.x = (indcoord.x & 0x0f) + ((bias & 1u) != 0u ? 1 : 0);\n"
" indcoord.y = (indcoord.y & 0x0f) + ((bias & 2u) != 0u ? 1 : 0);\n"
" indcoord.z = (indcoord.z & 0x0f) + ((bias & 4u) != 0u ? 1 : 0);\n"
" s.AlphaBump = s.AlphaBump & 0xf0;\n"
" break;\n"
- " case {}u:\n",
- ITF_3);
+ " case {:s}:\n",
+ IndTexFormat::ITF_3);
out.Write(" indcoord.x = (indcoord.x & 0x07) + ((bias & 1u) != 0u ? 1 : 0);\n"
" indcoord.y = (indcoord.y & 0x07) + ((bias & 2u) != 0u ? 1 : 0);\n"
" indcoord.z = (indcoord.z & 0x07) + ((bias & 4u) != 0u ? 1 : 0);\n"
@@ -924,7 +924,7 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
out.Write(" bool color_clamp = bool({});\n",
BitfieldExtract("ss.cc", TevStageCombiner().colorC.clamp));
out.Write(" uint color_shift = {};\n",
- BitfieldExtract("ss.cc", TevStageCombiner().colorC.shift));
+ BitfieldExtract("ss.cc", TevStageCombiner().colorC.scale));
out.Write(" uint color_dest = {};\n",
BitfieldExtract("ss.cc", TevStageCombiner().colorC.dest));
@@ -949,12 +949,12 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
" }} else {{ // Compare mode\n"
" // op 6 and 7 do a select per color channel\n"
" if (color_compare_op == 6u) {{\n"
- " // TEVCMP_RGB8_GT\n"
+ " // TevCompareMode::RGB8, TevComparison::GT\n"
" color.r = (color_A.r > color_B.r) ? color_C.r : 0;\n"
" color.g = (color_A.g > color_B.g) ? color_C.g : 0;\n"
" color.b = (color_A.b > color_B.b) ? color_C.b : 0;\n"
" }} else if (color_compare_op == 7u) {{\n"
- " // TEVCMP_RGB8_EQ\n"
+ " // TevCompareMode::RGB8, TevComparison::EQ\n"
" color.r = (color_A.r == color_B.r) ? color_C.r : 0;\n"
" color.g = (color_A.g == color_B.g) ? color_C.g : 0;\n"
" color.b = (color_A.b == color_B.b) ? color_C.b : 0;\n"
@@ -990,7 +990,7 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
out.Write(" bool alpha_clamp = bool({});\n",
BitfieldExtract("ss.ac", TevStageCombiner().alphaC.clamp));
out.Write(" uint alpha_shift = {};\n",
- BitfieldExtract("ss.ac", TevStageCombiner().alphaC.shift));
+ BitfieldExtract("ss.ac", TevStageCombiner().alphaC.scale));
out.Write(" uint alpha_dest = {};\n",
BitfieldExtract("ss.ac", TevStageCombiner().alphaC.dest));
@@ -1016,10 +1016,10 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
"true, alpha_shift);\n"
" }} else {{ // Compare mode\n"
" if (alpha_compare_op == 6u) {{\n"
- " // TEVCMP_A8_GT\n"
+ " // TevCompareMode::A8, TevComparison::GT\n"
" alpha = (alpha_A > alpha_B) ? alpha_C : 0;\n"
" }} else if (alpha_compare_op == 7u) {{\n"
- " // TEVCMP_A8_EQ\n"
+ " // TevCompareMode::A8, TevComparison::EQ\n"
" alpha = (alpha_A == alpha_B) ? alpha_C : 0;\n"
" }} else {{\n"
" // All remaining alpha compare ops actually compare the color channels\n"
@@ -1157,8 +1157,8 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
out.Write(" // Fog\n"
" uint fog_function = {};\n",
BitfieldExtract("bpmem_fogParam3", FogParam3().fsel));
- out.Write(" if (fog_function != 0u) {{\n"
- " // TODO: This all needs to be converted from float to fixed point\n"
+ out.Write(" if (fog_function != {:s}) {{\n", FogType::Off);
+ out.Write(" // TODO: This all needs to be converted from float to fixed point\n"
" float ze;\n"
" if ({} == 0u) {{\n",
BitfieldExtract("bpmem_fogParam3", FogParam3().proj));
@@ -1188,23 +1188,27 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config,
" }}\n"
"\n"
" float fog = clamp(ze - " I_FOGF ".y, 0.0, 1.0);\n"
- "\n"
- " if (fog_function > 3u) {{\n"
- " switch (fog_function) {{\n"
- " case 4u:\n"
+ "\n");
+ out.Write(" if (fog_function >= {:s}) {{\n", FogType::Exp);
+ out.Write(" switch (fog_function) {{\n"
+ " case {:s}:\n"
" fog = 1.0 - exp2(-8.0 * fog);\n"
- " break;\n"
- " case 5u:\n"
+ " break;\n",
+ FogType::Exp);
+ out.Write(" case {:s}:\n"
" fog = 1.0 - exp2(-8.0 * fog * fog);\n"
- " break;\n"
- " case 6u:\n"
+ " break;\n",
+ FogType::ExpSq);
+ out.Write(" case {:s}:\n"
" fog = exp2(-8.0 * (1.0 - fog));\n"
- " break;\n"
- " case 7u:\n"
+ " break;\n",
+ FogType::BackwardsExp);
+ out.Write(" case {:s}:\n"
" fog = 1.0 - fog;\n"
" fog = exp2(-8.0 * fog * fog);\n"
- " break;\n"
- " }}\n"
+ " break;\n",
+ FogType::BackwardsExpSq);
+ out.Write(" }}\n"
" }}\n"
"\n"
" int ifog = iround(fog * 256.0);\n"
diff --git a/Source/Core/VideoCommon/VertexLoaderManager.cpp b/Source/Core/VideoCommon/VertexLoaderManager.cpp
index 4dcc211178..fdb63679f5 100644
--- a/Source/Core/VideoCommon/VertexLoaderManager.cpp
+++ b/Source/Core/VideoCommon/VertexLoaderManager.cpp
@@ -293,7 +293,7 @@ int RunVertices(int vtx_attr_group, int primitive, int count, DataReader src, bo
// if cull mode is CULL_ALL, tell VertexManager to skip triangles and quads.
// They still need to go through vertex loading, because we need to calculate a zfreeze refrence
// slope.
- bool cullall = (bpmem.genMode.cullmode == GenMode::CULL_ALL && primitive < 5);
+ bool cullall = (bpmem.genMode.cullmode == CullMode::All && primitive < 5);
DataReader dst = g_vertex_manager->PrepareForAdditionalData(
primitive, count, loader->m_native_vtx_decl.stride, cullall);