diff options
| author | 2019-12-29 02:03:05 -0300 | |
|---|---|---|
| committer | 2020-02-28 17:56:42 -0300 | |
| commit | f7ec078592468fa22ff377b996a720c8be82c2dc (patch) | |
| tree | 9326105d022b9e939f036c46d028f7f7ef8f9e5e /src | |
| parent | gl_state_tracker: Add dirty flags for buffers and divisors (diff) | |
| download | yuzu-f7ec078592468fa22ff377b996a720c8be82c2dc.tar.gz yuzu-f7ec078592468fa22ff377b996a720c8be82c2dc.tar.xz yuzu-f7ec078592468fa22ff377b996a720c8be82c2dc.zip | |
gl_state_tracker: Implement dirty flags for clip distances and shaders
Diffstat (limited to 'src')
7 files changed, 43 insertions, 14 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index bb89985cc..717f127e9 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -232,8 +232,7 @@ GLintptr RasterizerOpenGL::SetupIndexBuffer() { | |||
| 232 | void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { | 232 | void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { |
| 233 | MICROPROFILE_SCOPE(OpenGL_Shader); | 233 | MICROPROFILE_SCOPE(OpenGL_Shader); |
| 234 | auto& gpu = system.GPU().Maxwell3D(); | 234 | auto& gpu = system.GPU().Maxwell3D(); |
| 235 | 235 | u32 clip_distances = 0; | |
| 236 | std::array<bool, Maxwell::NumClipDistances> clip_distances{}; | ||
| 237 | 236 | ||
| 238 | for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) { | 237 | for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) { |
| 239 | const auto& shader_config = gpu.regs.shader_config[index]; | 238 | const auto& shader_config = gpu.regs.shader_config[index]; |
| @@ -294,9 +293,7 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { | |||
| 294 | // When a clip distance is enabled but not set in the shader it crops parts of the screen | 293 | // When a clip distance is enabled but not set in the shader it crops parts of the screen |
| 295 | // (sometimes it's half the screen, sometimes three quarters). To avoid this, enable the | 294 | // (sometimes it's half the screen, sometimes three quarters). To avoid this, enable the |
| 296 | // clip distances only when it's written by a shader stage. | 295 | // clip distances only when it's written by a shader stage. |
| 297 | for (std::size_t i = 0; i < Maxwell::NumClipDistances; ++i) { | 296 | clip_distances |= shader->GetShaderEntries().clip_distances; |
| 298 | clip_distances[i] = clip_distances[i] || shader->GetShaderEntries().clip_distances[i]; | ||
| 299 | } | ||
| 300 | 297 | ||
| 301 | // When VertexA is enabled, we have dual vertex shaders | 298 | // When VertexA is enabled, we have dual vertex shaders |
| 302 | if (program == Maxwell::ShaderProgram::VertexA) { | 299 | if (program == Maxwell::ShaderProgram::VertexA) { |
| @@ -306,6 +303,7 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { | |||
| 306 | } | 303 | } |
| 307 | 304 | ||
| 308 | SyncClipEnabled(clip_distances); | 305 | SyncClipEnabled(clip_distances); |
| 306 | gpu.dirty.flags[Dirty::Shaders] = false; | ||
| 309 | } | 307 | } |
| 310 | 308 | ||
| 311 | std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const { | 309 | std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const { |
| @@ -972,12 +970,22 @@ void RasterizerOpenGL::SyncDepthClamp() { | |||
| 972 | oglEnable(GL_DEPTH_CLAMP, state.depth_clamp_far || state.depth_clamp_near); | 970 | oglEnable(GL_DEPTH_CLAMP, state.depth_clamp_far || state.depth_clamp_near); |
| 973 | } | 971 | } |
| 974 | 972 | ||
| 975 | void RasterizerOpenGL::SyncClipEnabled( | 973 | void RasterizerOpenGL::SyncClipEnabled(u32 clip_mask) { |
| 976 | const std::array<bool, Maxwell::Regs::NumClipDistances>& clip_mask) { | 974 | auto& gpu = system.GPU().Maxwell3D(); |
| 977 | const auto& regs = system.GPU().Maxwell3D().regs; | 975 | auto& flags = gpu.dirty.flags; |
| 976 | if (!flags[Dirty::ClipDistances] && !flags[Dirty::Shaders]) { | ||
| 977 | return; | ||
| 978 | } | ||
| 979 | flags[Dirty::ClipDistances] = false; | ||
| 980 | |||
| 981 | clip_mask &= gpu.regs.clip_distance_enabled; | ||
| 982 | if (clip_mask == last_clip_distance_mask) { | ||
| 983 | return; | ||
| 984 | } | ||
| 985 | last_clip_distance_mask = clip_mask; | ||
| 986 | |||
| 978 | for (std::size_t i = 0; i < Maxwell::Regs::NumClipDistances; ++i) { | 987 | for (std::size_t i = 0; i < Maxwell::Regs::NumClipDistances; ++i) { |
| 979 | oglEnable(static_cast<GLenum>(GL_CLIP_DISTANCE0 + i), | 988 | oglEnable(static_cast<GLenum>(GL_CLIP_DISTANCE0 + i), (clip_mask >> i) & 1); |
| 980 | clip_mask[i] && ((regs.clip_distance_enabled >> i) & 1)); | ||
| 981 | } | 989 | } |
| 982 | } | 990 | } |
| 983 | 991 | ||
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 22a3a3352..11206f557 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -137,8 +137,7 @@ private: | |||
| 137 | void SyncDepthClamp(); | 137 | void SyncDepthClamp(); |
| 138 | 138 | ||
| 139 | /// Syncs the clip enabled status to match the guest state | 139 | /// Syncs the clip enabled status to match the guest state |
| 140 | void SyncClipEnabled( | 140 | void SyncClipEnabled(u32 clip_mask); |
| 141 | const std::array<bool, Tegra::Engines::Maxwell3D::Regs::NumClipDistances>& clip_mask); | ||
| 142 | 141 | ||
| 143 | /// Syncs the clip coefficients to match the guest state | 142 | /// Syncs the clip coefficients to match the guest state |
| 144 | void SyncClipCoef(); | 143 | void SyncClipCoef(); |
| @@ -230,6 +229,8 @@ private: | |||
| 230 | 229 | ||
| 231 | /// Number of commands queued to the OpenGL driver. Reseted on flush. | 230 | /// Number of commands queued to the OpenGL driver. Reseted on flush. |
| 232 | std::size_t num_queued_commands = 0; | 231 | std::size_t num_queued_commands = 0; |
| 232 | |||
| 233 | u32 last_clip_distance_mask = 0; | ||
| 233 | }; | 234 | }; |
| 234 | 235 | ||
| 235 | } // namespace OpenGL | 236 | } // namespace OpenGL |
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index bef141f63..4cb89db8c 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include "video_core/renderer_opengl/gl_shader_cache.h" | 22 | #include "video_core/renderer_opengl/gl_shader_cache.h" |
| 23 | #include "video_core/renderer_opengl/gl_shader_decompiler.h" | 23 | #include "video_core/renderer_opengl/gl_shader_decompiler.h" |
| 24 | #include "video_core/renderer_opengl/gl_shader_disk_cache.h" | 24 | #include "video_core/renderer_opengl/gl_shader_disk_cache.h" |
| 25 | #include "video_core/renderer_opengl/gl_state_tracker.h" | ||
| 25 | #include "video_core/renderer_opengl/utils.h" | 26 | #include "video_core/renderer_opengl/utils.h" |
| 26 | #include "video_core/shader/shader_ir.h" | 27 | #include "video_core/shader/shader_ir.h" |
| 27 | 28 | ||
| @@ -623,6 +624,10 @@ bool ShaderCacheOpenGL::GenerateUnspecializedShaders( | |||
| 623 | } | 624 | } |
| 624 | 625 | ||
| 625 | Shader ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) { | 626 | Shader ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) { |
| 627 | if (!system.GPU().Maxwell3D().dirty.flags[Dirty::Shaders]) { | ||
| 628 | return last_shaders[static_cast<std::size_t>(program)]; | ||
| 629 | } | ||
| 630 | |||
| 626 | auto& memory_manager{system.GPU().MemoryManager()}; | 631 | auto& memory_manager{system.GPU().MemoryManager()}; |
| 627 | const GPUVAddr address{GetShaderAddress(system, program)}; | 632 | const GPUVAddr address{GetShaderAddress(system, program)}; |
| 628 | 633 | ||
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 4735000b5..3a41ed30c 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -2547,7 +2547,10 @@ ShaderEntries GetEntries(const VideoCommon::Shader::ShaderIR& ir) { | |||
| 2547 | for (const auto& image : ir.GetImages()) { | 2547 | for (const auto& image : ir.GetImages()) { |
| 2548 | entries.images.emplace_back(image); | 2548 | entries.images.emplace_back(image); |
| 2549 | } | 2549 | } |
| 2550 | entries.clip_distances = ir.GetClipDistances(); | 2550 | const auto clip_distances = ir.GetClipDistances(); |
| 2551 | for (std::size_t i = 0; i < std::size(clip_distances); ++i) { | ||
| 2552 | entries.clip_distances = (clip_distances[i] ? 1U : 0U) << i; | ||
| 2553 | } | ||
| 2551 | entries.shader_length = ir.GetLength(); | 2554 | entries.shader_length = ir.GetLength(); |
| 2552 | return entries; | 2555 | return entries; |
| 2553 | } | 2556 | } |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.h b/src/video_core/renderer_opengl/gl_shader_decompiler.h index 7876f48d6..0f692c1db 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.h +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.h | |||
| @@ -74,7 +74,7 @@ struct ShaderEntries { | |||
| 74 | std::vector<GlobalMemoryEntry> global_memory_entries; | 74 | std::vector<GlobalMemoryEntry> global_memory_entries; |
| 75 | std::vector<SamplerEntry> samplers; | 75 | std::vector<SamplerEntry> samplers; |
| 76 | std::vector<ImageEntry> images; | 76 | std::vector<ImageEntry> images; |
| 77 | std::array<bool, Maxwell::NumClipDistances> clip_distances{}; | 77 | u32 clip_distances{}; |
| 78 | std::size_t shader_length{}; | 78 | std::size_t shader_length{}; |
| 79 | }; | 79 | }; |
| 80 | 80 | ||
diff --git a/src/video_core/renderer_opengl/gl_state_tracker.cpp b/src/video_core/renderer_opengl/gl_state_tracker.cpp index 7150b9247..bc5942a7f 100644 --- a/src/video_core/renderer_opengl/gl_state_tracker.cpp +++ b/src/video_core/renderer_opengl/gl_state_tracker.cpp | |||
| @@ -124,6 +124,15 @@ void SetupDirtyScissors(Tables& tables) { | |||
| 124 | FillBlock(tables[1], OFF(scissor_test), NUM(scissor_test), Scissors); | 124 | FillBlock(tables[1], OFF(scissor_test), NUM(scissor_test), Scissors); |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | void SetupDirtyShaders(Tables& tables) { | ||
| 128 | FillBlock(tables[0], OFF(shader_config[0]), NUM(shader_config[0]) * Regs::MaxShaderProgram, | ||
| 129 | Shaders); | ||
| 130 | } | ||
| 131 | |||
| 132 | void SetupDirtyMisc(Tables& tables) { | ||
| 133 | tables[0][OFF(clip_distance_enabled)] = ClipDistances; | ||
| 134 | } | ||
| 135 | |||
| 127 | } // Anonymous namespace | 136 | } // Anonymous namespace |
| 128 | 137 | ||
| 129 | StateTracker::StateTracker(Core::System& system) : system{system} {} | 138 | StateTracker::StateTracker(Core::System& system) : system{system} {} |
| @@ -137,6 +146,8 @@ void StateTracker::Initialize() { | |||
| 137 | SetupDirtyScissors(tables); | 146 | SetupDirtyScissors(tables); |
| 138 | SetupDirtyVertexArrays(tables); | 147 | SetupDirtyVertexArrays(tables); |
| 139 | SetupDirtyVertexFormat(tables); | 148 | SetupDirtyVertexFormat(tables); |
| 149 | SetupDirtyShaders(tables); | ||
| 150 | SetupDirtyMisc(tables); | ||
| 140 | 151 | ||
| 141 | auto& store = dirty.on_write_stores; | 152 | auto& store = dirty.on_write_stores; |
| 142 | store[RenderTargets] = true; | 153 | store[RenderTargets] = true; |
diff --git a/src/video_core/renderer_opengl/gl_state_tracker.h b/src/video_core/renderer_opengl/gl_state_tracker.h index 85667cee1..11fdc6de4 100644 --- a/src/video_core/renderer_opengl/gl_state_tracker.h +++ b/src/video_core/renderer_opengl/gl_state_tracker.h | |||
| @@ -48,6 +48,7 @@ enum : u8 { | |||
| 48 | ColorMask7 = ColorMask0 + 7, | 48 | ColorMask7 = ColorMask0 + 7, |
| 49 | 49 | ||
| 50 | Shaders, | 50 | Shaders, |
| 51 | ClipDistances, | ||
| 51 | CullTestEnable, | 52 | CullTestEnable, |
| 52 | FrontFace, | 53 | FrontFace, |
| 53 | CullFace, | 54 | CullFace, |