aboutsummaryrefslogtreecommitdiffhomepage
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/generated/gl_3_2_core.c16
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp12
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h3
-rw-r--r--src/video_core/renderer_opengl/gl_shaders.h24
-rw-r--r--src/video_core/renderer_opengl/gl_state.cpp13
-rw-r--r--src/video_core/renderer_opengl/gl_state.h4
-rw-r--r--src/video_core/renderer_opengl/pica_to_gl.h31
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp2
8 files changed, 83 insertions, 22 deletions
diff --git a/src/video_core/renderer_opengl/generated/gl_3_2_core.c b/src/video_core/renderer_opengl/generated/gl_3_2_core.c
index ef29972d..95fd29c0 100644
--- a/src/video_core/renderer_opengl/generated/gl_3_2_core.c
+++ b/src/video_core/renderer_opengl/generated/gl_3_2_core.c
@@ -62,9 +62,9 @@ static int TestPointer(const PROC pTest)
ptrdiff_t iTest;
if(!pTest) return 0;
iTest = (ptrdiff_t)pTest;
-
+
if(iTest == 1 || iTest == 2 || iTest == 3 || iTest == -1) return 0;
-
+
return 1;
}
@@ -79,7 +79,7 @@ static PROC WinGetProcAddress(const char *name)
glMod = GetModuleHandleA("OpenGL32.dll");
return (PROC)GetProcAddress(glMod, (LPCSTR)name);
}
-
+
#define IntGetProcAddress(name) WinGetProcAddress(name)
#else
#if defined(__APPLE__)
@@ -1083,7 +1083,7 @@ static ogl_StrToExtMap *FindExtEntry(const char *extensionName)
if(strcmp(extensionName, currLoc->extensionName) == 0)
return currLoc;
}
-
+
return NULL;
}
@@ -1135,15 +1135,15 @@ int ogl_LoadFunctions()
{
int numFailed = 0;
ClearExtensionVars();
-
+
_ptrc_glGetIntegerv = (void (CODEGEN_FUNCPTR *)(GLenum, GLint *))IntGetProcAddress("glGetIntegerv");
if(!_ptrc_glGetIntegerv) return ogl_LOAD_FAILED;
_ptrc_glGetStringi = (const GLubyte * (CODEGEN_FUNCPTR *)(GLenum, GLuint))IntGetProcAddress("glGetStringi");
if(!_ptrc_glGetStringi) return ogl_LOAD_FAILED;
-
+
ProcExtsFromExtList();
numFailed = Load_Version_3_2();
-
+
if(numFailed == 0)
return ogl_LOAD_SUCCEEDED;
else
@@ -1177,7 +1177,7 @@ int ogl_IsVersionGEQ(int majorVersion, int minorVersion)
{
if(g_major_version == 0)
GetGLVersion();
-
+
if(majorVersion > g_major_version) return 1;
if(majorVersion < g_major_version) return 0;
if(minorVersion >= g_minor_version) return 1;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 4b7d099a..b51f8efd 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -135,6 +135,7 @@ void RasterizerOpenGL::Reset() {
SyncBlendFuncs();
SyncBlendColor();
SyncAlphaTest();
+ SyncLogicOp();
SyncStencilTest();
SyncDepthTest();
@@ -249,6 +250,11 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) {
SyncDepthTest();
break;
+ // Logic op
+ case PICA_REG_INDEX(output_merger.logic_op):
+ SyncLogicOp();
+ break;
+
// TEV stage 0
case PICA_REG_INDEX(tev_stage0.color_source1):
SyncTevSources(0, regs.tev_stage0);
@@ -350,7 +356,7 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) {
case PICA_REG_INDEX(tev_stage5.color_scale):
SyncTevMultipliers(5, regs.tev_stage5);
break;
-
+
// TEV combiner buffer color
case PICA_REG_INDEX(tev_combiner_buffer_color):
SyncCombinerColor();
@@ -633,6 +639,10 @@ void RasterizerOpenGL::SyncAlphaTest() {
glUniform1f(uniform_alphatest_ref, regs.output_merger.alpha_test.ref / 255.0f);
}
+void RasterizerOpenGL::SyncLogicOp() {
+ state.logic_op = PicaToGL::LogicOp(Pica::g_state.regs.output_merger.logic_op);
+}
+
void RasterizerOpenGL::SyncStencilTest() {
// TODO: Implement stencil test, mask, and op
}
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 9896f8d0..d7d422b1 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -125,6 +125,9 @@ private:
/// Syncs the alpha test states to match the PICA register
void SyncAlphaTest();
+ /// Syncs the logic op states to match the PICA register
+ void SyncLogicOp();
+
/// Syncs the stencil test states to match the PICA register
void SyncStencilTest();
diff --git a/src/video_core/renderer_opengl/gl_shaders.h b/src/video_core/renderer_opengl/gl_shaders.h
index 8f094123..a8cb2f59 100644
--- a/src/video_core/renderer_opengl/gl_shaders.h
+++ b/src/video_core/renderer_opengl/gl_shaders.h
@@ -69,15 +69,16 @@ const char g_fragment_shader_hw[] = R"(
#define NUM_VTX_ATTR 7
#define NUM_TEV_STAGES 6
-#define SOURCE_PRIMARYCOLOR 0x0
-#define SOURCE_PRIMARYFRAGMENTCOLOR 0x1
-#define SOURCE_TEXTURE0 0x3
-#define SOURCE_TEXTURE1 0x4
-#define SOURCE_TEXTURE2 0x5
-#define SOURCE_TEXTURE3 0x6
-#define SOURCE_PREVIOUSBUFFER 0xd
-#define SOURCE_CONSTANT 0xe
-#define SOURCE_PREVIOUS 0xf
+#define SOURCE_PRIMARYCOLOR 0x0
+#define SOURCE_PRIMARYFRAGMENTCOLOR 0x1
+#define SOURCE_SECONDARYFRAGMENTCOLOR 0x2
+#define SOURCE_TEXTURE0 0x3
+#define SOURCE_TEXTURE1 0x4
+#define SOURCE_TEXTURE2 0x5
+#define SOURCE_TEXTURE3 0x6
+#define SOURCE_PREVIOUSBUFFER 0xd
+#define SOURCE_CONSTANT 0xe
+#define SOURCE_PREVIOUS 0xf
#define COLORMODIFIER_SOURCECOLOR 0x0
#define COLORMODIFIER_ONEMINUSSOURCECOLOR 0x1
@@ -151,8 +152,11 @@ vec4 GetSource(int source) {
if (source == SOURCE_PRIMARYCOLOR) {
return o[2];
} else if (source == SOURCE_PRIMARYFRAGMENTCOLOR) {
- // HACK: Uses color value, but should really use fragment lighting output
+ // HACK: Until we implement fragment lighting, use primary_color
return o[2];
+ } else if (source == SOURCE_SECONDARYFRAGMENTCOLOR) {
+ // HACK: Until we implement fragment lighting, use zero
+ return vec4(0.0, 0.0, 0.0, 0.0);
} else if (source == SOURCE_TEXTURE0) {
return texture(tex[0], o[3].xy);
} else if (source == SOURCE_TEXTURE1) {
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp
index 1afa58c9..9c5f38f9 100644
--- a/src/video_core/renderer_opengl/gl_state.cpp
+++ b/src/video_core/renderer_opengl/gl_state.cpp
@@ -32,6 +32,8 @@ OpenGLState::OpenGLState() {
blend.color.blue = 0.0f;
blend.color.alpha = 0.0f;
+ logic_op = GL_COPY;
+
for (auto& texture_unit : texture_units) {
texture_unit.enabled_2d = false;
texture_unit.texture_2d = 0;
@@ -82,7 +84,7 @@ void OpenGLState::Apply() {
} else {
glDisable(GL_STENCIL_TEST);
}
- }
+ }
if (stencil.test_func != cur_state.stencil.test_func ||
stencil.test_ref != cur_state.stencil.test_ref ||
@@ -99,8 +101,13 @@ void OpenGLState::Apply() {
if (blend.enabled != cur_state.blend.enabled) {
if (blend.enabled) {
glEnable(GL_BLEND);
+
+ cur_state.logic_op = GL_COPY;
+ glLogicOp(cur_state.logic_op);
+ glDisable(GL_COLOR_LOGIC_OP);
} else {
glDisable(GL_BLEND);
+ glEnable(GL_COLOR_LOGIC_OP);
}
}
@@ -118,6 +125,10 @@ void OpenGLState::Apply() {
glBlendFuncSeparate(blend.src_rgb_func, blend.dst_rgb_func, blend.src_a_func, blend.dst_a_func);
}
+ if (logic_op != cur_state.logic_op) {
+ glLogicOp(logic_op);
+ }
+
// Textures
for (unsigned texture_index = 0; texture_index < ARRAY_SIZE(texture_units); ++texture_index) {
if (texture_units[texture_index].enabled_2d != cur_state.texture_units[texture_index].enabled_2d) {
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h
index 281b7cad..6b97721d 100644
--- a/src/video_core/renderer_opengl/gl_state.h
+++ b/src/video_core/renderer_opengl/gl_state.h
@@ -42,6 +42,8 @@ public:
} color; // GL_BLEND_COLOR
} blend;
+ GLenum logic_op; // GL_LOGIC_OP_MODE
+
// 3 texture units - one for each that is used in PICA fragment shader emulation
struct {
bool enabled_2d; // GL_TEXTURE_2D
@@ -61,7 +63,7 @@ public:
static const OpenGLState& GetCurState() {
return cur_state;
}
-
+
/// Apply this state as the current OpenGL state
void Apply();
diff --git a/src/video_core/renderer_opengl/pica_to_gl.h b/src/video_core/renderer_opengl/pica_to_gl.h
index f8763e71..e566f9f7 100644
--- a/src/video_core/renderer_opengl/pica_to_gl.h
+++ b/src/video_core/renderer_opengl/pica_to_gl.h
@@ -71,6 +71,37 @@ inline GLenum BlendFunc(Pica::Regs::BlendFactor factor) {
return blend_func_table[(unsigned)factor];
}
+inline GLenum LogicOp(Pica::Regs::LogicOp op) {
+ static const GLenum logic_op_table[] = {
+ GL_CLEAR, // Clear
+ GL_AND, // And
+ GL_AND_REVERSE, // AndReverse
+ GL_COPY, // Copy
+ GL_SET, // Set
+ GL_COPY_INVERTED, // CopyInverted
+ GL_NOOP, // NoOp
+ GL_INVERT, // Invert
+ GL_NAND, // Nand
+ GL_OR, // Or
+ GL_NOR, // Nor
+ GL_XOR, // Xor
+ GL_EQUIV, // Equiv
+ GL_AND_INVERTED, // AndInverted
+ GL_OR_REVERSE, // OrReverse
+ GL_OR_INVERTED, // OrInverted
+ };
+
+ // Range check table for input
+ if ((unsigned)op >= ARRAY_SIZE(logic_op_table)) {
+ LOG_CRITICAL(Render_OpenGL, "Unknown logic op %d", op);
+ UNREACHABLE();
+
+ return GL_COPY;
+ }
+
+ return logic_op_table[(unsigned)op];
+}
+
inline GLenum CompareFunc(Pica::Regs::CompareFunc func) {
static const GLenum compare_func_table[] = {
GL_NEVER, // CompareFunc::Never
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 16cf92e2..382aeaa0 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -157,7 +157,7 @@ void RendererOpenGL::LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig&
state.texture_units[0].enabled_2d = true;
state.texture_units[0].texture_2d = texture.handle;
state.Apply();
-
+
glActiveTexture(GL_TEXTURE0);
glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)pixel_stride);