summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/RenderState.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/VideoCommon/RenderState.cpp')
-rw-r--r--Source/Core/VideoCommon/RenderState.cpp86
1 files changed, 53 insertions, 33 deletions
diff --git a/Source/Core/VideoCommon/RenderState.cpp b/Source/Core/VideoCommon/RenderState.cpp
index d84a17257e..15559ae67f 100644
--- a/Source/Core/VideoCommon/RenderState.cpp
+++ b/Source/Core/VideoCommon/RenderState.cpp
@@ -202,27 +202,42 @@ void BlendingState::ApproximateLogicOpWithBlending()
void SamplerState::Generate(const BPMemory& bp, u32 index)
{
auto tex = bp.tex.GetUnit(index);
- const TexMode0& tm0 = tex.texMode0;
- const TexMode1& tm1 = tex.texMode1;
+ const TexMode0& bp_tm0 = tex.texMode0;
+ const TexMode1& bp_tm1 = tex.texMode1;
// 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 == 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;
+ tm0.min_filter = bp_tm0.min_filter;
+ tm0.mipmap_filter =
+ bp_tm0.mipmap_filter == MipMode::Linear ? FilterMode::Linear : FilterMode::Near;
+ tm0.mag_filter = bp_tm0.mag_filter;
// If mipmaps are disabled, clamp min/max lod
- max_lod = tm0.mipmap_filter != MipMode::None ? tm1.max_lod.Value() : 0;
- min_lod = std::min(max_lod.Value(), static_cast<u64>(tm1.min_lod));
- lod_bias = tm0.mipmap_filter != MipMode::None ? tm0.lod_bias * (256 / 32) : 0;
+ if (bp_tm0.mipmap_filter == MipMode::None)
+ {
+ tm1.max_lod = 0;
+ tm1.min_lod = 0;
+ tm0.lod_bias = 0;
+ }
+ else
+ {
+ // NOTE: When comparing, max is checked first, then min; if max is less than min, max wins
+ tm1.max_lod = bp_tm1.max_lod.Value();
+ tm1.min_lod = std::min(tm1.max_lod.Value(), bp_tm1.min_lod.Value());
+ tm0.lod_bias = bp_tm0.lod_bias * (256 / 32);
+ }
- // Address modes
+ // Wrap modes
// Hardware testing indicates that wrap_mode set to 3 behaves the same as clamp.
- static constexpr std::array<AddressMode, 4> address_modes = {
- {AddressMode::Clamp, AddressMode::Repeat, AddressMode::MirroredRepeat, AddressMode::Clamp}};
- wrap_u = address_modes[u32(tm0.wrap_s.Value())];
- wrap_v = address_modes[u32(tm0.wrap_t.Value())];
- anisotropic_filtering = 0;
+ auto filter_invalid_wrap = [](WrapMode mode) {
+ return (mode <= WrapMode::Mirror) ? mode : WrapMode::Clamp;
+ };
+ tm0.wrap_u = filter_invalid_wrap(bp_tm0.wrap_s);
+ tm0.wrap_v = filter_invalid_wrap(bp_tm0.wrap_t);
+
+ tm0.diag_lod = bp_tm0.diag_lod;
+ tm0.anisotropic_filtering = false; // TODO: Respect BP anisotropic filtering mode
+ tm0.lod_clamp = bp_tm0.lod_clamp; // TODO: What does this do?
}
namespace RenderState
@@ -315,37 +330,42 @@ BlendingState GetNoColorWriteBlendState()
SamplerState GetInvalidSamplerState()
{
SamplerState state;
- state.hex = UINT64_C(0xFFFFFFFFFFFFFFFF);
+ state.tm0.hex = 0xFFFFFFFF;
+ state.tm1.hex = 0xFFFFFFFF;
return state;
}
SamplerState GetPointSamplerState()
{
SamplerState state = {};
- state.min_filter = SamplerState::Filter::Point;
- state.mag_filter = SamplerState::Filter::Point;
- state.mipmap_filter = SamplerState::Filter::Point;
- state.wrap_u = SamplerState::AddressMode::Clamp;
- state.wrap_v = SamplerState::AddressMode::Clamp;
- state.min_lod = 0;
- state.max_lod = 255;
- state.lod_bias = 0;
- state.anisotropic_filtering = false;
+ state.tm0.min_filter = FilterMode::Near;
+ state.tm0.mag_filter = FilterMode::Near;
+ state.tm0.mipmap_filter = FilterMode::Near;
+ state.tm0.wrap_u = WrapMode::Clamp;
+ state.tm0.wrap_v = WrapMode::Clamp;
+ state.tm1.min_lod = 0;
+ state.tm1.max_lod = 255;
+ state.tm0.lod_bias = 0;
+ state.tm0.anisotropic_filtering = false;
+ state.tm0.diag_lod = LODType::Edge;
+ state.tm0.lod_clamp = false;
return state;
}
SamplerState GetLinearSamplerState()
{
SamplerState state = {};
- state.min_filter = SamplerState::Filter::Linear;
- state.mag_filter = SamplerState::Filter::Linear;
- state.mipmap_filter = SamplerState::Filter::Linear;
- state.wrap_u = SamplerState::AddressMode::Clamp;
- state.wrap_v = SamplerState::AddressMode::Clamp;
- state.min_lod = 0;
- state.max_lod = 255;
- state.lod_bias = 0;
- state.anisotropic_filtering = false;
+ state.tm0.min_filter = FilterMode::Linear;
+ state.tm0.mag_filter = FilterMode::Linear;
+ state.tm0.mipmap_filter = FilterMode::Linear;
+ state.tm0.wrap_u = WrapMode::Clamp;
+ state.tm0.wrap_v = WrapMode::Clamp;
+ state.tm1.min_lod = 0;
+ state.tm1.max_lod = 255;
+ state.tm0.lod_bias = 0;
+ state.tm0.anisotropic_filtering = false;
+ state.tm0.diag_lod = LODType::Edge;
+ state.tm0.lod_clamp = false;
return state;
}