summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2018-11-29 16:13:13 -0300
committerGravatar ReinUsesLisp2018-11-29 16:58:20 -0300
commit2908d302748c1db6df3f44cd27d51a34a1b50c31 (patch)
tree3a8c722a381133eb7316973b2aef282f770ea4fd
parentMerge pull request #1768 from greggameplayer/patch-2 (diff)
downloadyuzu-2908d302748c1db6df3f44cd27d51a34a1b50c31.tar.gz
yuzu-2908d302748c1db6df3f44cd27d51a34a1b50c31.tar.xz
yuzu-2908d302748c1db6df3f44cd27d51a34a1b50c31.zip
gl_rasterizer: Enable clip distances when set in register and in shader
-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 a44bbfae8..7cf213a0c 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -295,6 +295,7 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {
295 // shaders. The constbuffer bindpoint starts after the shader stage configuration bind points. 295 // shaders. The constbuffer bindpoint starts after the shader stage configuration bind points.
296 u32 current_constbuffer_bindpoint = Tegra::Engines::Maxwell3D::Regs::MaxShaderStage; 296 u32 current_constbuffer_bindpoint = Tegra::Engines::Maxwell3D::Regs::MaxShaderStage;
297 u32 current_texture_bindpoint = 0; 297 u32 current_texture_bindpoint = 0;
298 std::array<bool, Maxwell::NumClipDistances> clip_distances{};
298 299
299 for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) { 300 for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) {
300 const auto& shader_config = gpu.regs.shader_config[index]; 301 const auto& shader_config = gpu.regs.shader_config[index];
@@ -355,12 +356,22 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {
355 current_texture_bindpoint = SetupTextures(static_cast<Maxwell::ShaderStage>(stage), shader, 356 current_texture_bindpoint = SetupTextures(static_cast<Maxwell::ShaderStage>(stage), shader,
356 primitive_mode, current_texture_bindpoint); 357 primitive_mode, current_texture_bindpoint);
357 358
359 // Workaround for Intel drivers.
360 // When a clip distance is enabled but not set in the shader it crops parts of the screen
361 // (sometimes it's half the screen, sometimes three quarters). To avoid this, enable the
362 // clip distances only when it's written by a shader stage.
363 for (std::size_t i = 0; i < Maxwell::NumClipDistances; ++i) {
364 clip_distances[i] |= shader->GetShaderEntries().clip_distances[i];
365 }
366
358 // When VertexA is enabled, we have dual vertex shaders 367 // When VertexA is enabled, we have dual vertex shaders
359 if (program == Maxwell::ShaderProgram::VertexA) { 368 if (program == Maxwell::ShaderProgram::VertexA) {
360 // VertexB was combined with VertexA, so we skip the VertexB iteration 369 // VertexB was combined with VertexA, so we skip the VertexB iteration
361 index++; 370 index++;
362 } 371 }
363 } 372 }
373
374 SyncClipEnabled(clip_distances);
364} 375}
365 376
366std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const { 377std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const {
@@ -642,7 +653,6 @@ void RasterizerOpenGL::DrawArrays() {
642 SyncCullMode(); 653 SyncCullMode();
643 SyncPrimitiveRestart(); 654 SyncPrimitiveRestart();
644 SyncScissorTest(state); 655 SyncScissorTest(state);
645 SyncClipEnabled();
646 // Alpha Testing is synced on shaders. 656 // Alpha Testing is synced on shaders.
647 SyncTransformFeedback(); 657 SyncTransformFeedback();
648 SyncPointState(); 658 SyncPointState();
@@ -1019,20 +1029,23 @@ void RasterizerOpenGL::SyncViewport(OpenGLState& current_state) {
1019 state.depth_clamp.near_plane = regs.view_volume_clip_control.depth_clamp_near != 0; 1029 state.depth_clamp.near_plane = regs.view_volume_clip_control.depth_clamp_near != 0;
1020} 1030}
1021 1031
1022void RasterizerOpenGL::SyncClipEnabled() { 1032void RasterizerOpenGL::SyncClipEnabled(
1033 const std::array<bool, Maxwell::Regs::NumClipDistances>& clip_mask) {
1034
1023 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; 1035 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
1024 state.clip_distance[0] = regs.clip_distance_enabled.c0 != 0; 1036 const std::array<bool, Maxwell::Regs::NumClipDistances> reg_state{
1025 state.clip_distance[1] = regs.clip_distance_enabled.c1 != 0; 1037 regs.clip_distance_enabled.c0 != 0, regs.clip_distance_enabled.c1 != 0,
1026 state.clip_distance[2] = regs.clip_distance_enabled.c2 != 0; 1038 regs.clip_distance_enabled.c2 != 0, regs.clip_distance_enabled.c3 != 0,
1027 state.clip_distance[3] = regs.clip_distance_enabled.c3 != 0; 1039 regs.clip_distance_enabled.c4 != 0, regs.clip_distance_enabled.c5 != 0,
1028 state.clip_distance[4] = regs.clip_distance_enabled.c4 != 0; 1040 regs.clip_distance_enabled.c6 != 0, regs.clip_distance_enabled.c7 != 0};
1029 state.clip_distance[5] = regs.clip_distance_enabled.c5 != 0; 1041
1030 state.clip_distance[6] = regs.clip_distance_enabled.c6 != 0; 1042 for (std::size_t i = 0; i < Maxwell::Regs::NumClipDistances; ++i) {
1031 state.clip_distance[7] = regs.clip_distance_enabled.c7 != 0; 1043 state.clip_distance[i] = reg_state[i] && clip_mask[i];
1044 }
1032} 1045}
1033 1046
1034void RasterizerOpenGL::SyncClipCoef() { 1047void RasterizerOpenGL::SyncClipCoef() {
1035 UNREACHABLE(); 1048 UNIMPLEMENTED();
1036} 1049}
1037 1050
1038void RasterizerOpenGL::SyncCullMode() { 1051void RasterizerOpenGL::SyncCullMode() {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 7ec9746b1..ef19ef6d7 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -142,7 +142,8 @@ private:
142 void SyncViewport(OpenGLState& current_state); 142 void SyncViewport(OpenGLState& current_state);
143 143
144 /// Syncs the clip enabled status to match the guest state 144 /// Syncs the clip enabled status to match the guest state
145 void SyncClipEnabled(); 145 void SyncClipEnabled(
146 const std::array<bool, Tegra::Engines::Maxwell3D::Regs::NumClipDistances>& clip_mask);
146 147
147 /// Syncs the clip coefficients to match the guest state 148 /// Syncs the clip coefficients to match the guest state
148 void SyncClipCoef(); 149 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