mirror of
				https://git.suyu.dev/suyu/suyu.git
				synced 2025-11-01 07:16:42 +08:00 
			
		
		
		
	Merge pull request #1827 from ReinUsesLisp/clip-and-shader
gl_rasterizer: Enable clip distances when set in register and in shader
This commit is contained in:
		
						commit
						7ce17b2cf6
					
				| @ -42,6 +42,7 @@ public: | |||||||
|         static constexpr std::size_t NumVertexArrays = 32; |         static constexpr std::size_t NumVertexArrays = 32; | ||||||
|         static constexpr std::size_t NumVertexAttributes = 32; |         static constexpr std::size_t NumVertexAttributes = 32; | ||||||
|         static constexpr std::size_t NumTextureSamplers = 32; |         static constexpr std::size_t NumTextureSamplers = 32; | ||||||
|  |         static constexpr std::size_t NumClipDistances = 8; | ||||||
|         static constexpr std::size_t MaxShaderProgram = 6; |         static constexpr std::size_t MaxShaderProgram = 6; | ||||||
|         static constexpr std::size_t MaxShaderStage = 5; |         static constexpr std::size_t MaxShaderStage = 5; | ||||||
|         // Maximum number of const buffers per shader stage.
 |         // Maximum number of const buffers per shader stage.
 | ||||||
