summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_opengl
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2019-12-29 22:14:40 +0100
committerReinUsesLisp <reinuseslisp@airmail.cc>2020-02-28 21:56:42 +0100
commitb01dd7d1c86265dd19508ea15e4ff4db31681470 (patch)
tree90cf54950dce4a5fd280336c57bc98e627b09d3d /src/video_core/renderer_opengl
parentgl_state_tracker: Implement dirty flags for clip distances and shaders (diff)
downloadyuzu-b01dd7d1c86265dd19508ea15e4ff4db31681470.tar
yuzu-b01dd7d1c86265dd19508ea15e4ff4db31681470.tar.gz
yuzu-b01dd7d1c86265dd19508ea15e4ff4db31681470.tar.bz2
yuzu-b01dd7d1c86265dd19508ea15e4ff4db31681470.tar.lz
yuzu-b01dd7d1c86265dd19508ea15e4ff4db31681470.tar.xz
yuzu-b01dd7d1c86265dd19508ea15e4ff4db31681470.tar.zst
yuzu-b01dd7d1c86265dd19508ea15e4ff4db31681470.zip
Diffstat (limited to 'src/video_core/renderer_opengl')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp49
-rw-r--r--src/video_core/renderer_opengl/gl_state_tracker.cpp16
-rw-r--r--src/video_core/renderer_opengl/gl_state_tracker.h14
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.cpp1
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp1
5 files changed, 67 insertions, 14 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 717f127e9..cedfe5db1 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -458,6 +458,7 @@ void RasterizerOpenGL::Clear() {
}
// TODO: Signal state tracker about these changes
+ state_tracker.NotifyBlend0();
// TODO(Rodrigo): Find out if these changes affect clearing
glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
glDisablei(GL_BLEND, 0);
@@ -1102,31 +1103,53 @@ void RasterizerOpenGL::SyncFragmentColorClampState() {
}
void RasterizerOpenGL::SyncBlendState() {
- auto& maxwell3d = system.GPU().Maxwell3D();
- const auto& regs = maxwell3d.regs;
+ auto& gpu = system.GPU().Maxwell3D();
+ auto& flags = gpu.dirty.flags;
+ const auto& regs = gpu.regs;
+
+ if (flags[Dirty::BlendColor]) {
+ flags[Dirty::BlendColor] = false;
+ glBlendColor(regs.blend_color.r, regs.blend_color.g, regs.blend_color.b,
+ regs.blend_color.a);
+ }
- glBlendColor(regs.blend_color.r, regs.blend_color.g, regs.blend_color.b, regs.blend_color.a);
+ // TODO(Rodrigo): Revisit blending, there are several registers we are not reading
+
+ if (!flags[Dirty::BlendStates]) {
+ return;
+ }
+ flags[Dirty::BlendStates] = false;
if (!regs.independent_blend_enable) {
- const auto& src = regs.blend;
- oglEnable(GL_BLEND, src.enable[0]);
- if (!src.enable[0]) {
+ if (!regs.blend.enable[0]) {
+ glDisable(GL_BLEND);
return;
}
- glBlendFuncSeparate(MaxwellToGL::BlendFunc(src.factor_source_rgb),
- MaxwellToGL::BlendFunc(src.factor_dest_rgb),
- MaxwellToGL::BlendFunc(src.factor_source_a),
- MaxwellToGL::BlendFunc(src.factor_dest_a));
- glBlendEquationSeparate(MaxwellToGL::BlendEquation(src.equation_rgb),
- MaxwellToGL::BlendEquation(src.equation_a));
+ glEnable(GL_BLEND);
+ glBlendFuncSeparate(MaxwellToGL::BlendFunc(regs.blend.factor_source_rgb),
+ MaxwellToGL::BlendFunc(regs.blend.factor_dest_rgb),
+ MaxwellToGL::BlendFunc(regs.blend.factor_source_a),
+ MaxwellToGL::BlendFunc(regs.blend.factor_dest_a));
+ glBlendEquationSeparate(MaxwellToGL::BlendEquation(regs.blend.equation_rgb),
+ MaxwellToGL::BlendEquation(regs.blend.equation_a));
return;
}
+ const bool force = flags[Dirty::BlendIndependentEnabled];
+ flags[Dirty::BlendIndependentEnabled] = false;
+
for (std::size_t i = 0; i < Maxwell::NumRenderTargets; ++i) {
- oglEnablei(GL_BLEND, regs.blend.enable[i], static_cast<GLuint>(i));
+ if (!force && !flags[Dirty::BlendState0 + i]) {
+ continue;
+ }
+ flags[Dirty::BlendState0 + i] = false;
+
if (!regs.blend.enable[i]) {
+ glDisablei(GL_BLEND, static_cast<GLuint>(i));
continue;
}
+ glEnablei(GL_BLEND, static_cast<GLuint>(i));
+
const auto& src = regs.independent_blend[i];
glBlendFuncSeparatei(static_cast<GLuint>(i), MaxwellToGL::BlendFunc(src.factor_source_rgb),
MaxwellToGL::BlendFunc(src.factor_dest_rgb),
diff --git a/src/video_core/renderer_opengl/gl_state_tracker.cpp b/src/video_core/renderer_opengl/gl_state_tracker.cpp
index bc5942a7f..2da1b65fc 100644
--- a/src/video_core/renderer_opengl/gl_state_tracker.cpp
+++ b/src/video_core/renderer_opengl/gl_state_tracker.cpp
@@ -129,6 +129,21 @@ void SetupDirtyShaders(Tables& tables) {
Shaders);
}
+void SetupDirtyBlend(Tables& tables) {
+ FillBlock(tables[0], OFF(blend_color), NUM(blend_color), BlendColor);
+
+ tables[0][OFF(independent_blend_enable)] = BlendIndependentEnabled;
+
+ for (std::size_t i = 0; i < Regs::NumRenderTargets; ++i) {
+ const std::size_t offset = OFF(independent_blend) + i * NUM(independent_blend[0]);
+ FillBlock(tables[0], offset, NUM(independent_blend[0]), BlendState0 + i);
+
+ tables[0][OFF(blend.enable) + i] = static_cast<u8>(BlendState0 + i);
+ }
+ FillBlock(tables[1], OFF(independent_blend), NUM(independent_blend), BlendStates);
+ FillBlock(tables[1], OFF(blend), NUM(blend), BlendStates);
+}
+
void SetupDirtyMisc(Tables& tables) {
tables[0][OFF(clip_distance_enabled)] = ClipDistances;
}
@@ -147,6 +162,7 @@ void StateTracker::Initialize() {
SetupDirtyVertexArrays(tables);
SetupDirtyVertexFormat(tables);
SetupDirtyShaders(tables);
+ SetupDirtyBlend(tables);
SetupDirtyMisc(tables);
auto& store = dirty.on_write_stores;
diff --git a/src/video_core/renderer_opengl/gl_state_tracker.h b/src/video_core/renderer_opengl/gl_state_tracker.h
index 11fdc6de4..a9b470eee 100644
--- a/src/video_core/renderer_opengl/gl_state_tracker.h
+++ b/src/video_core/renderer_opengl/gl_state_tracker.h
@@ -47,8 +47,15 @@ enum : u8 {
ColorMask0,
ColorMask7 = ColorMask0 + 7,
+ BlendColor,
+ BlendIndependentEnabled,
+ BlendStates,
+ BlendState0,
+ BlendState7 = BlendState0 + 7,
+
Shaders,
ClipDistances,
+
CullTestEnable,
FrontFace,
CullFace,
@@ -56,7 +63,6 @@ enum : u8 {
DepthTest,
StencilTest,
ColorMask,
- BlendState,
PolygonOffset,
Last
@@ -103,6 +109,12 @@ public:
flags[OpenGL::Dirty::ColorMask0] = true;
}
+ void NotifyBlend0() {
+ auto& flags = system.GPU().Maxwell3D().dirty.flags;
+ flags[OpenGL::Dirty::BlendStates] = true;
+ flags[OpenGL::Dirty::BlendState0] = true;
+ }
+
void NotifyFramebuffer() {
auto& flags = system.GPU().Maxwell3D().dirty.flags;
flags[VideoCommon::Dirty::RenderTargets] = true;
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp
index a02326b9f..46572eb43 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp
@@ -520,6 +520,7 @@ void TextureCacheOpenGL::ImageBlit(View& src_view, View& dst_view,
// TODO: Signal state tracker about these changes
state_tracker.NotifyScissor0();
+ state_tracker.NotifyBlend0();
state_tracker.NotifyFramebuffer();
if (dst_params.srgb_conversion) {
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index cbe916488..d81c68077 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -580,6 +580,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
state_tracker.NotifyViewport0();
state_tracker.NotifyScissor0();
state_tracker.NotifyColorMask0();
+ state_tracker.NotifyBlend0();
state_tracker.NotifyFramebuffer();
program_manager.UseVertexShader(vertex_program.handle);