diff options
Diffstat (limited to 'src')
| -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 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 | ||
| 353 | std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const { | 364 | std::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 | ||
| 1009 | void RasterizerOpenGL::SyncClipEnabled() { | 1019 | void 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 | ||
| 1021 | void RasterizerOpenGL::SyncClipCoef() { | 1034 | void RasterizerOpenGL::SyncClipCoef() { |
| 1022 | UNREACHABLE(); | 1035 | UNIMPLEMENTED(); |
| 1023 | } | 1036 | } |
| 1024 | 1037 | ||
| 1025 | void RasterizerOpenGL::SyncCullMode() { | 1038 | void 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 | ||
| 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 | ||