|  | |||||||
| @ -282,6 +282,7 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { | |||||||
|     // shaders. The constbuffer bindpoint starts after the shader stage configuration bind points.
 |     // shaders. The constbuffer bindpoint starts after the shader stage configuration bind points.
 | ||||||
|     u32 current_constbuffer_bindpoint = Tegra::Engines::Maxwell3D::Regs::MaxShaderStage; |     u32 current_constbuffer_bindpoint = Tegra::Engines::Maxwell3D::Regs::MaxShaderStage; | ||||||
|     u32 current_texture_bindpoint = 0; |     u32 current_texture_bindpoint = 0; | ||||||
|  |     std::array<bool, Maxwell::NumClipDistances> clip_distances{}; | ||||||
| 
 | 
 | ||||||
|     for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) { |     for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) { | ||||||
|         const auto& shader_config = gpu.regs.shader_config[index]; |         const auto& shader_config = gpu.regs.shader_config[index]; | ||||||
| @ -342,12 +343,22 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { | |||||||
|         current_texture_bindpoint = SetupTextures(static_cast<Maxwell::ShaderStage>(stage), shader, |         current_texture_bindpoint = SetupTextures(static_cast<Maxwell::ShaderStage>(stage), shader, | ||||||
|                                                   primitive_mode, current_texture_bindpoint); |                                                   primitive_mode, current_texture_bindpoint); | ||||||
| 
 | 
 | ||||||
|  |         // Workaround for Intel drivers.
 | ||||||
|  |         // When a clip distance is enabled but not set in the shader it crops parts of the screen
 | ||||||
|  |         // (sometimes it's half the screen, sometimes three quarters). To avoid this, enable the
 | ||||||
|  |         // clip distances only when it's written by a shader stage.
 | ||||||
|  |         for (std::size_t i = 0; i < Maxwell::NumClipDistances; ++i) { | ||||||
|  |             clip_distances[i] |= shader->GetShaderEntries().clip_distances[i]; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         // When VertexA is enabled, we have dual vertex shaders
 |         // When VertexA is enabled, we have dual vertex shaders
 | ||||||
|         if (program == Maxwell::ShaderProgram::VertexA) { |         if (program == Maxwell::ShaderProgram::VertexA) { | ||||||
|             // VertexB was combined with VertexA, so we skip the VertexB iteration
 |             // VertexB was combined with VertexA, so we skip the VertexB iteration
 | ||||||
|             index++; |             index++; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     SyncClipEnabled(clip_distances); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const { | std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const { | ||||||
| @ -629,7 +640,6 @@ void RasterizerOpenGL::DrawArrays() { | |||||||
|     SyncCullMode(); |     SyncCullMode(); | ||||||
|     SyncPrimitiveRestart(); |     SyncPrimitiveRestart(); | ||||||
|     SyncScissorTest(state); |     SyncScissorTest(state); | ||||||
|     SyncClipEnabled(); |  | ||||||
|     // Alpha Testing is synced on shaders.
 |     // Alpha Testing is synced on shaders.
 | ||||||
|     SyncTransformFeedback(); |     SyncTransformFeedback(); | ||||||
|     SyncPointState(); |     SyncPointState(); | ||||||
| @ -1006,20 +1016,23 @@ void RasterizerOpenGL::SyncViewport(OpenGLState& current_state) { | |||||||
|     state.depth_clamp.near_plane = regs.view_volume_clip_control.depth_clamp_near != 0; |     state.depth_clamp.near_plane = regs.view_volume_clip_control.depth_clamp_near != 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RasterizerOpenGL::SyncClipEnabled() { | void RasterizerOpenGL::SyncClipEnabled( | ||||||
|  |     const std::array<bool, Maxwell::Regs::NumClipDistances>& clip_mask) { | ||||||
|  | 
 | ||||||
|     const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; |     const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; | ||||||
|     state.clip_distance[0] = regs.clip_distance_enabled.c0 != 0; |     const std::array<bool, Maxwell::Regs::NumClipDistances> reg_state{ | ||||||
|     state.clip_distance[1] = regs.clip_distance_enabled.c1 != 0; |         regs.clip_distance_enabled.c0 != 0, regs.clip_distance_enabled.c1 != 0, | ||||||
|     state.clip_distance[2] = regs.clip_distance_enabled.c2 != 0; |         regs.clip_distance_enabled.c2 != 0, regs.clip_distance_enabled.c3 != 0, | ||||||
|     state.clip_distance[3] = regs.clip_distance_enabled.c3 != 0; |         regs.clip_distance_enabled.c4 != 0, regs.clip_distance_enabled.c5 != 0, | ||||||
|     state.clip_distance[4] = regs.clip_distance_enabled.c4 != 0; |         regs.clip_distance_enabled.c6 != 0, regs.clip_distance_enabled.c7 != 0}; | ||||||
|     state.clip_distance[5] = regs.clip_distance_enabled.c5 != 0; | 
 | ||||||
|     state.clip_distance[6] = regs.clip_distance_enabled.c6 != 0; |     for (std::size_t i = 0; i < Maxwell::Regs::NumClipDistances; ++i) { | ||||||
|     state.clip_distance[7] = regs.clip_distance_enabled.c7 != 0; |         state.clip_distance[i] = reg_state[i] && clip_mask[i]; | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RasterizerOpenGL::SyncClipCoef() { | void RasterizerOpenGL::SyncClipCoef() { | ||||||
|     UNREACHABLE(); |     UNIMPLEMENTED(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RasterizerOpenGL::SyncCullMode() { | void RasterizerOpenGL::SyncCullMode() { | ||||||
|  | |||||||
| @ -128,7 +128,8 @@ private: | |||||||
|     void SyncViewport(OpenGLState& current_state); |     void SyncViewport(OpenGLState& current_state); | ||||||
| 
 | 
 | ||||||
|     /// Syncs the clip enabled status to match the guest state
 |     /// Syncs the clip enabled status to match the guest state
 | ||||||
|     void SyncClipEnabled(); |     void SyncClipEnabled( | ||||||
|  |         const std::array<bool, Tegra::Engines::Maxwell3D::Regs::NumClipDistances>& clip_mask); | ||||||
| 
 | 
 | ||||||
|     /// Syncs the clip coefficients to match the guest state
 |     /// Syncs the clip coefficients to match the guest state
 | ||||||
|     void SyncClipCoef(); |     void SyncClipCoef(); | ||||||
|  | |||||||
| @ -525,6 +525,7 @@ public: | |||||||
|                 ((header.vtg.clip_distances >> index) & 1) == 0, |                 ((header.vtg.clip_distances >> index) & 1) == 0, | ||||||
|                 "Shader is setting gl_ClipDistance{} without enabling it in the header", index); |                 "Shader is setting gl_ClipDistance{} without enabling it in the header", index); | ||||||
| 
 | 
 | ||||||
|  |             clip_distances[index] = true; | ||||||
|             fixed_pipeline_output_attributes_used.insert(attribute); |             fixed_pipeline_output_attributes_used.insert(attribute); | ||||||
|             shader.AddLine(dest + '[' + std::to_string(index) + "] = " + src + ';'); |             shader.AddLine(dest + '[' + std::to_string(index) + "] = " + src + ';'); | ||||||
|             break; |             break; | ||||||
| @ -602,6 +603,11 @@ public: | |||||||
|         return used_samplers; |         return used_samplers; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /// Returns an array of the used clip distances.
 | ||||||
|  |     const std::array<bool, Maxwell::NumClipDistances>& GetClipDistances() const { | ||||||
|  |         return clip_distances; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /// Returns the GLSL sampler used for the input shader sampler, and creates a new one if
 |     /// Returns the GLSL sampler used for the input shader sampler, and creates a new one if
 | ||||||
|     /// necessary.
 |     /// necessary.
 | ||||||
|     std::string AccessSampler(const Sampler& sampler, Tegra::Shader::TextureType type, |     std::string AccessSampler(const Sampler& sampler, Tegra::Shader::TextureType type, | ||||||
| @ -975,6 +981,7 @@ private: | |||||||
|     const std::string& suffix; |     const std::string& suffix; | ||||||
|     const Tegra::Shader::Header& header; |     const Tegra::Shader::Header& header; | ||||||
|     std::unordered_set<Attribute::Index> fixed_pipeline_output_attributes_used; |     std::unordered_set<Attribute::Index> fixed_pipeline_output_attributes_used; | ||||||
|  |     std::array<bool, Maxwell::NumClipDistances> clip_distances{}; | ||||||
|     u64 local_memory_size; |     u64 local_memory_size; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| @ -997,7 +1004,8 @@ public: | |||||||
| 
 | 
 | ||||||
|     /// Returns entries in the shader that are useful for external functions
 |     /// Returns entries in the shader that are useful for external functions
 | ||||||
|     ShaderEntries GetEntries() const { |     ShaderEntries GetEntries() const { | ||||||
|         return {regs.GetConstBuffersDeclarations(), regs.GetSamplers(), shader_length}; |         return {regs.GetConstBuffersDeclarations(), regs.GetSamplers(), regs.GetClipDistances(), | ||||||
|  |                 shader_length}; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|  | |||||||
| @ -163,6 +163,7 @@ private: | |||||||
| struct ShaderEntries { | struct ShaderEntries { | ||||||
|     std::vector<ConstBufferEntry> const_buffer_entries; |     std::vector<ConstBufferEntry> const_buffer_entries; | ||||||
|     std::vector<SamplerEntry> texture_samplers; |     std::vector<SamplerEntry> texture_samplers; | ||||||
|  |     std::array<bool, Tegra::Engines::Maxwell3D::Regs::NumClipDistances> clip_distances; | ||||||
|     std::size_t shader_length; |     std::size_t shader_length; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user