summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/maxwell_3d.h1
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp35
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h3
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp10
-rw-r--r--src/video_core/renderer_opengl/gl_shader_gen.h1
5 files changed, 37 insertions, 13 deletions
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index d3b3ed1f0..25bb7604a 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -42,6 +42,7 @@ public:
42 static constexpr std::size_t NumVertexArrays = 32; 42 static constexpr std::size_t NumVertexArrays = 32;
43 static constexpr std::size_t NumVertexAttributes = 32; 43 static constexpr std::size_t NumVertexAttributes = 32;
44 static constexpr std::size_t NumTextureSamplers = 32; 44 static constexpr std::size_t NumTextureSamplers = 32;
45 static constexpr std::size_t NumClipDistances = 8;
45 static constexpr std::size_t MaxShaderProgram = 6; 46 static constexpr std::size_t MaxShaderProgram = 6;
46 static constexpr std::size_t MaxShaderStage = 5; 47 static constexpr std::size_t MaxShaderStage = 5;
47 // Maximum number of const buffers per shader stage. 48 // Maximum number of const buffers per shader stage.
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 70855fcfd..9e93bd609 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -282,6 +282,7 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {
282 // shaders. The constbuffer bindpoint starts after the shader stage configuration bind points. 282 // shaders. The constbuffer bindpoint starts after the shader stage configuration bind points.
283 u32 current_constbuffer_bindpoint = Tegra::Engines::Maxwell3D::Regs::MaxShaderStage; 283 u32 current_constbuffer_bindpoint = Tegra::Engines::Maxwell3D::Regs::MaxShaderStage;
284 u32 current_texture_bindpoint = 0; 284 u32 current_texture_bindpoint = 0;
285 std::array<bool, Maxwell::NumClipDistances> clip_distances{};
285 286
286 for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) { 287 for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) {
287 const auto& shader_config = gpu.regs.shader_config[index]; 288 const auto& shader_config = gpu.regs.shader_config[index];
@@ -342,12 +343,22 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {
342 current_texture_bindpoint = SetupTextures(static_cast<Maxwell::ShaderStage>(stage), shader, 343 current_texture_bindpoint = SetupTextures(static_cast<Maxwell::ShaderStage>(stage), shader,
343 primitive_mode, current_texture_bindpoint); 344 primitive_mode, current_texture_bindpoint);
344 345
346 // Workaround for Intel drivers.
347 // When a clip distance is enabled but not set in the shader it crops parts of the screen
348 // (sometimes it's half the screen, sometimes three quarters). To avoid this, enable the
349 // clip distances only when it's written by a shader stage.
350 for (std::size_t i = 0; i < Maxwell::NumClipDistances; ++i) {
351 clip_distances[i] |= shader->GetShaderEntries().clip_distances[i];
352 }
353
345 // When VertexA is enabled, we have dual vertex shaders 354 // When VertexA is enabled, we have dual vertex shaders
346 if (program == Maxwell::ShaderProgram::VertexA) { 355 if (program == Maxwell::ShaderProgram::VertexA) {
347 // VertexB was combined with VertexA, so we skip the VertexB iteration 356 // VertexB was combined with VertexA, so we skip the VertexB iteration
348 index++; 357 index++;
349 } 358 }
350 } 359 }
360
361 SyncClipEnabled(clip_distances);
351} 362}
352 363
353std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const { 364std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const {
@@ -629,7 +640,6 @@ void RasterizerOpenGL::DrawArrays() {
629 SyncCullMode(); 640 SyncCullMode();
630 SyncPrimitiveRestart(); 641 SyncPrimitiveRestart();
631 SyncScissorTest(state); 642 SyncScissorTest(state);
632 SyncClipEnabled();
633 // Alpha Testing is synced on shaders. 643 // Alpha Testing is synced on shaders.
634 SyncTransformFeedback(); 644 SyncTransformFeedback();
635 SyncPointState(); 645 SyncPointState();
@@ -1006,20 +1016,23 @@ void RasterizerOpenGL::SyncViewport(OpenGLState& current_state) {
1006 state.depth_clamp.near_plane = regs.view_volume_clip_control.depth_clamp_near != 0; 1016 state.depth_clamp.near_plane = regs.view_volume_clip_control.depth_clamp_near != 0;
1007} 1017}
1008 1018
1009void RasterizerOpenGL::SyncClipEnabled() { 1019void RasterizerOpenGL::SyncClipEnabled(
1020 const std::array<bool, Maxwell::Regs::NumClipDistances>& clip_mask) {
1021
1010 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; 1022 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
1011 state.clip_distance[0] = regs.clip_distance_enabled.c0 != 0; 1023 const std::array<bool, Maxwell::Regs::NumClipDistances> reg_state{
1012 state.clip_distance[1] = regs.clip_distance_enabled.c1 != 0; 1024 regs.clip_distance_enabled.c0 != 0, regs.clip_distance_enabled.c1 != 0,
1013 state.clip_distance[2] = regs.clip_distance_enabled.c2 != 0; 1025 regs.clip_distance_enabled.c2 != 0, regs.clip_distance_enabled.c3 != 0,
1014 state.clip_distance[3] = regs.clip_distance_enabled.c3 != 0; 1026 regs.clip_distance_enabled.c4 != 0, regs.clip_distance_enabled.c5 != 0,
1015 state.clip_distance[4] = regs.clip_distance_enabled.c4 != 0; 1027 regs.clip_distance_enabled.c6 != 0, regs.clip_distance_enabled.c7 != 0};
1016 state.clip_distance[5] = regs.clip_distance_enabled.c5 != 0; 1028
1017 state.clip_distance[6] = regs.clip_distance_enabled.c6 != 0; 1029 for (std::size_t i = 0; i < Maxwell::Regs::NumClipDistances; ++i) {
1018 state.clip_distance[7] = regs.clip_distance_enabled.c7 != 0; 1030 state.clip_distance[i] = reg_state[i] && clip_mask[i];
1031 }
1019} 1032}
1020 1033
1021void RasterizerOpenGL::SyncClipCoef() { 1034void RasterizerOpenGL::SyncClipCoef() {
1022 UNREACHABLE(); 1035 UNIMPLEMENTED();
1023} 1036}
1024 1037
1025void RasterizerOpenGL::SyncCullMode() { 1038void RasterizerOpenGL::SyncCullMode() {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index ed70d73ee..988fa3e27 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -128,7 +128,8 @@ private:
128 void SyncViewport(OpenGLState& current_state); 128 void SyncViewport(OpenGLState& current_state);
129 129
130 /// Syncs the clip enabled status to match the guest state 130 /// Syncs the clip enabled status to match the guest state
131 void SyncClipEnabled(); 131 void SyncClipEnabled(
132 const std::array<bool, Tegra::Engines::Maxwell3D::Regs::NumClipDistances>& clip_mask);
132 133
133 /// Syncs the clip coefficients to match the guest state 134 /// Syncs the clip coefficients to match the guest state
134 void SyncClipCoef(); 135 void SyncClipCoef();
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 0c4524d5c..0c1632bd1 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -525,6 +525,7 @@ public:
525 ((header.vtg.clip_distances >> index) & 1) == 0, 525 ((header.vtg.clip_distances >> index) & 1) == 0,
526 "Shader is setting gl_ClipDistance{} without enabling it in the header", index); 526 "Shader is setting gl_ClipDistance{} without enabling it in the header", index);
527 527
528 clip_distances[index] = true;
528 fixed_pipeline_output_attributes_used.insert(attribute); 529 fixed_pipeline_output_attributes_used.insert(attribute);
529 shader.AddLine(dest + '[' + std::to_string(index) + "] = " + src + ';'); 530 shader.AddLine(dest + '[' + std::to_string(index) + "] = " + src + ';');
530 break; 531 break;
@@ -602,6 +603,11 @@ public:
602 return used_samplers; 603 return used_samplers;
603 } 604 }
604 605
606 /// Returns an array of the used clip distances.
607 const std::array<bool, Maxwell::NumClipDistances>& GetClipDistances() const {
608 return clip_distances;
609 }
610
605 /// Returns the GLSL sampler used for the input shader sampler, and creates a new one if 611 /// Returns the GLSL sampler used for the input shader sampler, and creates a new one if
606 /// necessary. 612 /// necessary.
607 std::string AccessSampler(const Sampler& sampler, Tegra::Shader::TextureType type, 613 std::string AccessSampler(const Sampler& sampler, Tegra::Shader::TextureType type,
@@ -975,6 +981,7 @@ private:
975 const std::string& suffix; 981 const std::string& suffix;
976 const Tegra::Shader::Header& header; 982 const Tegra::Shader::Header& header;
977 std::unordered_set<Attribute::Index> fixed_pipeline_output_attributes_used; 983 std::unordered_set<Attribute::Index> fixed_pipeline_output_attributes_used;
984 std::array<bool, Maxwell::NumClipDistances> clip_distances{};
978 u64 local_memory_size; 985 u64 local_memory_size;
979}; 986};
980 987
@@ -997,7 +1004,8 @@ public:
997 1004
998 /// Returns entries in the shader that are useful for external functions 1005 /// Returns entries in the shader that are useful for external functions
999 ShaderEntries GetEntries() const { 1006 ShaderEntries GetEntries() const {
1000 return {regs.GetConstBuffersDeclarations(), regs.GetSamplers(), shader_length}; 1007 return {regs.GetConstBuffersDeclarations(), regs.GetSamplers(), regs.GetClipDistances(),
1008 shader_length};
1001 } 1009 }
1002 1010
1003private: 1011private:
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.h b/src/video_core/renderer_opengl/gl_shader_gen.h
index b425d98ae..4fa6d7612 100644
--- a/src/video_core/renderer_opengl/gl_shader_gen.h
+++ b/src/video_core/renderer_opengl/gl_shader_gen.h
@@ -163,6 +163,7 @@ private:
163struct ShaderEntries { 163struct ShaderEntries {
164 std::vector<ConstBufferEntry> const_buffer_entries; 164 std::vector<ConstBufferEntry> const_buffer_entries;
165 std::vector<SamplerEntry> texture_samplers; 165 std::vector<SamplerEntry> texture_samplers;
166 std::array<bool, Tegra::Engines::Maxwell3D::Regs::NumClipDistances> clip_distances;
166 std::size_t shader_length; 167 std::size_t shader_length;
167}; 168};
168 169