diff options
| author | 2018-11-29 16:13:13 -0300 | |
|---|---|---|
| committer | 2018-11-29 16:58:20 -0300 | |
| commit | 2908d302748c1db6df3f44cd27d51a34a1b50c31 (patch) | |
| tree | 3a8c722a381133eb7316973b2aef282f770ea4fd | |
| parent | Merge pull request #1768 from greggameplayer/patch-2 (diff) | |
| download | yuzu-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.h | 1 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 35 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 10 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_gen.h | 1 |
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 | ||
| 366 | std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const { | 377 | std::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 | ||
| 1022 | void RasterizerOpenGL::SyncClipEnabled() { | 1032 | void 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 | ||
| 1034 | void RasterizerOpenGL::SyncClipCoef() { | 1047 | void RasterizerOpenGL::SyncClipCoef() { |
| 1035 | UNREACHABLE(); | 1048 | UNIMPLEMENTED(); |
| 1036 | } | 1049 | } |
| 1037 | 1050 | ||
| 1038 | void RasterizerOpenGL::SyncCullMode() { | 1051 | void 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 | ||
| 1003 | private: | 1011 | private: |
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: | |||
| 163 | struct ShaderEntries { | 163 | struct 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 | ||