summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2019-12-29 02:03:05 -0300
committerGravatar ReinUsesLisp2020-02-28 17:56:42 -0300
commitf7ec078592468fa22ff377b996a720c8be82c2dc (patch)
tree9326105d022b9e939f036c46d028f7f7ef8f9e5e /src
parentgl_state_tracker: Add dirty flags for buffers and divisors (diff)
downloadyuzu-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')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp28
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h5
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp5
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp5
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.h2
-rw-r--r--src/video_core/renderer_opengl/gl_state_tracker.cpp11
-rw-r--r--src/video_core/renderer_opengl/gl_state_tracker.h1
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() {
232void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { 232void 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
311std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const { 309std::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
975void RasterizerOpenGL::SyncClipEnabled( 973void 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
625Shader ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) { 626Shader 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
127void SetupDirtyShaders(Tables& tables) {
128 FillBlock(tables[0], OFF(shader_config[0]), NUM(shader_config[0]) * Regs::MaxShaderProgram,
129 Shaders);
130}
131
132void SetupDirtyMisc(Tables& tables) {
133 tables[0][OFF(clip_distance_enabled)] = ClipDistances;
134}
135
127} // Anonymous namespace 136} // Anonymous namespace
128 137
129StateTracker::StateTracker(Core::System& system) : system{system} {} 138StateTracker::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,