summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp7
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp39
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h5
3 files changed, 51 insertions, 0 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index ee04569fa..1a0a18c3e 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -575,6 +575,8 @@ std::pair<bool, bool> RasterizerOpenGL::ConfigureFramebuffers(
SetupCachedFramebuffer(fbkey, current_state);
SyncViewport(current_state);
+ res_cache.SignalPostFramebufferSetup();
+
return current_depth_stencil_usage = {static_cast<bool>(depth_surface), fbkey.stencil_enable};
}
@@ -738,9 +740,13 @@ void RasterizerOpenGL::DrawArrays() {
shader_program_manager->ApplyTo(state);
state.Apply();
+ res_cache.SignalPreDrawCall();
+
// Execute draw call
params.DispatchDraw();
+ res_cache.SignalPostDrawCall();
+
// Disable scissor test
state.viewports[0].scissor.enabled = false;
@@ -1013,6 +1019,7 @@ void RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, const Shader& s
texture_samplers[current_bindpoint].SyncWithConfig(texture.tsc);
Surface surface = res_cache.GetTextureSurface(texture, entry);
+ res_cache.SignalSurfaceParameter(surface);
if (surface != nullptr) {
state.texture_units[current_bindpoint].texture =
entry.IsArray() ? surface->TextureLayer().handle : surface->Texture().handle;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index 367dbd041..5e97e2f7a 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -1392,10 +1392,49 @@ bool RasterizerCacheOpenGL::PartialReinterpretSurface(Surface triggering_surface
void RasterizerCacheOpenGL::NotifyFrameBufferChange(Surface triggering_surface) {
if (triggering_surface == nullptr)
return;
+ run_texception_pass = false;
+ if (texception) {
+ return;
+ }
Surface intersect = CollideOnReinterpretedSurface(triggering_surface->GetAddr());
if (intersect != nullptr) {
PartialReinterpretSurface(triggering_surface, intersect);
}
}
+void RasterizerCacheOpenGL::SignalPreDrawCall() {
+ if (texception) {
+ glTextureBarrier();
+ }
+}
+
+void RasterizerCacheOpenGL::SignalPostDrawCall() {
+ if (!run_texception_pass)
+ return;
+ for (u32 i = 0; i < Maxwell::NumRenderTargets; i++) {
+ if (current_color_buffers[i] != nullptr) {
+ Surface intersect = CollideOnReinterpretedSurface(current_color_buffers[i]->GetAddr());
+ if (intersect != nullptr) {
+ PartialReinterpretSurface(current_color_buffers[i], intersect);
+ texception = true;
+ }
+ }
+ }
+ if (!texception)
+ run_texception_pass = false;
+}
+
+void RasterizerCacheOpenGL::SignalPostFramebufferSetup() {
+ if (!run_texception_pass)
+ texception = false;
+}
+
+void RasterizerCacheOpenGL::SignalSurfaceParameter(Surface& surface) {
+ if (surface == nullptr)
+ return;
+ if (surface->IsReinterpreted()) {
+ run_texception_pass = true;
+ }
+}
+
} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
index 2be056f0a..8c3cddf6a 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
@@ -469,6 +469,11 @@ public:
const Common::Rectangle<u32>& src_rect,
const Common::Rectangle<u32>& dst_rect);
+ void SignalPreDrawCall();
+ void SignalPostDrawCall();
+ void SignalSurfaceParameter(Surface& surface);
+ void SignalPostFramebufferSetup();
+
private:
void LoadSurface(const Surface& surface);
Surface GetSurface(const SurfaceParams& params, bool preserve_contents = true);