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 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 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(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(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(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(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(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(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(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(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 #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(ti0.format); - const TLUTFormat tlutfmt = static_cast(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& 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& 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& 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(new_format), - static_cast(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(old_format), - static_cast(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 : EnumFormatter { - TEVCMP_R8 = 0, - TEVCMP_GR16 = 1, - TEVCMP_BGR24 = 2, - TEVCMP_RGB8 = 3 + formatter() : EnumFormatter({"1", "2", "4", "0.5"}) {} }; // TEV combiner operator -enum : u32 +enum class TevOp : 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 + Add = 0, + Sub = 1, +}; +template <> +struct fmt::formatter : EnumFormatter +{ + formatter() : EnumFormatter({"Add", "Subtract"}) {} +}; + +enum class TevCompareMode : u32 +{ + R8 = 0, + GR16 = 1, + BGR24 = 2, + RGB8 = 3, + A8 = RGB8, +}; +template <> +struct fmt::formatter : EnumFormatter +{ + formatter() : EnumFormatter({"R8", "GR16", "BGR24", "RGB8 / A8"}) {} +}; + +enum class TevComparison : u32 +{ + GT = 0, + EQ = 1, +}; +template <> +struct fmt::formatter : EnumFormatter +{ + formatter() : EnumFormatter({"Greater than", "Equal to"}) {} }; // TEV color combiner input -enum : u32 +enum class TevColorArg : 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 + 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 : EnumFormatter +{ + 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 : EnumFormatter +{ + 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 : EnumFormatter +{ + formatter() : EnumFormatter({"prev", "c0", "c1", "c2"}) {} }; // Z-texture formats -enum : u32 +enum class ZTexFormat : u32 { - TEV_ZTEX_TYPE_U8 = 0, - TEV_ZTEX_TYPE_U16 = 1, - TEV_ZTEX_TYPE_U24 = 2 + U8 = 0, + U16 = 1, + U24 = 2 +}; +template <> +struct fmt::formatter : EnumFormatter +{ + 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 : EnumFormatter +{ + formatter() : EnumFormatter({"Disabled", "Add", "Replace"}) {} }; // TEV bias value -enum : u32 +enum class TevBias : u32 { - TEVBIAS_ZERO = 0, - TEVBIAS_ADDHALF = 1, - TEVBIAS_SUBHALF = 2, - TEVBIAS_COMPARE = 3 + Zero = 0, + AddHalf = 1, + Subhalf = 2, + Compare = 3 +}; +template <> +struct fmt::formatter : EnumFormatter +{ + 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 : EnumFormatter +{ + formatter() : EnumFormatter({"ITF_8", "ITF_5", "ITF_4", "ITF_3"}) {} +}; // Indirect texture bias -enum : u32 +enum class IndTexBias : u32 { - ITB_NONE = 0, - ITB_S = 1, - ITB_T = 2, - ITB_ST = 3, - ITB_U = 4, - ITB_SU = 5, - ITB_TU = 6, - ITB_STU = 7 + 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 : EnumFormatter +{ + 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 : EnumFormatter +{ + 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 : EnumFormatter +{ + 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 : EnumFormatter +{ + 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 : EnumFormatter +{ + formatter() : EnumFormatter({"Clamp", "Repeat", "Mirror"}) {} +}; + +enum class MipMode : u32 +{ + None = 0, + Point = 1, + Linear = 2, +}; +template <> +struct fmt::formatter : EnumFormatter +{ + formatter() : EnumFormatter({"None", "Mip point", "Mip linear"}) {} +}; + +enum class FilterMode : u32 +{ + Near = 0, + Linear = 1, +}; +template <> +struct fmt::formatter : EnumFormatter +{ + formatter() : EnumFormatter({"Near", "Linear"}) {} +}; + +enum class LODType : u32 +{ + Edge = 0, + Diagonal = 1, +}; +template <> +struct fmt::formatter : EnumFormatter +{ + formatter() : EnumFormatter({"Edge LOD", "Diagonal LOD"}) {} +}; + +enum class MaxAnsio +{ + One = 0, + Two = 1, + Four = 2, +}; +template <> +struct fmt::formatter : EnumFormatter +{ + formatter() : EnumFormatter({"1", "2 (requires edge LOD)", "4 (requires edge LOD)"}) {} +}; union TexMode0 { - enum TextureFilter : u32 - { - TEXF_NONE = 0, - TEXF_POINT = 1, - TEXF_LINEAR = 2 - }; - - 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; - }; + 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 +enum class CullMode : u32 +{ + None = 0, + Back = 1, // cull back-facing primitives + Front = 2, // cull front-facing primitives + All = 3, // cull all primitives +}; +template <> +struct fmt::formatter : EnumFormatter +{ + static constexpr array_type names = { + "None", + "Back-facing primitives only", + "Front-facing primitives only", + "All primitives", + }; + formatter() : EnumFormatter(names) {} +}; union GenMode { - 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 - }; - 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 : EnumFormatter +{ + 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 : EnumFormatter +{ + 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) {} +}; + +enum class DstBlendFactor : u32 +{ + Zero = 0, + One = 1, + SrcClr = 2, + InvSrcClr = 3, + SrcAlpha = 4, + InvSrcAlpha = 5, + DstAlpha = 6, + InvDstAlpha = 7 +}; +template <> +struct fmt::formatter : EnumFormatter +{ + 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 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 : EnumFormatter +{ + 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) {} +}; union BlendMode { - 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 - }; - - 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 - }; - - 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; + 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 : EnumFormatter +{ + formatter() : EnumFormatter({"Perspective", "Orthographic"}) {} +}; + +enum class FogType : u32 +{ + Off = 0, + Linear = 2, + Exp = 4, + ExpSq = 5, + BackwardsExp = 6, + BackwardsExpSq = 7, +}; +template <> +struct fmt::formatter : EnumFormatter +{ + 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; }; +enum class CompareMode : u32 +{ + Never = 0, + Less = 1, + Equal = 2, + LEqual = 3, + Greater = 4, + NEqual = 5, + GEqual = 6, + Always = 7 +}; +template <> +struct fmt::formatter : EnumFormatter +{ + static constexpr array_type names = {"Never", "Less", "Equal", "LEqual", + "Greater", "NEqual", "GEqual", "Always"}; + formatter() : EnumFormatter(names) {} +}; + union ZMode { - enum CompareMode : u32 - { - NEVER = 0, - LESS = 1, - EQUAL = 2, - LEQUAL = 3, - GREATER = 4, - NEQUAL = 5, - GEQUAL = 6, - ALWAYS = 7 - }; - - BitField<0, 1, u32> testenable; + 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 : EnumFormatter +{ + 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; }; +enum class 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. +}; +template <> +struct fmt::formatter : EnumFormatter +{ + static constexpr array_type names = {"RGB8_Z24", "RGBA6_Z24", "RGB565_Z16", "Z24", + "Y8", "U8", "V8", "YUV420"}; + formatter() : EnumFormatter(names) {} +}; + +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 : EnumFormatter +{ + 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 { - 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. - }; - - 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 - }; - 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 : EnumFormatter +{ + 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(); } +}; + +enum class AlphaTestOp : u32 +{ + And = 0, + Or = 1, + Xor = 2, + Xnor = 3 +}; +template <> +struct fmt::formatter : EnumFormatter +{ + formatter() : EnumFormatter({"And", "Or", "Xor", "Xnor"}) {} +}; + +enum class AlphaTestResult +{ + Undetermined = 0, + Fail = 1, + Pass = 2, }; union AlphaTest { - enum CompareMode : u32 - { - NEVER = 0, - LESS = 1, - EQUAL = 2, - LEQUAL = 3, - GREATER = 4, - NEQUAL = 5, - GEQUAL = 6, - ALWAYS = 7 - }; - - enum Op : u32 - { - AND = 0, - OR = 1, - XOR = 2, - XNOR = 3 - }; - 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 : EnumFormatter +{ + 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(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(bpmem.alpha_test.comp0), static_cast(bpmem.alpha_test.comp1), - static_cast(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(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; using uint4 = std::array; using int4 = std::array; +enum class SrcBlendFactor : u32; +enum class DstBlendFactor : u32; + struct PixelShaderConstants { std::array colors; @@ -45,10 +48,10 @@ struct PixelShaderConstants std::array 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 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 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 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 tev_scale_table_left{ - "", // SCALE_1 - " << 1", // SCALE_2 - " << 2", // SCALE_4 - "", // DIVIDE_2 + "", // Scale1 + " << 1", // Scale2 + " << 2", // Scale4 + "", // Divide2 }; static constexpr std::array 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 tev_lerp_bias{ "", " + 128", @@ -1341,15 +1351,15 @@ static void WriteTevRegular(ShaderCode& out, std::string_view components, int bi }; static constexpr std::array tev_bias_table{ - "", // ZERO, - " + 128", // ADDHALF, - " - 128", // SUBHALF, + "", // Zero, + " + 128", // AddHalf, + " - 128", // SubHalf, "", }; static constexpr std::array 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 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 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 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& 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(static_cast(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 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 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(tm1.min_lod)); lod_bias = SamplerCommon::AreBpTexMode0MipmapsEnabled(tm0) ? tm0.lod_bias * (256 / 32) : 0; // Address modes static constexpr std::array 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 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 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(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(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 #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 : EnumFormatter +{ + 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 : EnumFormatter +{ + 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 : EnumFormatter +{ + 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);