mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	gl_rasterizer: Use buffer_storage for uniform data.
This replaces the glBufferData logic with the shared stream buffer code. The new code doesn't need a temporary staging buffer any more, so the performance should imrpove quite a bit.
This commit is contained in:
		
							parent
							
								
									7bffd7c1b0
								
							
						
					
					
						commit
						5960282303
					
				
					 2 changed files with 34 additions and 13 deletions
				
			
		|  | @ -31,7 +31,8 @@ MICROPROFILE_DEFINE(OpenGL_Blits, "OpenGL", "Blits", MP_RGB(100, 100, 255)); | ||||||
| MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100)); | MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100)); | ||||||
| 
 | 
 | ||||||
| RasterizerOpenGL::RasterizerOpenGL() | RasterizerOpenGL::RasterizerOpenGL() | ||||||
|     : shader_dirty(true), vertex_buffer(GL_ARRAY_BUFFER, VERTEX_BUFFER_SIZE) { |     : shader_dirty(true), vertex_buffer(GL_ARRAY_BUFFER, VERTEX_BUFFER_SIZE), | ||||||
|  |       uniform_buffer(GL_UNIFORM_BUFFER, UNIFORM_BUFFER_SIZE) { | ||||||
|     // Clipping plane 0 is always enabled for PICA fixed clip plane z <= 0
 |     // Clipping plane 0 is always enabled for PICA fixed clip plane z <= 0
 | ||||||
|     state.clip_distance[0] = true; |     state.clip_distance[0] = true; | ||||||
| 
 | 
 | ||||||
|  | @ -48,16 +49,12 @@ RasterizerOpenGL::RasterizerOpenGL() | ||||||
| 
 | 
 | ||||||
|     // Generate VBO, VAO and UBO
 |     // Generate VBO, VAO and UBO
 | ||||||
|     vertex_array.Create(); |     vertex_array.Create(); | ||||||
|     uniform_buffer.Create(); |  | ||||||
| 
 | 
 | ||||||
|     state.draw.vertex_array = vertex_array.handle; |     state.draw.vertex_array = vertex_array.handle; | ||||||
|     state.draw.vertex_buffer = vertex_buffer.GetHandle(); |     state.draw.vertex_buffer = vertex_buffer.GetHandle(); | ||||||
|     state.draw.uniform_buffer = uniform_buffer.handle; |     state.draw.uniform_buffer = uniform_buffer.GetHandle(); | ||||||
|     state.Apply(); |     state.Apply(); | ||||||
| 
 | 
 | ||||||
|     // Bind the UBO to binding point 0
 |  | ||||||
|     glBindBufferBase(GL_UNIFORM_BUFFER, 0, uniform_buffer.handle); |  | ||||||
| 
 |  | ||||||
|     uniform_block_data.dirty = true; |     uniform_block_data.dirty = true; | ||||||
| 
 | 
 | ||||||
|     uniform_block_data.lut_dirty.fill(true); |     uniform_block_data.lut_dirty.fill(true); | ||||||
|  | @ -70,6 +67,10 @@ RasterizerOpenGL::RasterizerOpenGL() | ||||||
|     uniform_block_data.proctex_lut_dirty = true; |     uniform_block_data.proctex_lut_dirty = true; | ||||||
|     uniform_block_data.proctex_diff_lut_dirty = true; |     uniform_block_data.proctex_diff_lut_dirty = true; | ||||||
| 
 | 
 | ||||||
|  |     glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &uniform_buffer_alignment); | ||||||
|  |     uniform_size_aligned_fs = | ||||||
|  |         Common::AlignUp<size_t>(sizeof(UniformData), uniform_buffer_alignment); | ||||||
|  | 
 | ||||||
|     // Set vertex attributes
 |     // Set vertex attributes
 | ||||||
|     glVertexAttribPointer(GLShader::ATTRIBUTE_POSITION, 4, GL_FLOAT, GL_FALSE, |     glVertexAttribPointer(GLShader::ATTRIBUTE_POSITION, 4, GL_FLOAT, GL_FALSE, | ||||||
|                           sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, position)); |                           sizeof(HardwareVertex), (GLvoid*)offsetof(HardwareVertex, position)); | ||||||
|  | @ -475,11 +476,7 @@ void RasterizerOpenGL::DrawTriangles() { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Sync the uniform data
 |     // Sync the uniform data
 | ||||||
|     if (uniform_block_data.dirty) { |     UploadUniforms(); | ||||||
|         glBufferData(GL_UNIFORM_BUFFER, sizeof(UniformData), &uniform_block_data.data, |  | ||||||
|                      GL_STATIC_DRAW); |  | ||||||
|         uniform_block_data.dirty = false; |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     // Viewport can have negative offsets or larger
 |     // Viewport can have negative offsets or larger
 | ||||||
|     // dimensions than our framebuffer sub-rect.
 |     // dimensions than our framebuffer sub-rect.
 | ||||||
|  | @ -1652,3 +1649,19 @@ void RasterizerOpenGL::SyncLightDistanceAttenuationScale(int light_index) { | ||||||
|         uniform_block_data.dirty = true; |         uniform_block_data.dirty = true; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | void RasterizerOpenGL::UploadUniforms() { | ||||||
|  |     if (!uniform_block_data.dirty) | ||||||
|  |         return; | ||||||
|  | 
 | ||||||
|  |     size_t uniform_size = uniform_size_aligned_fs; | ||||||
|  |     u8* uniforms; | ||||||
|  |     GLintptr offset; | ||||||
|  |     std::tie(uniforms, offset, std::ignore) = | ||||||
|  |         uniform_buffer.Map(uniform_size, uniform_buffer_alignment); | ||||||
|  |     std::memcpy(uniforms, &uniform_block_data.data, sizeof(UniformData)); | ||||||
|  |     uniform_buffer.Unmap(uniform_size); | ||||||
|  |     glBindBufferRange(GL_UNIFORM_BUFFER, 0, uniform_buffer.GetHandle(), offset, | ||||||
|  |                       sizeof(UniformData)); | ||||||
|  |     uniform_block_data.dirty = false; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -215,6 +215,9 @@ private: | ||||||
|     /// Syncs the specified light's distance attenuation scale to match the PICA register
 |     /// Syncs the specified light's distance attenuation scale to match the PICA register
 | ||||||
|     void SyncLightDistanceAttenuationScale(int light_index); |     void SyncLightDistanceAttenuationScale(int light_index); | ||||||
| 
 | 
 | ||||||
|  |     /// Upload the uniform blocks to the uniform buffer object
 | ||||||
|  |     void UploadUniforms(); | ||||||
|  | 
 | ||||||
|     OpenGLState state; |     OpenGLState state; | ||||||
| 
 | 
 | ||||||
|     RasterizerCacheOpenGL res_cache; |     RasterizerCacheOpenGL res_cache; | ||||||
|  | @ -237,12 +240,17 @@ private: | ||||||
| 
 | 
 | ||||||
|     std::unique_ptr<ShaderProgramManager> shader_program_manager; |     std::unique_ptr<ShaderProgramManager> shader_program_manager; | ||||||
| 
 | 
 | ||||||
|  |     // They shall be big enough for about one frame.
 | ||||||
|  |     static constexpr size_t VERTEX_BUFFER_SIZE = 32 * 1024 * 1024; | ||||||
|  |     static constexpr size_t UNIFORM_BUFFER_SIZE = 2 * 1024 * 1024; | ||||||
|  | 
 | ||||||
|     std::array<SamplerInfo, 3> texture_samplers; |     std::array<SamplerInfo, 3> texture_samplers; | ||||||
|     OGLVertexArray vertex_array; |     OGLVertexArray vertex_array; | ||||||
|     static constexpr size_t VERTEX_BUFFER_SIZE = 32 * 1024 * 1024; |  | ||||||
|     OGLStreamBuffer vertex_buffer; |     OGLStreamBuffer vertex_buffer; | ||||||
|     OGLBuffer uniform_buffer; |     OGLStreamBuffer uniform_buffer; | ||||||
|     OGLFramebuffer framebuffer; |     OGLFramebuffer framebuffer; | ||||||
|  |     GLint uniform_buffer_alignment; | ||||||
|  |     size_t uniform_size_aligned_fs; | ||||||
| 
 | 
 | ||||||
|     // TODO (wwylele): consider caching texture cube in the rasterizer cache
 |     // TODO (wwylele): consider caching texture cube in the rasterizer cache
 | ||||||
|     OGLTexture texture_cube; |     OGLTexture texture_cube; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue