mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-10-30 15:39:02 -05:00 
			
		
		
		
	gl_rasterizer_cache: Keep track of surface 2D size separately from total size.
This commit is contained in:
		| @@ -71,7 +71,8 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) { | |||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     params.size_in_bytes = params.SizeInBytes(); |     params.size_in_bytes_total = params.SizeInBytesTotal(); | ||||||
|  |     params.size_in_bytes_2d = params.SizeInBytes2D(); | ||||||
|     return params; |     return params; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -89,7 +90,8 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) { | |||||||
|     params.unaligned_height = config.height; |     params.unaligned_height = config.height; | ||||||
|     params.target = SurfaceTarget::Texture2D; |     params.target = SurfaceTarget::Texture2D; | ||||||
|     params.depth = 1; |     params.depth = 1; | ||||||
|     params.size_in_bytes = params.SizeInBytes(); |     params.size_in_bytes_total = params.SizeInBytesTotal(); | ||||||
|  |     params.size_in_bytes_2d = params.SizeInBytes2D(); | ||||||
|     return params; |     return params; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -108,7 +110,8 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) { | |||||||
|     params.unaligned_height = zeta_height; |     params.unaligned_height = zeta_height; | ||||||
|     params.target = SurfaceTarget::Texture2D; |     params.target = SurfaceTarget::Texture2D; | ||||||
|     params.depth = 1; |     params.depth = 1; | ||||||
|     params.size_in_bytes = params.SizeInBytes(); |     params.size_in_bytes_total = params.SizeInBytesTotal(); | ||||||
|  |     params.size_in_bytes_2d = params.SizeInBytes2D(); | ||||||
|     return params; |     return params; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -585,10 +588,13 @@ void CachedSurface::LoadGLBuffer() { | |||||||
|  |  | ||||||
|     const u32 bytes_per_pixel = GetGLBytesPerPixel(params.pixel_format); |     const u32 bytes_per_pixel = GetGLBytesPerPixel(params.pixel_format); | ||||||
|     const u32 copy_size = params.width * params.height * bytes_per_pixel; |     const u32 copy_size = params.width * params.height * bytes_per_pixel; | ||||||
|  |     const std::size_t total_size = copy_size * params.depth; | ||||||
|  |  | ||||||
|     MICROPROFILE_SCOPE(OpenGL_SurfaceLoad); |     MICROPROFILE_SCOPE(OpenGL_SurfaceLoad); | ||||||
|  |  | ||||||
|     if (params.is_tiled) { |     if (params.is_tiled) { | ||||||
|  |         gl_buffer.resize(total_size); | ||||||
|  |  | ||||||
|         // TODO(bunnei): This only unswizzles and copies a 2D texture - we do not yet know how to do |         // TODO(bunnei): This only unswizzles and copies a 2D texture - we do not yet know how to do | ||||||
|         // this for 3D textures, etc. |         // this for 3D textures, etc. | ||||||
|         switch (params.target) { |         switch (params.target) { | ||||||
| @@ -601,13 +607,11 @@ void CachedSurface::LoadGLBuffer() { | |||||||
|             UNREACHABLE(); |             UNREACHABLE(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         gl_buffer.resize(static_cast<std::size_t>(params.depth) * copy_size); |  | ||||||
|         morton_to_gl_fns[static_cast<std::size_t>(params.pixel_format)]( |         morton_to_gl_fns[static_cast<std::size_t>(params.pixel_format)]( | ||||||
|             params.width, params.block_height, params.height, gl_buffer.data(), copy_size, |             params.width, params.block_height, params.height, gl_buffer.data(), copy_size, | ||||||
|             params.addr); |             params.addr); | ||||||
|     } else { |     } else { | ||||||
|         const u8* const texture_src_data_end{texture_src_data + |         const u8* const texture_src_data_end{texture_src_data + total_size}; | ||||||
|                                              (static_cast<std::size_t>(params.depth) * copy_size)}; |  | ||||||
|         gl_buffer.assign(texture_src_data, texture_src_data_end); |         gl_buffer.assign(texture_src_data, texture_src_data_end); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -663,15 +667,15 @@ void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle | |||||||
|             glCompressedTexImage2D( |             glCompressedTexImage2D( | ||||||
|                 SurfaceTargetToGL(params.target), 0, tuple.internal_format, |                 SurfaceTargetToGL(params.target), 0, tuple.internal_format, | ||||||
|                 static_cast<GLsizei>(params.width), static_cast<GLsizei>(params.height), 0, |                 static_cast<GLsizei>(params.width), static_cast<GLsizei>(params.height), 0, | ||||||
|                 static_cast<GLsizei>(params.size_in_bytes), &gl_buffer[buffer_offset]); |                 static_cast<GLsizei>(params.size_in_bytes_2d), &gl_buffer[buffer_offset]); | ||||||
|             break; |             break; | ||||||
|         case SurfaceParams::SurfaceTarget::Texture3D: |         case SurfaceParams::SurfaceTarget::Texture3D: | ||||||
|         case SurfaceParams::SurfaceTarget::Texture2DArray: |         case SurfaceParams::SurfaceTarget::Texture2DArray: | ||||||
|             glCompressedTexImage3D( |             glCompressedTexImage3D( | ||||||
|                 SurfaceTargetToGL(params.target), 0, tuple.internal_format, |                 SurfaceTargetToGL(params.target), 0, tuple.internal_format, | ||||||
|                 static_cast<GLsizei>(params.width), static_cast<GLsizei>(params.height), |                 static_cast<GLsizei>(params.width), static_cast<GLsizei>(params.height), | ||||||
|                 static_cast<GLsizei>(params.depth), 0, static_cast<GLsizei>(params.size_in_bytes), |                 static_cast<GLsizei>(params.depth), 0, | ||||||
|                 &gl_buffer[buffer_offset]); |                 static_cast<GLsizei>(params.size_in_bytes_total), &gl_buffer[buffer_offset]); | ||||||
|             break; |             break; | ||||||
|         default: |         default: | ||||||
|             LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}", |             LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}", | ||||||
| @@ -679,8 +683,8 @@ void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle | |||||||
|             UNREACHABLE(); |             UNREACHABLE(); | ||||||
|             glCompressedTexImage2D( |             glCompressedTexImage2D( | ||||||
|                 GL_TEXTURE_2D, 0, tuple.internal_format, static_cast<GLsizei>(params.width), |                 GL_TEXTURE_2D, 0, tuple.internal_format, static_cast<GLsizei>(params.width), | ||||||
|                 static_cast<GLsizei>(params.height), 0, static_cast<GLsizei>(params.size_in_bytes), |                 static_cast<GLsizei>(params.height), 0, | ||||||
|                 &gl_buffer[buffer_offset]); |                 static_cast<GLsizei>(params.size_in_bytes_2d), &gl_buffer[buffer_offset]); | ||||||
|         } |         } | ||||||
|     } else { |     } else { | ||||||
|  |  | ||||||
| @@ -811,15 +815,15 @@ Surface RasterizerCacheOpenGL::GetUncachedSurface(const SurfaceParams& params) { | |||||||
|     return surface; |     return surface; | ||||||
| } | } | ||||||
|  |  | ||||||
| Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& surface, | Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& old_surface, | ||||||
|                                                const SurfaceParams& new_params) { |                                                const SurfaceParams& new_params) { | ||||||
|     // Verify surface is compatible for blitting |     // Verify surface is compatible for blitting | ||||||
|     const auto& params{surface->GetSurfaceParams()}; |     const auto& old_params{old_surface->GetSurfaceParams()}; | ||||||
|  |  | ||||||
|     // Get a new surface with the new parameters, and blit the previous surface to it |     // Get a new surface with the new parameters, and blit the previous surface to it | ||||||
|     Surface new_surface{GetUncachedSurface(new_params)}; |     Surface new_surface{GetUncachedSurface(new_params)}; | ||||||
|  |  | ||||||
|     if (params.pixel_format == new_params.pixel_format || |     if (old_params.pixel_format == new_params.pixel_format || | ||||||
|         !Settings::values.use_accurate_framebuffers) { |         !Settings::values.use_accurate_framebuffers) { | ||||||
|         // If the format is the same, just do a framebuffer blit. This is significantly faster than |         // If the format is the same, just do a framebuffer blit. This is significantly faster than | ||||||
|         // using PBOs. The is also likely less accurate, as textures will be converted rather than |         // using PBOs. The is also likely less accurate, as textures will be converted rather than | ||||||
| @@ -833,24 +837,26 @@ Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& surface, | |||||||
|         // where pixels are reinterpreted as a new format (without conversion). This code path uses |         // where pixels are reinterpreted as a new format (without conversion). This code path uses | ||||||
|         // OpenGL PBOs and is quite slow. |         // OpenGL PBOs and is quite slow. | ||||||
|  |  | ||||||
|         auto source_format = GetFormatTuple(params.pixel_format, params.component_type); |         auto source_format = GetFormatTuple(old_params.pixel_format, old_params.component_type); | ||||||
|         auto dest_format = GetFormatTuple(new_params.pixel_format, new_params.component_type); |         auto dest_format = GetFormatTuple(new_params.pixel_format, new_params.component_type); | ||||||
|  |  | ||||||
|         std::size_t buffer_size = std::max(params.SizeInBytes(), new_params.SizeInBytes()); |         std::size_t buffer_size = | ||||||
|  |             std::max(old_params.size_in_bytes_total, new_params.size_in_bytes_total); | ||||||
|  |  | ||||||
|         glBindBuffer(GL_PIXEL_PACK_BUFFER, copy_pbo.handle); |         glBindBuffer(GL_PIXEL_PACK_BUFFER, copy_pbo.handle); | ||||||
|         glBufferData(GL_PIXEL_PACK_BUFFER, buffer_size, nullptr, GL_STREAM_DRAW_ARB); |         glBufferData(GL_PIXEL_PACK_BUFFER, buffer_size, nullptr, GL_STREAM_DRAW_ARB); | ||||||
|         if (source_format.compressed) { |         if (source_format.compressed) { | ||||||
|             glGetCompressedTextureImage(surface->Texture().handle, 0, |             glGetCompressedTextureImage(old_surface->Texture().handle, 0, | ||||||
|                                         static_cast<GLsizei>(params.SizeInBytes()), nullptr); |                                         static_cast<GLsizei>(old_params.size_in_bytes_total), | ||||||
|  |                                         nullptr); | ||||||
|         } else { |         } else { | ||||||
|             glGetTextureImage(surface->Texture().handle, 0, source_format.format, |             glGetTextureImage(old_surface->Texture().handle, 0, source_format.format, | ||||||
|                               source_format.type, static_cast<GLsizei>(params.SizeInBytes()), |                               source_format.type, | ||||||
|                               nullptr); |                               static_cast<GLsizei>(old_params.size_in_bytes_total), nullptr); | ||||||
|         } |         } | ||||||
|         // If the new texture is bigger than the previous one, we need to fill in the rest with data |         // If the new texture is bigger than the previous one, we need to fill in the rest with data | ||||||
|         // from the CPU. |         // from the CPU. | ||||||
|         if (params.SizeInBytes() < new_params.SizeInBytes()) { |         if (old_params.size_in_bytes_total < new_params.size_in_bytes_total) { | ||||||
|             // Upload the rest of the memory. |             // Upload the rest of the memory. | ||||||
|             if (new_params.is_tiled) { |             if (new_params.is_tiled) { | ||||||
|                 // TODO(Subv): We might have to de-tile the subtexture and re-tile it with the rest |                 // TODO(Subv): We might have to de-tile the subtexture and re-tile it with the rest | ||||||
| @@ -860,10 +866,12 @@ Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& surface, | |||||||
|                 LOG_DEBUG(HW_GPU, "Trying to upload extra texture data from the CPU during " |                 LOG_DEBUG(HW_GPU, "Trying to upload extra texture data from the CPU during " | ||||||
|                                   "reinterpretation but the texture is tiled."); |                                   "reinterpretation but the texture is tiled."); | ||||||
|             } |             } | ||||||
|             std::size_t remaining_size = new_params.SizeInBytes() - params.SizeInBytes(); |             std::size_t remaining_size = | ||||||
|  |                 new_params.size_in_bytes_total - old_params.size_in_bytes_total; | ||||||
|             std::vector<u8> data(remaining_size); |             std::vector<u8> data(remaining_size); | ||||||
|             Memory::ReadBlock(new_params.addr + params.SizeInBytes(), data.data(), data.size()); |             Memory::ReadBlock(new_params.addr + old_params.size_in_bytes_total, data.data(), | ||||||
|             glBufferSubData(GL_PIXEL_PACK_BUFFER, params.SizeInBytes(), remaining_size, |                               data.size()); | ||||||
|  |             glBufferSubData(GL_PIXEL_PACK_BUFFER, old_params.size_in_bytes_total, remaining_size, | ||||||
|                             data.data()); |                             data.data()); | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -898,7 +906,7 @@ Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& surface, | |||||||
|                 break; |                 break; | ||||||
|             default: |             default: | ||||||
|                 LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}", |                 LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}", | ||||||
|                              static_cast<u32>(params.target)); |                              static_cast<u32>(new_params.target)); | ||||||
|                 UNREACHABLE(); |                 UNREACHABLE(); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -689,13 +689,18 @@ struct SurfaceParams { | |||||||
|     /// Returns the rectangle corresponding to this surface |     /// Returns the rectangle corresponding to this surface | ||||||
|     MathUtil::Rectangle<u32> GetRect() const; |     MathUtil::Rectangle<u32> GetRect() const; | ||||||
|  |  | ||||||
|     /// Returns the size of this surface in bytes, adjusted for compression |     /// Returns the size of this surface as a 2D texture in bytes, adjusted for compression | ||||||
|     std::size_t SizeInBytes() const { |     std::size_t SizeInBytes2D() const { | ||||||
|         const u32 compression_factor{GetCompressionFactor(pixel_format)}; |         const u32 compression_factor{GetCompressionFactor(pixel_format)}; | ||||||
|         ASSERT(width % compression_factor == 0); |         ASSERT(width % compression_factor == 0); | ||||||
|         ASSERT(height % compression_factor == 0); |         ASSERT(height % compression_factor == 0); | ||||||
|         return (width / compression_factor) * (height / compression_factor) * |         return (width / compression_factor) * (height / compression_factor) * | ||||||
|                GetFormatBpp(pixel_format) * depth / CHAR_BIT; |                GetFormatBpp(pixel_format) / CHAR_BIT; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// Returns the total size of this surface in bytes, adjusted for compression | ||||||
|  |     std::size_t SizeInBytesTotal() const { | ||||||
|  |         return SizeInBytes2D() * depth; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// Creates SurfaceParams from a texture configuration |     /// Creates SurfaceParams from a texture configuration | ||||||
| @@ -725,7 +730,8 @@ struct SurfaceParams { | |||||||
|     u32 height; |     u32 height; | ||||||
|     u32 depth; |     u32 depth; | ||||||
|     u32 unaligned_height; |     u32 unaligned_height; | ||||||
|     std::size_t size_in_bytes; |     std::size_t size_in_bytes_total; | ||||||
|  |     std::size_t size_in_bytes_2d; | ||||||
|     SurfaceTarget target; |     SurfaceTarget target; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -759,7 +765,7 @@ public: | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     std::size_t GetSizeInBytes() const { |     std::size_t GetSizeInBytes() const { | ||||||
|         return params.size_in_bytes; |         return params.size_in_bytes_total; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     const OGLTexture& Texture() const { |     const OGLTexture& Texture() const { | ||||||
| @@ -822,7 +828,7 @@ private: | |||||||
|     Surface GetUncachedSurface(const SurfaceParams& params); |     Surface GetUncachedSurface(const SurfaceParams& params); | ||||||
|  |  | ||||||
|     /// Recreates a surface with new parameters |     /// Recreates a surface with new parameters | ||||||
|     Surface RecreateSurface(const Surface& surface, const SurfaceParams& new_params); |     Surface RecreateSurface(const Surface& old_surface, const SurfaceParams& new_params); | ||||||
|  |  | ||||||
|     /// Reserves a unique surface that can be reused later |     /// Reserves a unique surface that can be reused later | ||||||
|     void ReserveSurface(const Surface& surface); |     void ReserveSurface(const Surface& surface); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 bunnei
					bunnei