mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	OpenGL Cache: Add surface utility functions
Separates creating and filling surfaces into static functions that can be reused from the different RasterizerCache methods.
This commit is contained in:
		
							parent
							
								
									e9e2d444ef
								
							
						
					
					
						commit
						0b98b768f5
					
				
					 1 changed files with 46 additions and 41 deletions
				
			
		|  | @ -25,6 +25,11 @@ | ||||||
| #include "video_core/utils.h" | #include "video_core/utils.h" | ||||||
| #include "video_core/video_core.h" | #include "video_core/video_core.h" | ||||||
| 
 | 
 | ||||||
|  | using SurfaceType = SurfaceParams::SurfaceType; | ||||||
|  | using PixelFormat = SurfaceParams::PixelFormat; | ||||||
|  | 
 | ||||||
|  | static std::array<OGLFramebuffer, 2> transfer_framebuffers; | ||||||
|  | 
 | ||||||
| struct FormatTuple { | struct FormatTuple { | ||||||
|     GLint internal_format; |     GLint internal_format; | ||||||
|     GLenum format; |     GLenum format; | ||||||
|  | @ -46,6 +51,27 @@ static const std::array<FormatTuple, 4> depth_format_tuples = {{ | ||||||
|     {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, // D24S8
 |     {GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, // D24S8
 | ||||||
| }}; | }}; | ||||||
| 
 | 
 | ||||||
|  | static constexpr FormatTuple tex_tuple = {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE}; | ||||||
|  | 
 | ||||||
|  | static const FormatTuple& GetFormatTuple(PixelFormat pixel_format) { | ||||||
|  |     const SurfaceType type = SurfaceParams::GetFormatType(pixel_format); | ||||||
|  |     if (type == SurfaceType::Color) { | ||||||
|  |         ASSERT((size_t)pixel_format < fb_format_tuples.size()); | ||||||
|  |         return fb_format_tuples[(unsigned int)pixel_format]; | ||||||
|  |     } else if (type == SurfaceType::Depth || type == SurfaceType::DepthStencil) { | ||||||
|  |         size_t tuple_idx = (size_t)pixel_format - 14; | ||||||
|  |         ASSERT(tuple_idx < depth_format_tuples.size()); | ||||||
|  |         return depth_format_tuples[tuple_idx]; | ||||||
|  |     } else { | ||||||
|  |         return tex_tuple; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | template <typename Map, typename Interval> | ||||||
|  | constexpr auto RangeFromInterval(Map& map, const Interval& interval) { | ||||||
|  |     return boost::make_iterator_range(map.equal_range(interval)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static bool FillSurface(const Surface& surface, const u8* fill_data, | static bool FillSurface(const Surface& surface, const u8* fill_data, | ||||||
|                         const MathUtil::Rectangle<u32>& fill_rect) { |                         const MathUtil::Rectangle<u32>& fill_rect) { | ||||||
|     OpenGLState state = OpenGLState::GetCurState(); |     OpenGLState state = OpenGLState::GetCurState(); | ||||||
|  | @ -53,11 +79,11 @@ static bool FillSurface(const Surface& surface, const u8* fill_data, | ||||||
|     OpenGLState prev_state = state; |     OpenGLState prev_state = state; | ||||||
|     SCOPE_EXIT({ prev_state.Apply(); }); |     SCOPE_EXIT({ prev_state.Apply(); }); | ||||||
| 
 | 
 | ||||||
|     OpenGLState::ResetTexture(surface->texture.handle); |     state.ResetTexture(surface->texture.handle); | ||||||
| 
 | 
 | ||||||
|     state.scissor.enabled = true; |     state.scissor.enabled = true; | ||||||
|     state.scissor.x = static_cast<GLint>(fill_rect.left); |     state.scissor.x = static_cast<GLint>(fill_rect.left); | ||||||
|     state.scissor.y = static_cast<GLint>(std::min(fill_rect.top, fill_rect.bottom)); |     state.scissor.y = static_cast<GLint>(fill_rect.bottom); | ||||||
|     state.scissor.width = static_cast<GLsizei>(fill_rect.GetWidth()); |     state.scissor.width = static_cast<GLsizei>(fill_rect.GetWidth()); | ||||||
|     state.scissor.height = static_cast<GLsizei>(fill_rect.GetHeight()); |     state.scissor.height = static_cast<GLsizei>(fill_rect.GetHeight()); | ||||||
| 
 | 
 | ||||||
|  | @ -256,24 +282,22 @@ static constexpr std::array<void (*)(u32, u32, u8*, PAddr, PAddr, PAddr), 18> gl | ||||||
|     MortonCopy<false, PixelFormat::D24S8> // 17
 |     MortonCopy<false, PixelFormat::D24S8> // 17
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| void RasterizerCacheOpenGL::BlitTextures(GLuint src_tex, GLuint dst_tex, | static bool BlitTextures(GLuint src_tex, const MathUtil::Rectangle<u32>& src_rect, GLuint dst_tex, | ||||||
|                                          CachedSurface::SurfaceType type, |                          const MathUtil::Rectangle<u32>& dst_rect, SurfaceType type) { | ||||||
|                                          const MathUtil::Rectangle<int>& src_rect, |     OpenGLState state = OpenGLState::GetCurState(); | ||||||
|                                          const MathUtil::Rectangle<int>& dst_rect) { |  | ||||||
|     using SurfaceType = CachedSurface::SurfaceType; |  | ||||||
| 
 | 
 | ||||||
|     OpenGLState cur_state = OpenGLState::GetCurState(); |     OpenGLState prev_state = state; | ||||||
|  |     SCOPE_EXIT({ prev_state.Apply(); }); | ||||||
| 
 | 
 | ||||||
|     // Make sure textures aren't bound to texture units, since going to bind them to framebuffer
 |     // Make sure textures aren't bound to texture units, since going to bind them to framebuffer
 | ||||||
|     // components
 |     // components
 | ||||||
|     OpenGLState::ResetTexture(src_tex); |     state.ResetTexture(src_tex); | ||||||
|     OpenGLState::ResetTexture(dst_tex); |     state.ResetTexture(dst_tex); | ||||||
| 
 | 
 | ||||||
|     // Keep track of previous framebuffer bindings
 |     // Keep track of previous framebuffer bindings
 | ||||||
|     GLuint old_fbs[2] = {cur_state.draw.read_framebuffer, cur_state.draw.draw_framebuffer}; |     state.draw.read_framebuffer = transfer_framebuffers[0].handle; | ||||||
|     cur_state.draw.read_framebuffer = transfer_framebuffers[0].handle; |     state.draw.draw_framebuffer = transfer_framebuffers[1].handle; | ||||||
|     cur_state.draw.draw_framebuffer = transfer_framebuffers[1].handle; |     state.Apply(); | ||||||
|     cur_state.Apply(); |  | ||||||
| 
 | 
 | ||||||
|     u32 buffers = 0; |     u32 buffers = 0; | ||||||
| 
 | 
 | ||||||
|  | @ -311,14 +335,11 @@ void RasterizerCacheOpenGL::BlitTextures(GLuint src_tex, GLuint dst_tex, | ||||||
|         buffers = GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; |         buffers = GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     glBlitFramebuffer(src_rect.left, src_rect.top, src_rect.right, src_rect.bottom, dst_rect.left, |     glBlitFramebuffer(src_rect.left, src_rect.bottom, src_rect.right, src_rect.top, dst_rect.left, | ||||||
|                       dst_rect.top, dst_rect.right, dst_rect.bottom, buffers, |                       dst_rect.bottom, dst_rect.right, dst_rect.top, buffers, | ||||||
|                       buffers == GL_COLOR_BUFFER_BIT ? GL_LINEAR : GL_NEAREST); |                       buffers == GL_COLOR_BUFFER_BIT ? GL_LINEAR : GL_NEAREST); | ||||||
| 
 | 
 | ||||||
|     // Restore previous framebuffer bindings
 |     return true; | ||||||
|     cur_state.draw.read_framebuffer = old_fbs[0]; |  | ||||||
|     cur_state.draw.draw_framebuffer = old_fbs[1]; |  | ||||||
|     cur_state.Apply(); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool RasterizerCacheOpenGL::TryBlitSurfaces(CachedSurface* src_surface, | bool RasterizerCacheOpenGL::TryBlitSurfaces(CachedSurface* src_surface, | ||||||
|  | @ -336,11 +357,9 @@ bool RasterizerCacheOpenGL::TryBlitSurfaces(CachedSurface* src_surface, | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void AllocateSurfaceTexture(GLuint texture, CachedSurface::PixelFormat pixel_format, | // Allocate an uninitialized texture of appropriate size and format for the surface
 | ||||||
|                                    u32 width, u32 height) { | static void AllocateSurfaceTexture(GLuint texture, const FormatTuple& format_tuple, u32 width, | ||||||
|     // Allocate an uninitialized texture of appropriate size and format for the surface
 |                                    u32 height) { | ||||||
|     using SurfaceType = CachedSurface::SurfaceType; |  | ||||||
| 
 |  | ||||||
|     OpenGLState cur_state = OpenGLState::GetCurState(); |     OpenGLState cur_state = OpenGLState::GetCurState(); | ||||||
| 
 | 
 | ||||||
|     // Keep track of previous texture bindings
 |     // Keep track of previous texture bindings
 | ||||||
|  | @ -349,22 +368,8 @@ static void AllocateSurfaceTexture(GLuint texture, CachedSurface::PixelFormat pi | ||||||
|     cur_state.Apply(); |     cur_state.Apply(); | ||||||
|     glActiveTexture(GL_TEXTURE0); |     glActiveTexture(GL_TEXTURE0); | ||||||
| 
 | 
 | ||||||
|     SurfaceType type = CachedSurface::GetFormatType(pixel_format); |     glTexImage2D(GL_TEXTURE_2D, 0, format_tuple.internal_format, width, height, 0, | ||||||
| 
 |                  format_tuple.format, format_tuple.type, nullptr); | ||||||
|     FormatTuple tuple; |  | ||||||
|     if (type == SurfaceType::Color) { |  | ||||||
|         ASSERT((size_t)pixel_format < fb_format_tuples.size()); |  | ||||||
|         tuple = fb_format_tuples[(unsigned int)pixel_format]; |  | ||||||
|     } else if (type == SurfaceType::Depth || type == SurfaceType::DepthStencil) { |  | ||||||
|         size_t tuple_idx = (size_t)pixel_format - 14; |  | ||||||
|         ASSERT(tuple_idx < depth_format_tuples.size()); |  | ||||||
|         tuple = depth_format_tuples[tuple_idx]; |  | ||||||
|     } else { |  | ||||||
|         tuple = {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE}; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     glTexImage2D(GL_TEXTURE_2D, 0, tuple.internal_format, width, height, 0, tuple.format, |  | ||||||
|                  tuple.type, nullptr); |  | ||||||
| 
 | 
 | ||||||
|     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); |     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); | ||||||
|     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue