From 73321856c8ce52d38e7f60a722214d22ea6952b4 Mon Sep 17 00:00:00 2001
From: wheremyfoodat <44909372+wheremyfoodat@users.noreply.github.com>
Date: Fri, 28 Jul 2023 02:24:26 +0300
Subject: [PATCH] Mooore

---
 include/renderer_gl/gl_state.hpp     | 16 ++++++++
 include/renderer_gl/opengl.hpp       | 55 +++++++++++++++-------------
 src/core/renderer_gl/gl_state.cpp    |  5 +++
 src/core/renderer_gl/renderer_gl.cpp |  6 +--
 4 files changed, 53 insertions(+), 29 deletions(-)

diff --git a/include/renderer_gl/gl_state.hpp b/include/renderer_gl/gl_state.hpp
index a6c8d1f9..98f589e0 100644
--- a/include/renderer_gl/gl_state.hpp
+++ b/include/renderer_gl/gl_state.hpp
@@ -34,11 +34,13 @@ struct GLStateManager {
 	bool redMask, greenMask, blueMask, alphaMask;
 	bool depthMask;
 
+	GLuint stencilMask;
 	GLuint boundVAO;
 	GLuint boundVBO;
 	GLuint currentProgram;
 
 	GLenum depthFunc;
+	GLenum logicOp;
 
 	void reset();
 	void resetBlend();
@@ -121,6 +123,13 @@ struct GLStateManager {
 		}
 	}
 
+	void setLogicOp(GLenum op) {
+		if (logicOp != op) {
+			logicOp = op;
+			OpenGL::setLogicOp(op);
+		}
+	}
+
 	void enableClipPlane(GLuint index) {
 		if (index >= clipPlaneCount) [[unlikely]] {
 			Helpers::panic("Enabled invalid clipping plane %d\n", index);
@@ -143,6 +152,13 @@ struct GLStateManager {
 		}
 	}
 
+	void setStencilMask(GLuint mask) {
+		if (stencilMask != mask) {
+			stencilMask = mask;
+			OpenGL::setStencilMask(mask);
+		}
+	}
+
 	void bindVAO(GLuint handle) {
 		if (boundVAO != handle) {
 			boundVAO = handle;
diff --git a/include/renderer_gl/opengl.hpp b/include/renderer_gl/opengl.hpp
index 8a52b1d6..e129f6b6 100644
--- a/include/renderer_gl/opengl.hpp
+++ b/include/renderer_gl/opengl.hpp
@@ -497,42 +497,45 @@ namespace OpenGL {
     };
 
     static void setClearColor(float val) { glClearColor(val, val, val, val); }
-    static void setClearColor(float r, float g, float b, float a) { glClearColor(r, g, b, a); }
-    static void setClearDepth(float depth) { glClearDepthf(depth); }
-    static void setClearStencil(GLint stencil) { glClearStencil(stencil); }
-    static void clearColor() { glClear(GL_COLOR_BUFFER_BIT); }
-    static void clearDepth() { glClear(GL_DEPTH_BUFFER_BIT); }
-    static void clearStencil() { glClear(GL_STENCIL_BUFFER_BIT); }
-    static void clearColorAndDepth() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); }
-    static void clearColorAndStencil() { glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); }
-    static void clearDepthAndStencil() { glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); }
-    static void clearAll() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); }
+	static void setClearColor(float r, float g, float b, float a) { glClearColor(r, g, b, a); }
+	static void setClearDepth(float depth) { glClearDepthf(depth); }
+	static void setClearStencil(GLint stencil) { glClearStencil(stencil); }
+	static void clearColor() { glClear(GL_COLOR_BUFFER_BIT); }
+	static void clearDepth() { glClear(GL_DEPTH_BUFFER_BIT); }
+	static void clearStencil() { glClear(GL_STENCIL_BUFFER_BIT); }
+	static void clearColorAndDepth() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); }
+	static void clearColorAndStencil() { glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); }
+	static void clearDepthAndStencil() { glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); }
+	static void clearAll() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); }
 
-    static void setViewport(GLsizei width, GLsizei height) { glViewport(0, 0, width, height); }
-    static void setViewport(GLsizei x, GLsizei y, GLsizei width, GLsizei height) { glViewport(x, y, width, height); }
-    static void setScissor(GLsizei width, GLsizei height) { glScissor(0, 0, width, height); }
-    static void setScissor(GLsizei x, GLsizei y, GLsizei width, GLsizei height) { glScissor(x, y, width, height); }
-    static void setStencilMask(GLuint mask) { glStencilMask(mask); }
+	static void setViewport(GLsizei width, GLsizei height) { glViewport(0, 0, width, height); }
+	static void setViewport(GLsizei x, GLsizei y, GLsizei width, GLsizei height) { glViewport(x, y, width, height); }
+	static void setScissor(GLsizei width, GLsizei height) { glScissor(0, 0, width, height); }
+	static void setScissor(GLsizei x, GLsizei y, GLsizei width, GLsizei height) { glScissor(x, y, width, height); }
+	static void setStencilMask(GLuint mask) { glStencilMask(mask); }
 
-    static void bindScreenFramebuffer() { glBindFramebuffer(GL_FRAMEBUFFER, 0); }
-    static void enableScissor() { glEnable(GL_SCISSOR_TEST); }
-    static void disableScissor() { glDisable(GL_SCISSOR_TEST); }
-    static void enableBlend() { glEnable(GL_BLEND); }
-    static void disableBlend() { glDisable(GL_BLEND); }
+	static void bindScreenFramebuffer() { glBindFramebuffer(GL_FRAMEBUFFER, 0); }
+	static void enableScissor() { glEnable(GL_SCISSOR_TEST); }
+	static void disableScissor() { glDisable(GL_SCISSOR_TEST); }
+	static void enableBlend() { glEnable(GL_BLEND); }
+	static void disableBlend() { glDisable(GL_BLEND); }
 	static void enableLogicOp() { glEnable(GL_COLOR_LOGIC_OP); }
 	static void disableLogicOp() { glDisable(GL_COLOR_LOGIC_OP); }
-    static void enableDepth() { glEnable(GL_DEPTH_TEST); }
-    static void disableDepth() { glDisable(GL_DEPTH_TEST); }
-    static void enableStencil() { glEnable(GL_STENCIL_TEST); }
-    static void disableStencil() { glDisable(GL_STENCIL_TEST); }
+	static void enableDepth() { glEnable(GL_DEPTH_TEST); }
+	static void disableDepth() { glDisable(GL_DEPTH_TEST); }
+	static void enableStencil() { glEnable(GL_STENCIL_TEST); }
+	static void disableStencil() { glDisable(GL_STENCIL_TEST); }
 
-    static void enableClipPlane(GLuint index) { glEnable(GL_CLIP_DISTANCE0 + index); }
+	static void enableClipPlane(GLuint index) { glEnable(GL_CLIP_DISTANCE0 + index); }
 	static void disableClipPlane(GLuint index) { glDisable(GL_CLIP_DISTANCE0 + index); }
 
-    static void setDepthFunc(DepthFunc func) { glDepthFunc(static_cast<GLenum>(func)); }
+	static void setDepthFunc(DepthFunc func) { glDepthFunc(static_cast<GLenum>(func)); }
 	static void setColourMask(GLboolean r, GLboolean g, GLboolean b, GLboolean a) { glColorMask(r, g, b, a); }
 	static void setDepthMask(GLboolean mask) { glDepthMask(mask); }
 
+	// TODO: Add a proper enum for this
+	static void setLogicOp(GLenum op) { glLogicOp(op); }
+
     enum Primitives {
         Triangle = GL_TRIANGLES,
         Triangles = Triangle,
diff --git a/src/core/renderer_gl/gl_state.cpp b/src/core/renderer_gl/gl_state.cpp
index 6d073128..4a512f44 100644
--- a/src/core/renderer_gl/gl_state.cpp
+++ b/src/core/renderer_gl/gl_state.cpp
@@ -3,9 +3,11 @@
 void GLStateManager::resetBlend() {
 	blendEnabled = false;
 	logicOpEnabled = false;
+	logicOp = GL_COPY;
 
 	OpenGL::disableBlend();
 	OpenGL::disableLogicOp();
+	OpenGL::setLogicOp(GL_COPY);
 }
 
 void GLStateManager::resetClipping() {
@@ -39,7 +41,10 @@ void GLStateManager::resetScissor() {
 
 void GLStateManager::resetStencil() {
 	stencilEnabled = false;
+	stencilMask = 0xff;
+
 	OpenGL::disableStencil();
+	OpenGL::setStencilMask(0xff);
 }
 
 void GLStateManager::resetVAO() {
diff --git a/src/core/renderer_gl/renderer_gl.cpp b/src/core/renderer_gl/renderer_gl.cpp
index ddbffd98..f140893d 100644
--- a/src/core/renderer_gl/renderer_gl.cpp
+++ b/src/core/renderer_gl/renderer_gl.cpp
@@ -184,7 +184,7 @@ void RendererGL::setupBlending() {
 
 	if (!blendingEnabled) { // Logic ops are enabled
 		const u32 logicOp = getBits<0, 4>(regs[PICA::InternalRegs::LogicOp]);
-		glLogicOp(logicOps[logicOp]);
+		gl.setLogicOp(logicOps[logicOp]);
 
 		// If logic ops are enabled we don't need to disable blending because they override it
 		gl.enableLogicOp();
@@ -243,7 +243,7 @@ void RendererGL::setupStencilTest(bool stencilEnable) {
 	const u32 stencilBufferMask = stencilWrite ? getBits<8, 8>(stencilConfig) : 0;
 
 	glStencilFunc(stencilFuncs[stencilFunc], reference, stencilRefMask);
-	glStencilMask(stencilBufferMask);
+	gl.setStencilMask(stencilBufferMask);
 
 	static constexpr std::array<GLenum, 8> stencilOps = {
 		GL_KEEP,
@@ -489,7 +489,7 @@ void RendererGL::clearBuffer(u32 startAddress, u32 endAddress, u32 value, u32 co
 
 		if (format == DepthFmt::Depth24Stencil8) {
 			const u8 stencil = (value >> 24);
-			OpenGL::setStencilMask(0xff);
+			gl.setStencilMask(0xff);
 			OpenGL::setClearStencil(stencil);
 			OpenGL::clearDepthAndStencil();
 		} else {