Просмотр исходного кода

rasterizer_cache_gl: Implement Texception Pass

Fernando Sahmkow 7 лет назад
Родитель
Сommit
5bc82d124c

+ 7 - 0
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;

+ 39 - 0
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

+ 5 - 0
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);