aboutsummaryrefslogtreecommitdiff
path: root/src/video_core/renderer_opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/renderer_opengl')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp73
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h9
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp5
-rw-r--r--src/video_core/renderer_opengl/pica_to_gl.h12
4 files changed, 79 insertions, 20 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 1fadcf5ae..6ca9f45e2 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -9,7 +9,6 @@
#include "common/color.h"
#include "common/file_util.h"
-#include "common/make_unique.h"
#include "common/math_util.h"
#include "common/microprofile.h"
#include "common/profiler.h"
@@ -140,8 +139,9 @@ void RasterizerOpenGL::InitObjects() {
}
state.Apply();
- ASSERT_MSG(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE,
- "OpenGL rasterizer framebuffer setup failed, status %X", glCheckFramebufferStatus(GL_FRAMEBUFFER));
+ GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ ASSERT_MSG(status == GL_FRAMEBUFFER_COMPLETE,
+ "OpenGL rasterizer framebuffer setup failed, status %X", status);
}
void RasterizerOpenGL::Reset() {
@@ -153,6 +153,9 @@ void RasterizerOpenGL::Reset() {
SyncLogicOp();
SyncStencilTest();
SyncDepthTest();
+ SyncColorWriteMask();
+ SyncStencilWriteMask();
+ SyncDepthWriteMask();
SetShader();
@@ -268,15 +271,36 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) {
state.draw.shader_dirty = true;
break;
- // Stencil test
+ // Sync GL stencil test + stencil write mask
+ // (Pica stencil test function register also contains a stencil write mask)
case PICA_REG_INDEX(output_merger.stencil_test.raw_func):
+ SyncStencilTest();
+ SyncStencilWriteMask();
+ break;
case PICA_REG_INDEX(output_merger.stencil_test.raw_op):
+ case PICA_REG_INDEX(framebuffer.depth_format):
SyncStencilTest();
break;
- // Depth test
+ // Sync GL depth test + depth and color write mask
+ // (Pica depth test function register also contains a depth and color write mask)
case PICA_REG_INDEX(output_merger.depth_test_enable):
SyncDepthTest();
+ SyncDepthWriteMask();
+ SyncColorWriteMask();
+ break;
+
+ // Sync GL depth and stencil write mask
+ // (This is a dedicated combined depth / stencil write-enable register)
+ case PICA_REG_INDEX(framebuffer.allow_depth_stencil_write):
+ SyncDepthWriteMask();
+ SyncStencilWriteMask();
+ break;
+
+ // Sync GL color write mask
+ // (This is a dedicated color write-enable register)
+ case PICA_REG_INDEX(framebuffer.allow_color_write):
+ SyncColorWriteMask();
break;
// Logic op
@@ -677,7 +701,7 @@ void RasterizerOpenGL::ReconfigureDepthTexture(DepthTextureInfo& texture, Pica::
void RasterizerOpenGL::SetShader() {
PicaShaderConfig config = PicaShaderConfig::CurrentConfig();
- std::unique_ptr<PicaShader> shader = Common::make_unique<PicaShader>();
+ std::unique_ptr<PicaShader> shader = std::make_unique<PicaShader>();
// Find (or generate) the GLSL shader for the current TEV state
auto cached_shader = shader_cache.find(config);
@@ -808,6 +832,10 @@ void RasterizerOpenGL::SyncFramebuffer() {
ReloadDepthBuffer();
}
+
+ GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ ASSERT_MSG(status == GL_FRAMEBUFFER_COMPLETE,
+ "OpenGL rasterizer framebuffer setup failed, status %X", status);
}
void RasterizerOpenGL::SyncCullMode() {
@@ -876,13 +904,39 @@ void RasterizerOpenGL::SyncLogicOp() {
state.logic_op = PicaToGL::LogicOp(Pica::g_state.regs.output_merger.logic_op);
}
+void RasterizerOpenGL::SyncColorWriteMask() {
+ const auto& regs = Pica::g_state.regs;
+
+ auto IsColorWriteEnabled = [&](u32 value) {
+ return (regs.framebuffer.allow_color_write != 0 && value != 0) ? GL_TRUE : GL_FALSE;
+ };
+
+ state.color_mask.red_enabled = IsColorWriteEnabled(regs.output_merger.red_enable);
+ state.color_mask.green_enabled = IsColorWriteEnabled(regs.output_merger.green_enable);
+ state.color_mask.blue_enabled = IsColorWriteEnabled(regs.output_merger.blue_enable);
+ state.color_mask.alpha_enabled = IsColorWriteEnabled(regs.output_merger.alpha_enable);
+}
+
+void RasterizerOpenGL::SyncStencilWriteMask() {
+ const auto& regs = Pica::g_state.regs;
+ state.stencil.write_mask = (regs.framebuffer.allow_depth_stencil_write != 0)
+ ? static_cast<GLuint>(regs.output_merger.stencil_test.write_mask)
+ : 0;
+}
+
+void RasterizerOpenGL::SyncDepthWriteMask() {
+ const auto& regs = Pica::g_state.regs;
+ state.depth.write_mask = (regs.framebuffer.allow_depth_stencil_write != 0 && regs.output_merger.depth_write_enable)
+ ? GL_TRUE
+ : GL_FALSE;
+}
+
void RasterizerOpenGL::SyncStencilTest() {
const auto& regs = Pica::g_state.regs;
state.stencil.test_enabled = regs.output_merger.stencil_test.enable && regs.framebuffer.depth_format == Pica::Regs::DepthFormat::D24S8;
state.stencil.test_func = PicaToGL::CompareFunc(regs.output_merger.stencil_test.func);
state.stencil.test_ref = regs.output_merger.stencil_test.reference_value;
state.stencil.test_mask = regs.output_merger.stencil_test.input_mask;
- state.stencil.write_mask = regs.output_merger.stencil_test.write_mask;
state.stencil.action_stencil_fail = PicaToGL::StencilOp(regs.output_merger.stencil_test.action_stencil_fail);
state.stencil.action_depth_fail = PicaToGL::StencilOp(regs.output_merger.stencil_test.action_depth_fail);
state.stencil.action_depth_pass = PicaToGL::StencilOp(regs.output_merger.stencil_test.action_depth_pass);
@@ -894,11 +948,6 @@ void RasterizerOpenGL::SyncDepthTest() {
regs.output_merger.depth_write_enable == 1;
state.depth.test_func = regs.output_merger.depth_test_enable == 1 ?
PicaToGL::CompareFunc(regs.output_merger.depth_test_func) : GL_ALWAYS;
- state.color_mask.red_enabled = regs.output_merger.red_enable;
- state.color_mask.green_enabled = regs.output_merger.green_enable;
- state.color_mask.blue_enabled = regs.output_merger.blue_enable;
- state.color_mask.alpha_enabled = regs.output_merger.alpha_enable;
- state.depth.write_mask = regs.output_merger.depth_write_enable ? GL_TRUE : GL_FALSE;
}
void RasterizerOpenGL::SyncCombinerColor() {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index fc85aa3ff..390349a0c 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -344,6 +344,15 @@ private:
/// Syncs the logic op states to match the PICA register
void SyncLogicOp();
+ /// Syncs the color write mask to match the PICA register state
+ void SyncColorWriteMask();
+
+ /// Syncs the stencil write mask to match the PICA register state
+ void SyncStencilWriteMask();
+
+ /// Syncs the depth write mask to match the PICA register state
+ void SyncDepthWriteMask();
+
/// Syncs the stencil test states to match the PICA register
void SyncStencilTest();
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index a9ad46fe0..1323c12e4 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -2,8 +2,9 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include <memory>
+
#include "common/hash.h"
-#include "common/make_unique.h"
#include "common/math_util.h"
#include "common/microprofile.h"
#include "common/vector_math.h"
@@ -29,7 +30,7 @@ void RasterizerCacheOpenGL::LoadAndBindTexture(OpenGLState &state, unsigned text
} else {
MICROPROFILE_SCOPE(OpenGL_TextureUpload);
- std::unique_ptr<CachedTexture> new_texture = Common::make_unique<CachedTexture>();
+ std::unique_ptr<CachedTexture> new_texture = std::make_unique<CachedTexture>();
new_texture->texture.Create();
state.texture_units[texture_unit].texture_2d = new_texture->texture.handle;
diff --git a/src/video_core/renderer_opengl/pica_to_gl.h b/src/video_core/renderer_opengl/pica_to_gl.h
index 3d6c4e9e5..fd3617d77 100644
--- a/src/video_core/renderer_opengl/pica_to_gl.h
+++ b/src/video_core/renderer_opengl/pica_to_gl.h
@@ -22,7 +22,7 @@ inline GLenum TextureFilterMode(Pica::Regs::TextureConfig::TextureFilter mode) {
};
// Range check table for input
- if (mode >= ARRAY_SIZE(filter_mode_table)) {
+ if (static_cast<size_t>(mode) >= ARRAY_SIZE(filter_mode_table)) {
LOG_CRITICAL(Render_OpenGL, "Unknown texture filtering mode %d", mode);
UNREACHABLE();
@@ -51,7 +51,7 @@ inline GLenum WrapMode(Pica::Regs::TextureConfig::WrapMode mode) {
};
// Range check table for input
- if (mode >= ARRAY_SIZE(wrap_mode_table)) {
+ if (static_cast<size_t>(mode) >= ARRAY_SIZE(wrap_mode_table)) {
LOG_CRITICAL(Render_OpenGL, "Unknown texture wrap mode %d", mode);
UNREACHABLE();
@@ -91,7 +91,7 @@ inline GLenum BlendFunc(Pica::Regs::BlendFactor factor) {
};
// Range check table for input
- if ((unsigned)factor >= ARRAY_SIZE(blend_func_table)) {
+ if (static_cast<size_t>(factor) >= ARRAY_SIZE(blend_func_table)) {
LOG_CRITICAL(Render_OpenGL, "Unknown blend factor %d", factor);
UNREACHABLE();
@@ -122,7 +122,7 @@ inline GLenum LogicOp(Pica::Regs::LogicOp op) {
};
// Range check table for input
- if ((unsigned)op >= ARRAY_SIZE(logic_op_table)) {
+ if (static_cast<size_t>(op) >= ARRAY_SIZE(logic_op_table)) {
LOG_CRITICAL(Render_OpenGL, "Unknown logic op %d", op);
UNREACHABLE();
@@ -145,7 +145,7 @@ inline GLenum CompareFunc(Pica::Regs::CompareFunc func) {
};
// Range check table for input
- if ((unsigned)func >= ARRAY_SIZE(compare_func_table)) {
+ if (static_cast<size_t>(func) >= ARRAY_SIZE(compare_func_table)) {
LOG_CRITICAL(Render_OpenGL, "Unknown compare function %d", func);
UNREACHABLE();
@@ -168,7 +168,7 @@ inline GLenum StencilOp(Pica::Regs::StencilAction action) {
};
// Range check table for input
- if ((unsigned)action >= ARRAY_SIZE(stencil_op_table)) {
+ if (static_cast<size_t>(action) >= ARRAY_SIZE(stencil_op_table)) {
LOG_CRITICAL(Render_OpenGL, "Unknown stencil op %d", action);
UNREACHABLE();