mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-22 22:00:39 -06:00
Convert BPMemory to BitField and enum class
Additional changes: - For TevStageCombiner's ColorCombiner and AlphaCombiner, op/comparison and scale/compare_mode have been split as there are different meanings and enums if bias is set to compare. (Shift has also been renamed to scale) - In TexMode0, min_filter has been split into min_mip and min_filter. - In TexImage1, image_type is now cache_manually_managed. - The unused bit in GenMode is now exposed. - LPSize's lineaspect is now named adjust_for_aspect_ratio.
This commit is contained in:
@ -15,7 +15,7 @@ void RasterizationState::Generate(const BPMemory& bp, PrimitiveType primitive_ty
|
||||
|
||||
// Back-face culling should be disabled for points/lines.
|
||||
if (primitive_type != PrimitiveType::Triangles && primitive_type != PrimitiveType::TriangleStrip)
|
||||
cullmode = GenMode::CULL_NONE;
|
||||
cullmode = CullMode::None;
|
||||
}
|
||||
|
||||
RasterizationState& RasterizationState::operator=(const RasterizationState& rhs)
|
||||
@ -47,14 +47,27 @@ DepthState& DepthState::operator=(const DepthState& rhs)
|
||||
// ONE on blending. As the backends may emulate this framebuffer
|
||||
// configuration with an alpha channel, we just drop all references
|
||||
// to the destination alpha channel.
|
||||
static BlendMode::BlendFactor RemoveDstAlphaUsage(BlendMode::BlendFactor factor)
|
||||
static SrcBlendFactor RemoveDstAlphaUsage(SrcBlendFactor factor)
|
||||
{
|
||||
switch (factor)
|
||||
{
|
||||
case BlendMode::DSTALPHA:
|
||||
return BlendMode::ONE;
|
||||
case BlendMode::INVDSTALPHA:
|
||||
return BlendMode::ZERO;
|
||||
case SrcBlendFactor::DstAlpha:
|
||||
return SrcBlendFactor::One;
|
||||
case SrcBlendFactor::InvDstAlpha:
|
||||
return SrcBlendFactor::Zero;
|
||||
default:
|
||||
return factor;
|
||||
}
|
||||
}
|
||||
|
||||
static DstBlendFactor RemoveDstAlphaUsage(DstBlendFactor factor)
|
||||
{
|
||||
switch (factor)
|
||||
{
|
||||
case DstBlendFactor::DstAlpha:
|
||||
return DstBlendFactor::One;
|
||||
case DstBlendFactor::InvDstAlpha:
|
||||
return DstBlendFactor::Zero;
|
||||
default:
|
||||
return factor;
|
||||
}
|
||||
@ -64,14 +77,14 @@ static BlendMode::BlendFactor RemoveDstAlphaUsage(BlendMode::BlendFactor factor)
|
||||
// the alpha component, CLR and ALPHA are indentical. So just always
|
||||
// use ALPHA as this makes it easier for the backends to use the second
|
||||
// alpha value of dual source blending.
|
||||
static BlendMode::BlendFactor RemoveSrcColorUsage(BlendMode::BlendFactor factor)
|
||||
static DstBlendFactor RemoveSrcColorUsage(DstBlendFactor factor)
|
||||
{
|
||||
switch (factor)
|
||||
{
|
||||
case BlendMode::SRCCLR:
|
||||
return BlendMode::SRCALPHA;
|
||||
case BlendMode::INVSRCCLR:
|
||||
return BlendMode::INVSRCALPHA;
|
||||
case DstBlendFactor::SrcClr:
|
||||
return DstBlendFactor::SrcAlpha;
|
||||
case DstBlendFactor::InvSrcClr:
|
||||
return DstBlendFactor::InvSrcAlpha;
|
||||
default:
|
||||
return factor;
|
||||
}
|
||||
@ -79,14 +92,14 @@ static BlendMode::BlendFactor RemoveSrcColorUsage(BlendMode::BlendFactor factor)
|
||||
|
||||
// Same as RemoveSrcColorUsage, but because of the overlapping enum,
|
||||
// this must be written as another function.
|
||||
static BlendMode::BlendFactor RemoveDstColorUsage(BlendMode::BlendFactor factor)
|
||||
static SrcBlendFactor RemoveDstColorUsage(SrcBlendFactor factor)
|
||||
{
|
||||
switch (factor)
|
||||
{
|
||||
case BlendMode::DSTCLR:
|
||||
return BlendMode::DSTALPHA;
|
||||
case BlendMode::INVDSTCLR:
|
||||
return BlendMode::INVDSTALPHA;
|
||||
case SrcBlendFactor::DstClr:
|
||||
return SrcBlendFactor::DstAlpha;
|
||||
case SrcBlendFactor::InvDstClr:
|
||||
return SrcBlendFactor::InvDstAlpha;
|
||||
default:
|
||||
return factor;
|
||||
}
|
||||
@ -97,11 +110,11 @@ void BlendingState::Generate(const BPMemory& bp)
|
||||
// Start with everything disabled.
|
||||
hex = 0;
|
||||
|
||||
bool target_has_alpha = bp.zcontrol.pixel_format == PEControl::RGBA6_Z24;
|
||||
bool alpha_test_may_success = bp.alpha_test.TestResult() != AlphaTest::FAIL;
|
||||
bool target_has_alpha = bp.zcontrol.pixel_format == PixelFormat::RGBA6_Z24;
|
||||
bool alpha_test_may_succeed = bp.alpha_test.TestResult() != AlphaTestResult::Fail;
|
||||
|
||||
colorupdate = bp.blendmode.colorupdate && alpha_test_may_success;
|
||||
alphaupdate = bp.blendmode.alphaupdate && target_has_alpha && alpha_test_may_success;
|
||||
colorupdate = bp.blendmode.colorupdate && alpha_test_may_succeed;
|
||||
alphaupdate = bp.blendmode.alphaupdate && target_has_alpha && alpha_test_may_succeed;
|
||||
dstalpha = bp.dstalpha.enable && alphaupdate;
|
||||
usedualsrc = true;
|
||||
|
||||
@ -110,14 +123,14 @@ void BlendingState::Generate(const BPMemory& bp)
|
||||
{
|
||||
blendenable = true;
|
||||
subtractAlpha = subtract = true;
|
||||
srcfactoralpha = srcfactor = BlendMode::ONE;
|
||||
dstfactoralpha = dstfactor = BlendMode::ONE;
|
||||
srcfactoralpha = srcfactor = SrcBlendFactor::One;
|
||||
dstfactoralpha = dstfactor = DstBlendFactor::One;
|
||||
|
||||
if (dstalpha)
|
||||
{
|
||||
subtractAlpha = false;
|
||||
srcfactoralpha = BlendMode::ONE;
|
||||
dstfactoralpha = BlendMode::ZERO;
|
||||
srcfactoralpha = SrcBlendFactor::One;
|
||||
dstfactoralpha = DstBlendFactor::Zero;
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,22 +146,22 @@ void BlendingState::Generate(const BPMemory& bp)
|
||||
srcfactor = RemoveDstAlphaUsage(srcfactor);
|
||||
dstfactor = RemoveDstAlphaUsage(dstfactor);
|
||||
}
|
||||
// replaces SRCCLR with SRCALPHA and DSTCLR with DSTALPHA, it is important to
|
||||
// replaces SrcClr with SrcAlpha and DstClr with DstAlpha, it is important to
|
||||
// use the dst function for the src factor and vice versa
|
||||
srcfactoralpha = RemoveDstColorUsage(srcfactor);
|
||||
dstfactoralpha = RemoveSrcColorUsage(dstfactor);
|
||||
|
||||
if (dstalpha)
|
||||
{
|
||||
srcfactoralpha = BlendMode::ONE;
|
||||
dstfactoralpha = BlendMode::ZERO;
|
||||
srcfactoralpha = SrcBlendFactor::One;
|
||||
dstfactoralpha = DstBlendFactor::Zero;
|
||||
}
|
||||
}
|
||||
|
||||
// The logicop bit has the lowest priority
|
||||
else if (bp.blendmode.logicopenable)
|
||||
{
|
||||
if (bp.blendmode.logicmode == BlendMode::NOOP)
|
||||
if (bp.blendmode.logicmode == LogicOp::NoOp)
|
||||
{
|
||||
// Fast path for Kirby's Return to Dreamland, they use it with dstAlpha.
|
||||
colorupdate = false;
|
||||
@ -169,38 +182,39 @@ void BlendingState::Generate(const BPMemory& bp)
|
||||
|
||||
void BlendingState::ApproximateLogicOpWithBlending()
|
||||
{
|
||||
// Any of these which use SRC as srcFactor or DST as dstFactor won't be correct.
|
||||
// This is because the two are aliased to one another (see the enum).
|
||||
struct LogicOpApproximation
|
||||
{
|
||||
bool subtract;
|
||||
BlendMode::BlendFactor srcfactor;
|
||||
BlendMode::BlendFactor dstfactor;
|
||||
SrcBlendFactor srcfactor;
|
||||
DstBlendFactor dstfactor;
|
||||
};
|
||||
// TODO: This previously had a warning about SRC and DST being aliased and not to mix them,
|
||||
// but INVSRCCLR and INVDSTCLR were also aliased and were mixed.
|
||||
// Thus, NOR, EQUIV, INVERT, COPY_INVERTED, and OR_INVERTED duplicate(d) other values.
|
||||
static constexpr std::array<LogicOpApproximation, 16> approximations = {{
|
||||
{false, BlendMode::ZERO, BlendMode::ZERO}, // CLEAR
|
||||
{false, BlendMode::DSTCLR, BlendMode::ZERO}, // AND
|
||||
{true, BlendMode::ONE, BlendMode::INVSRCCLR}, // AND_REVERSE
|
||||
{false, BlendMode::ONE, BlendMode::ZERO}, // COPY
|
||||
{true, BlendMode::DSTCLR, BlendMode::ONE}, // AND_INVERTED
|
||||
{false, BlendMode::ZERO, BlendMode::ONE}, // NOOP
|
||||
{false, BlendMode::INVDSTCLR, BlendMode::INVSRCCLR}, // XOR
|
||||
{false, BlendMode::INVDSTCLR, BlendMode::ONE}, // OR
|
||||
{false, BlendMode::INVSRCCLR, BlendMode::INVDSTCLR}, // NOR
|
||||
{false, BlendMode::INVSRCCLR, BlendMode::ZERO}, // EQUIV
|
||||
{false, BlendMode::INVDSTCLR, BlendMode::INVDSTCLR}, // INVERT
|
||||
{false, BlendMode::ONE, BlendMode::INVDSTALPHA}, // OR_REVERSE
|
||||
{false, BlendMode::INVSRCCLR, BlendMode::INVSRCCLR}, // COPY_INVERTED
|
||||
{false, BlendMode::INVSRCCLR, BlendMode::ONE}, // OR_INVERTED
|
||||
{false, BlendMode::INVDSTCLR, BlendMode::INVSRCCLR}, // NAND
|
||||
{false, BlendMode::ONE, BlendMode::ONE}, // SET
|
||||
{false, SrcBlendFactor::Zero, DstBlendFactor::Zero}, // CLEAR
|
||||
{false, SrcBlendFactor::DstClr, DstBlendFactor::Zero}, // AND
|
||||
{true, SrcBlendFactor::One, DstBlendFactor::InvSrcClr}, // AND_REVERSE
|
||||
{false, SrcBlendFactor::One, DstBlendFactor::Zero}, // COPY
|
||||
{true, SrcBlendFactor::DstClr, DstBlendFactor::One}, // AND_INVERTED
|
||||
{false, SrcBlendFactor::Zero, DstBlendFactor::One}, // NOOP
|
||||
{false, SrcBlendFactor::InvDstClr, DstBlendFactor::InvSrcClr}, // XOR
|
||||
{false, SrcBlendFactor::InvDstClr, DstBlendFactor::One}, // OR
|
||||
{false, SrcBlendFactor::InvDstClr, DstBlendFactor::InvSrcClr}, // NOR
|
||||
{false, SrcBlendFactor::InvDstClr, DstBlendFactor::Zero}, // EQUIV
|
||||
{false, SrcBlendFactor::InvDstClr, DstBlendFactor::InvSrcClr}, // INVERT
|
||||
{false, SrcBlendFactor::One, DstBlendFactor::InvDstAlpha}, // OR_REVERSE
|
||||
{false, SrcBlendFactor::InvDstClr, DstBlendFactor::InvSrcClr}, // COPY_INVERTED
|
||||
{false, SrcBlendFactor::InvDstClr, DstBlendFactor::One}, // OR_INVERTED
|
||||
{false, SrcBlendFactor::InvDstClr, DstBlendFactor::InvSrcClr}, // NAND
|
||||
{false, SrcBlendFactor::One, DstBlendFactor::One}, // SET
|
||||
}};
|
||||
|
||||
logicopenable = false;
|
||||
blendenable = true;
|
||||
subtract = approximations[logicmode].subtract;
|
||||
srcfactor = approximations[logicmode].srcfactor;
|
||||
dstfactor = approximations[logicmode].dstfactor;
|
||||
subtract = approximations[u32(logicmode.Value())].subtract;
|
||||
srcfactor = approximations[u32(logicmode.Value())].srcfactor;
|
||||
dstfactor = approximations[u32(logicmode.Value())].dstfactor;
|
||||
}
|
||||
|
||||
BlendingState& BlendingState::operator=(const BlendingState& rhs)
|
||||
@ -217,20 +231,20 @@ void SamplerState::Generate(const BPMemory& bp, u32 index)
|
||||
|
||||
// GX can configure the mip filter to none. However, D3D and Vulkan can't express this in their
|
||||
// sampler states. Therefore, we set the min/max LOD to zero if this option is used.
|
||||
min_filter = (tm0.min_filter & 4) != 0 ? Filter::Linear : Filter::Point;
|
||||
mipmap_filter = (tm0.min_filter & 3) == TexMode0::TEXF_LINEAR ? Filter::Linear : Filter::Point;
|
||||
mag_filter = tm0.mag_filter != 0 ? Filter::Linear : Filter::Point;
|
||||
min_filter = tm0.min_filter == FilterMode::Linear ? Filter::Linear : Filter::Point;
|
||||
mipmap_filter = tm0.mipmap_filter == MipMode::Linear ? Filter::Linear : Filter::Point;
|
||||
mag_filter = tm0.mag_filter == FilterMode::Linear ? Filter::Linear : Filter::Point;
|
||||
|
||||
// If mipmaps are disabled, clamp min/max lod
|
||||
max_lod = SamplerCommon::AreBpTexMode0MipmapsEnabled(tm0) ? tm1.max_lod : 0;
|
||||
max_lod = SamplerCommon::AreBpTexMode0MipmapsEnabled(tm0) ? tm1.max_lod.Value() : 0;
|
||||
min_lod = std::min(max_lod.Value(), static_cast<u64>(tm1.min_lod));
|
||||
lod_bias = SamplerCommon::AreBpTexMode0MipmapsEnabled(tm0) ? tm0.lod_bias * (256 / 32) : 0;
|
||||
|
||||
// Address modes
|
||||
static constexpr std::array<AddressMode, 4> address_modes = {
|
||||
{AddressMode::Clamp, AddressMode::Repeat, AddressMode::MirroredRepeat, AddressMode::Repeat}};
|
||||
wrap_u = address_modes[tm0.wrap_s];
|
||||
wrap_v = address_modes[tm0.wrap_t];
|
||||
wrap_u = address_modes[u32(tm0.wrap_s.Value())];
|
||||
wrap_v = address_modes[u32(tm0.wrap_t.Value())];
|
||||
anisotropic_filtering = 0;
|
||||
}
|
||||
|
||||
@ -252,7 +266,7 @@ RasterizationState GetInvalidRasterizationState()
|
||||
RasterizationState GetNoCullRasterizationState(PrimitiveType primitive)
|
||||
{
|
||||
RasterizationState state = {};
|
||||
state.cullmode = GenMode::CULL_NONE;
|
||||
state.cullmode = CullMode::None;
|
||||
state.primitive = primitive;
|
||||
return state;
|
||||
}
|
||||
@ -260,7 +274,7 @@ RasterizationState GetNoCullRasterizationState(PrimitiveType primitive)
|
||||
RasterizationState GetCullBackFaceRasterizationState(PrimitiveType primitive)
|
||||
{
|
||||
RasterizationState state = {};
|
||||
state.cullmode = GenMode::CULL_BACK;
|
||||
state.cullmode = CullMode::Back;
|
||||
state.primitive = primitive;
|
||||
return state;
|
||||
}
|
||||
@ -277,7 +291,7 @@ DepthState GetNoDepthTestingDepthState()
|
||||
DepthState state = {};
|
||||
state.testenable = false;
|
||||
state.updateenable = false;
|
||||
state.func = ZMode::ALWAYS;
|
||||
state.func = CompareMode::Always;
|
||||
return state;
|
||||
}
|
||||
|
||||
@ -286,7 +300,7 @@ DepthState GetAlwaysWriteDepthState()
|
||||
DepthState state = {};
|
||||
state.testenable = true;
|
||||
state.updateenable = true;
|
||||
state.func = ZMode::ALWAYS;
|
||||
state.func = CompareMode::Always;
|
||||
return state;
|
||||
}
|
||||
|
||||
@ -302,10 +316,10 @@ BlendingState GetNoBlendingBlendState()
|
||||
BlendingState state = {};
|
||||
state.usedualsrc = false;
|
||||
state.blendenable = false;
|
||||
state.srcfactor = BlendMode::ONE;
|
||||
state.srcfactoralpha = BlendMode::ONE;
|
||||
state.dstfactor = BlendMode::ZERO;
|
||||
state.dstfactoralpha = BlendMode::ZERO;
|
||||
state.srcfactor = SrcBlendFactor::One;
|
||||
state.srcfactoralpha = SrcBlendFactor::One;
|
||||
state.dstfactor = DstBlendFactor::Zero;
|
||||
state.dstfactoralpha = DstBlendFactor::Zero;
|
||||
state.logicopenable = false;
|
||||
state.colorupdate = true;
|
||||
state.alphaupdate = true;
|
||||
@ -317,10 +331,10 @@ BlendingState GetNoColorWriteBlendState()
|
||||
BlendingState state = {};
|
||||
state.usedualsrc = false;
|
||||
state.blendenable = false;
|
||||
state.srcfactor = BlendMode::ONE;
|
||||
state.srcfactoralpha = BlendMode::ONE;
|
||||
state.dstfactor = BlendMode::ZERO;
|
||||
state.dstfactoralpha = BlendMode::ZERO;
|
||||
state.srcfactor = SrcBlendFactor::One;
|
||||
state.srcfactoralpha = SrcBlendFactor::One;
|
||||
state.dstfactor = DstBlendFactor::Zero;
|
||||
state.dstfactoralpha = DstBlendFactor::Zero;
|
||||
state.logicopenable = false;
|
||||
state.colorupdate = false;
|
||||
state.alphaupdate = false;
|
||||
|
Reference in New Issue
Block a user