diff options
| author | 2019-06-15 13:22:57 -0400 | |
|---|---|---|
| committer | 2019-06-20 21:38:34 -0300 | |
| commit | d7587842eb404a52eb75a12816028f0706821dd0 (patch) | |
| tree | 30e522738e4fad03be4aef1436079e5902d49a74 /src/video_core | |
| parent | texture_cache: Corrections to buffers and shadow formats use. (diff) | |
| download | yuzu-d7587842eb404a52eb75a12816028f0706821dd0.tar.gz yuzu-d7587842eb404a52eb75a12816028f0706821dd0.tar.xz yuzu-d7587842eb404a52eb75a12816028f0706821dd0.zip | |
texture_cache: Implement texception detection and texture barriers.
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 10 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache.h | 37 |
2 files changed, 40 insertions, 7 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 97c55f2ec..c9f3a35e6 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -422,7 +422,7 @@ std::pair<bool, bool> RasterizerOpenGL::ConfigureFramebuffers( | |||
| 422 | } | 422 | } |
| 423 | current_framebuffer_config_state = fb_config_state; | 423 | current_framebuffer_config_state = fb_config_state; |
| 424 | 424 | ||
| 425 | texture_cache.Guard(true); | 425 | texture_cache.GuardRenderTargets(true); |
| 426 | 426 | ||
| 427 | View depth_surface{}; | 427 | View depth_surface{}; |
| 428 | if (using_depth_fb) { | 428 | if (using_depth_fb) { |
| @@ -500,7 +500,7 @@ std::pair<bool, bool> RasterizerOpenGL::ConfigureFramebuffers( | |||
| 500 | depth_surface->GetSurfaceParams().type == SurfaceType::DepthStencil; | 500 | depth_surface->GetSurfaceParams().type == SurfaceType::DepthStencil; |
| 501 | } | 501 | } |
| 502 | 502 | ||
| 503 | texture_cache.Guard(false); | 503 | texture_cache.GuardRenderTargets(false); |
| 504 | 504 | ||
| 505 | current_state.draw.draw_framebuffer = framebuffer_cache.GetFramebuffer(fbkey); | 505 | current_state.draw.draw_framebuffer = framebuffer_cache.GetFramebuffer(fbkey); |
| 506 | SyncViewport(current_state); | 506 | SyncViewport(current_state); |
| @@ -651,7 +651,9 @@ void RasterizerOpenGL::DrawArrays() { | |||
| 651 | SetupVertexBuffer(vao); | 651 | SetupVertexBuffer(vao); |
| 652 | 652 | ||
| 653 | DrawParameters params = SetupDraw(); | 653 | DrawParameters params = SetupDraw(); |
| 654 | texture_cache.GuardSamplers(true); | ||
| 654 | SetupShaders(params.primitive_mode); | 655 | SetupShaders(params.primitive_mode); |
| 656 | texture_cache.GuardSamplers(false); | ||
| 655 | 657 | ||
| 656 | ConfigureFramebuffers(state); | 658 | ConfigureFramebuffers(state); |
| 657 | 659 | ||
| @@ -660,6 +662,10 @@ void RasterizerOpenGL::DrawArrays() { | |||
| 660 | shader_program_manager->ApplyTo(state); | 662 | shader_program_manager->ApplyTo(state); |
| 661 | state.Apply(); | 663 | state.Apply(); |
| 662 | 664 | ||
| 665 | if (texture_cache.TextureBarrier()) { | ||
| 666 | glTextureBarrier(); | ||
| 667 | } | ||
| 668 | |||
| 663 | params.DispatchDraw(); | 669 | params.DispatchDraw(); |
| 664 | 670 | ||
| 665 | accelerate_draw = AccelDraw::Disabled; | 671 | accelerate_draw = AccelDraw::Disabled; |
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index a9e61cba1..353fa4e31 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
| @@ -70,8 +70,12 @@ public: | |||
| 70 | * `Guard` guarantees that rendertargets don't unregister themselves if the | 70 | * `Guard` guarantees that rendertargets don't unregister themselves if the |
| 71 | * collide. Protection is currently only done on 3D slices. | 71 | * collide. Protection is currently only done on 3D slices. |
| 72 | **/ | 72 | **/ |
| 73 | void Guard(bool new_guard) { | 73 | void GuardRenderTargets(bool new_guard) { |
| 74 | guard_cache = new_guard; | 74 | guard_render_targets = new_guard; |
| 75 | } | ||
| 76 | |||
| 77 | void GuardSamplers(bool new_guard) { | ||
| 78 | guard_samplers = new_guard; | ||
| 75 | } | 79 | } |
| 76 | 80 | ||
| 77 | void FlushRegion(CacheAddr addr, std::size_t size) { | 81 | void FlushRegion(CacheAddr addr, std::size_t size) { |
| @@ -98,7 +102,25 @@ public: | |||
| 98 | return {}; | 102 | return {}; |
| 99 | } | 103 | } |
| 100 | const auto params{SurfaceParams::CreateForTexture(system, config, entry)}; | 104 | const auto params{SurfaceParams::CreateForTexture(system, config, entry)}; |
| 101 | return GetSurface(gpu_addr, params, true, false).second; | 105 | auto pair = GetSurface(gpu_addr, params, true, false); |
| 106 | if (guard_samplers) { | ||
| 107 | if (sampled_textures_stack_pointer == sampled_textures_stack.size()) { | ||
| 108 | sampled_textures_stack.resize(sampled_textures_stack.size() * 2); | ||
| 109 | } | ||
| 110 | sampled_textures_stack[sampled_textures_stack_pointer] = pair.first; | ||
| 111 | sampled_textures_stack_pointer++; | ||
| 112 | } | ||
| 113 | return pair.second; | ||
| 114 | } | ||
| 115 | |||
| 116 | bool TextureBarrier() { | ||
| 117 | bool must_do = false; | ||
| 118 | for (u32 i = 0; i < sampled_textures_stack_pointer; i++) { | ||
| 119 | must_do |= sampled_textures_stack[i]->IsRenderTarget(); | ||
| 120 | sampled_textures_stack[i] = nullptr; | ||
| 121 | } | ||
| 122 | sampled_textures_stack_pointer = 0; | ||
| 123 | return must_do; | ||
| 102 | } | 124 | } |
| 103 | 125 | ||
| 104 | TView GetDepthBufferSurface(bool preserve_contents) { | 126 | TView GetDepthBufferSurface(bool preserve_contents) { |
| @@ -239,6 +261,7 @@ protected: | |||
| 239 | make_siblings(PixelFormat::Z16, PixelFormat::R16F); | 261 | make_siblings(PixelFormat::Z16, PixelFormat::R16F); |
| 240 | make_siblings(PixelFormat::Z32F, PixelFormat::R32F); | 262 | make_siblings(PixelFormat::Z32F, PixelFormat::R32F); |
| 241 | make_siblings(PixelFormat::Z32FS8, PixelFormat::RG32F); | 263 | make_siblings(PixelFormat::Z32FS8, PixelFormat::RG32F); |
| 264 | sampled_textures_stack.resize(64); | ||
| 242 | } | 265 | } |
| 243 | 266 | ||
| 244 | ~TextureCache() = default; | 267 | ~TextureCache() = default; |
| @@ -275,7 +298,7 @@ protected: | |||
| 275 | } | 298 | } |
| 276 | 299 | ||
| 277 | void Unregister(TSurface surface) { | 300 | void Unregister(TSurface surface) { |
| 278 | if (guard_cache && surface->IsProtected()) { | 301 | if (guard_render_targets && surface->IsProtected()) { |
| 279 | return; | 302 | return; |
| 280 | } | 303 | } |
| 281 | const GPUVAddr gpu_addr = surface->GetGpuAddr(); | 304 | const GPUVAddr gpu_addr = surface->GetGpuAddr(); |
| @@ -766,7 +789,8 @@ private: | |||
| 766 | u64 ticks{}; | 789 | u64 ticks{}; |
| 767 | 790 | ||
| 768 | // Guards the cache for protection conflicts. | 791 | // Guards the cache for protection conflicts. |
| 769 | bool guard_cache{}; | 792 | bool guard_render_targets{}; |
| 793 | bool guard_samplers{}; | ||
| 770 | 794 | ||
| 771 | // The siblings table is for formats that can inter exchange with one another | 795 | // The siblings table is for formats that can inter exchange with one another |
| 772 | // without causing issues. This is only valid when a conflict occurs on a non | 796 | // without causing issues. This is only valid when a conflict occurs on a non |
| @@ -792,6 +816,9 @@ private: | |||
| 792 | render_targets; | 816 | render_targets; |
| 793 | FramebufferTargetInfo depth_buffer; | 817 | FramebufferTargetInfo depth_buffer; |
| 794 | 818 | ||
| 819 | std::vector<TSurface> sampled_textures_stack{}; | ||
| 820 | u32 sampled_textures_stack_pointer{}; | ||
| 821 | |||
| 795 | StagingCache staging_cache; | 822 | StagingCache staging_cache; |
| 796 | std::recursive_mutex mutex; | 823 | std::recursive_mutex mutex; |
| 797 | }; | 824 | }; |