summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/RenderState.cpp
diff options
context:
space:
mode:
authorMarkus Wick <degasus@users.noreply.github.com>2017-09-11 13:28:09 +0200
committerGitHub <noreply@github.com>2017-09-11 13:28:09 +0200
commit002e01d0ede3bd0eeebebc09f8f6a813ebc8d444 (patch)
tree5fb17c3d07988499767c51908b49dac2d8d9c881 /Source/Core/VideoCommon/RenderState.cpp
parent9d169449a7898cefab29a5e033f82560cfcdef5e (diff)
parent24ddea04ce3c843dd1de3d34d775e9a49d195225 (diff)
Merge pull request #5343 from stenzek/videocommon-states
Move depth, rasterization and sampler states to VideoCommon
Diffstat (limited to 'Source/Core/VideoCommon/RenderState.cpp')
-rw-r--r--Source/Core/VideoCommon/RenderState.cpp133
1 files changed, 133 insertions, 0 deletions
diff --git a/Source/Core/VideoCommon/RenderState.cpp b/Source/Core/VideoCommon/RenderState.cpp
index 7e6d845ccb..8f8d421730 100644
--- a/Source/Core/VideoCommon/RenderState.cpp
+++ b/Source/Core/VideoCommon/RenderState.cpp
@@ -3,6 +3,38 @@
// Refer to the license.txt file included.
#include "VideoCommon/RenderState.h"
+#include <algorithm>
+#include <array>
+#include "VideoCommon/SamplerCommon.h"
+
+void RasterizationState::Generate(const BPMemory& bp, PrimitiveType primitive_type)
+{
+ cullmode = bp.genMode.cullmode;
+ primitive = primitive_type;
+
+ // Back-face culling should be disabled for points/lines.
+ if (primitive_type != PrimitiveType::Triangles && primitive_type != PrimitiveType::TriangleStrip)
+ cullmode = GenMode::CULL_NONE;
+}
+
+RasterizationState& RasterizationState::operator=(const RasterizationState& rhs)
+{
+ hex = rhs.hex;
+ return *this;
+}
+
+void DepthState::Generate(const BPMemory& bp)
+{
+ testenable = bp.zmode.testenable.Value();
+ updateenable = bp.zmode.updateenable.Value();
+ func = bp.zmode.func.Value();
+}
+
+DepthState& DepthState::operator=(const DepthState& rhs)
+{
+ hex = rhs.hex;
+ return *this;
+}
// If the framebuffer format has no alpha channel, it is assumed to
// ONE on blending. As the backends may emulate this framebuffer
@@ -127,3 +159,104 @@ void BlendingState::Generate(const BPMemory& bp)
}
}
}
+
+BlendingState& BlendingState::operator=(const BlendingState& rhs)
+{
+ hex = rhs.hex;
+ return *this;
+}
+
+void SamplerState::Generate(const BPMemory& bp, u32 index)
+{
+ const FourTexUnits& tex = bpmem.tex[index / 4];
+ const TexMode0& tm0 = tex.texMode0[index % 4];
+ const TexMode1& tm1 = tex.texMode1[index % 4];
+
+ // 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;
+
+ // If mipmaps are disabled, clamp min/max lod
+ max_lod = SamplerCommon::AreBpTexMode0MipmapsEnabled(tm0) ? tm1.max_lod : 0;
+ min_lod = std::min(max_lod.Value(), tm1.min_lod);
+ lod_bias = SamplerCommon::AreBpTexMode0MipmapsEnabled(tm0) ? tm0.lod_bias : 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];
+ anisotropic_filtering = 0;
+}
+
+SamplerState& SamplerState::operator=(const SamplerState& rhs)
+{
+ hex = rhs.hex;
+ return *this;
+}
+
+namespace RenderState
+{
+RasterizationState GetNoCullRasterizationState()
+{
+ RasterizationState state = {};
+ state.cullmode = GenMode::CULL_NONE;
+ return state;
+}
+
+DepthState GetNoDepthTestingDepthStencilState()
+{
+ DepthState state = {};
+ state.testenable = false;
+ state.updateenable = false;
+ state.func = ZMode::ALWAYS;
+ return state;
+}
+
+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.logicopenable = false;
+ state.colorupdate = true;
+ state.alphaupdate = true;
+ 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;
+ 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;
+ return state;
+}
+}