diff options
| author | 2018-10-13 02:08:04 -0400 | |
|---|---|---|
| committer | 2018-10-16 11:31:01 -0400 | |
| commit | 5f79ba04bd617254f47e1d707479ab2468f8aaf9 (patch) | |
| tree | 92f47d0627c29bbb750b3b75da5fd51d687a7bbd /src | |
| parent | gl_rasterizer_cache: Rename GetGLBytesPerPixel to GetBytesPerPixel. (diff) | |
| download | yuzu-5f79ba04bd617254f47e1d707479ab2468f8aaf9.tar.gz yuzu-5f79ba04bd617254f47e1d707479ab2468f8aaf9.tar.xz yuzu-5f79ba04bd617254f47e1d707479ab2468f8aaf9.zip | |
gl_rasterizer_cache: Separate guest and host surface size managment.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 148 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 38 |
2 files changed, 94 insertions, 92 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index c2cd67f02..4ba34ebc4 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | |||
| @@ -34,23 +34,56 @@ struct FormatTuple { | |||
| 34 | bool compressed; | 34 | bool compressed; |
| 35 | }; | 35 | }; |
| 36 | 36 | ||
| 37 | static bool IsPixelFormatASTC(PixelFormat format) { | ||
| 38 | switch (format) { | ||
| 39 | case PixelFormat::ASTC_2D_4X4: | ||
| 40 | case PixelFormat::ASTC_2D_5X4: | ||
| 41 | case PixelFormat::ASTC_2D_8X8: | ||
| 42 | case PixelFormat::ASTC_2D_8X5: | ||
| 43 | return true; | ||
| 44 | default: | ||
| 45 | return false; | ||
| 46 | } | ||
| 47 | } | ||
| 48 | |||
| 49 | static std::pair<u32, u32> GetASTCBlockSize(PixelFormat format) { | ||
| 50 | switch (format) { | ||
| 51 | case PixelFormat::ASTC_2D_4X4: | ||
| 52 | return {4, 4}; | ||
| 53 | case PixelFormat::ASTC_2D_5X4: | ||
| 54 | return {5, 4}; | ||
| 55 | case PixelFormat::ASTC_2D_8X8: | ||
| 56 | return {8, 8}; | ||
| 57 | case PixelFormat::ASTC_2D_8X5: | ||
| 58 | return {8, 5}; | ||
| 59 | default: | ||
| 60 | LOG_CRITICAL(HW_GPU, "Unhandled format: {}", static_cast<u32>(format)); | ||
| 61 | UNREACHABLE(); | ||
| 62 | } | ||
| 63 | } | ||
| 64 | |||
| 37 | void SurfaceParams::InitCacheParameters(Tegra::GPUVAddr gpu_addr) { | 65 | void SurfaceParams::InitCacheParameters(Tegra::GPUVAddr gpu_addr) { |
| 38 | auto& memory_manager{Core::System::GetInstance().GPU().MemoryManager()}; | 66 | auto& memory_manager{Core::System::GetInstance().GPU().MemoryManager()}; |
| 39 | const auto cpu_addr{memory_manager.GpuToCpuAddress(gpu_addr)}; | 67 | const auto cpu_addr{memory_manager.GpuToCpuAddress(gpu_addr)}; |
| 40 | const auto max_size{memory_manager.GetRegionEnd(gpu_addr) - gpu_addr}; | 68 | const auto max_size{memory_manager.GetRegionEnd(gpu_addr) - gpu_addr}; |
| 41 | 69 | ||
| 42 | addr = cpu_addr ? *cpu_addr : 0; | 70 | addr = cpu_addr ? *cpu_addr : 0; |
| 43 | size_in_bytes_total = SizeInBytesTotal(); | 71 | size_in_bytes = SizeInBytesRaw(); |
| 44 | size_in_bytes_2d = SizeInBytes2D(); | 72 | |
| 45 | 73 | if (IsPixelFormatASTC(pixel_format)) { | |
| 46 | // Clamp sizes to mapped GPU memory region | 74 | // ASTC is uncompressed in software, in emulated as RGBA8 |
| 47 | if (size_in_bytes_2d > max_size) { | 75 | size_in_bytes_gl = width * height * depth * 4; |
| 48 | LOG_ERROR(HW_GPU, "Surface size {} exceeds region size {}", size_in_bytes_2d, max_size); | 76 | } else { |
| 49 | size_in_bytes_total = max_size; | 77 | size_in_bytes_gl = SizeInBytesGL(); |
| 50 | size_in_bytes_2d = max_size; | 78 | } |
| 51 | } else if (size_in_bytes_total > max_size) { | 79 | |
| 52 | LOG_ERROR(HW_GPU, "Surface size {} exceeds region size {}", size_in_bytes_total, max_size); | 80 | // Clamp size to mapped GPU memory region |
| 53 | size_in_bytes_total = max_size; | 81 | // TODO(bunnei): Super Mario Odyssey maps a 0x40000 byte region and then uses it for a 0x80000 |
| 82 | // R32F render buffer. We do not yet know if this is a game bug or something else, but this | ||
| 83 | // check is necessary to prevent flushing from overwriting unmapped memory. | ||
| 84 | if (size_in_bytes > max_size) { | ||
| 85 | LOG_ERROR(HW_GPU, "Surface size {} exceeds region size {}", size_in_bytes, max_size); | ||
| 86 | size_in_bytes = max_size; | ||
| 54 | } | 87 | } |
| 55 | } | 88 | } |
| 56 | 89 | ||
| @@ -289,34 +322,6 @@ static const FormatTuple& GetFormatTuple(PixelFormat pixel_format, ComponentType | |||
| 289 | return format; | 322 | return format; |
| 290 | } | 323 | } |
| 291 | 324 | ||
| 292 | static bool IsPixelFormatASTC(PixelFormat format) { | ||
| 293 | switch (format) { | ||
| 294 | case PixelFormat::ASTC_2D_4X4: | ||
| 295 | case PixelFormat::ASTC_2D_5X4: | ||
| 296 | case PixelFormat::ASTC_2D_8X8: | ||
| 297 | case PixelFormat::ASTC_2D_8X5: | ||
| 298 | return true; | ||
| 299 | default: | ||
| 300 | return false; | ||
| 301 | } | ||
| 302 | } | ||
| 303 | |||
| 304 | static std::pair<u32, u32> GetASTCBlockSize(PixelFormat format) { | ||
| 305 | switch (format) { | ||
| 306 | case PixelFormat::ASTC_2D_4X4: | ||
| 307 | return {4, 4}; | ||
| 308 | case PixelFormat::ASTC_2D_5X4: | ||
| 309 | return {5, 4}; | ||
| 310 | case PixelFormat::ASTC_2D_8X8: | ||
| 311 | return {8, 8}; | ||
| 312 | case PixelFormat::ASTC_2D_8X5: | ||
| 313 | return {8, 5}; | ||
| 314 | default: | ||
| 315 | LOG_CRITICAL(HW_GPU, "Unhandled format: {}", static_cast<u32>(format)); | ||
| 316 | UNREACHABLE(); | ||
| 317 | } | ||
| 318 | } | ||
| 319 | |||
| 320 | MathUtil::Rectangle<u32> SurfaceParams::GetRect() const { | 325 | MathUtil::Rectangle<u32> SurfaceParams::GetRect() const { |
| 321 | u32 actual_height{unaligned_height}; | 326 | u32 actual_height{unaligned_height}; |
| 322 | if (IsPixelFormatASTC(pixel_format)) { | 327 | if (IsPixelFormatASTC(pixel_format)) { |
| @@ -358,7 +363,7 @@ void MortonCopy(u32 stride, u32 block_height, u32 height, u32 block_depth, u32 d | |||
| 358 | const std::size_t size_to_copy{std::min(gl_buffer_size, data.size())}; | 363 | const std::size_t size_to_copy{std::min(gl_buffer_size, data.size())}; |
| 359 | memcpy(gl_buffer, data.data(), size_to_copy); | 364 | memcpy(gl_buffer, data.data(), size_to_copy); |
| 360 | } else { | 365 | } else { |
| 361 | std::vector<u8> data(height * stride * bytes_per_pixel); | 366 | std::vector<u8> data(gl_buffer_size); |
| 362 | Tegra::Texture::CopySwizzledData(stride / tile_size, height / tile_size, depth, | 367 | Tegra::Texture::CopySwizzledData(stride / tile_size, height / tile_size, depth, |
| 363 | bytes_per_pixel, bytes_per_pixel, data.data(), gl_buffer, | 368 | bytes_per_pixel, bytes_per_pixel, data.data(), gl_buffer, |
| 364 | false, block_height, block_depth); | 369 | false, block_height, block_depth); |
| @@ -639,22 +644,21 @@ static void CopySurface(const Surface& src_surface, const Surface& dst_surface, | |||
| 639 | auto source_format = GetFormatTuple(src_params.pixel_format, src_params.component_type); | 644 | auto source_format = GetFormatTuple(src_params.pixel_format, src_params.component_type); |
| 640 | auto dest_format = GetFormatTuple(dst_params.pixel_format, dst_params.component_type); | 645 | auto dest_format = GetFormatTuple(dst_params.pixel_format, dst_params.component_type); |
| 641 | 646 | ||
| 642 | std::size_t buffer_size = | 647 | std::size_t buffer_size = std::max(src_params.size_in_bytes, dst_params.size_in_bytes); |
| 643 | std::max(src_params.size_in_bytes_total, dst_params.size_in_bytes_total); | ||
| 644 | 648 | ||
| 645 | glBindBuffer(GL_PIXEL_PACK_BUFFER, copy_pbo_handle); | 649 | glBindBuffer(GL_PIXEL_PACK_BUFFER, copy_pbo_handle); |
| 646 | glBufferData(GL_PIXEL_PACK_BUFFER, buffer_size, nullptr, GL_STREAM_DRAW_ARB); | 650 | glBufferData(GL_PIXEL_PACK_BUFFER, buffer_size, nullptr, GL_STREAM_DRAW_ARB); |
| 647 | if (source_format.compressed) { | 651 | if (source_format.compressed) { |
| 648 | glGetCompressedTextureImage(src_surface->Texture().handle, src_attachment, | 652 | glGetCompressedTextureImage(src_surface->Texture().handle, src_attachment, |
| 649 | static_cast<GLsizei>(src_params.size_in_bytes_total), nullptr); | 653 | static_cast<GLsizei>(src_params.size_in_bytes), nullptr); |
| 650 | } else { | 654 | } else { |
| 651 | glGetTextureImage(src_surface->Texture().handle, src_attachment, source_format.format, | 655 | glGetTextureImage(src_surface->Texture().handle, src_attachment, source_format.format, |
| 652 | source_format.type, static_cast<GLsizei>(src_params.size_in_bytes_total), | 656 | source_format.type, static_cast<GLsizei>(src_params.size_in_bytes), |
| 653 | nullptr); | 657 | nullptr); |
| 654 | } | 658 | } |
| 655 | // If the new texture is bigger than the previous one, we need to fill in the rest with data | 659 | // If the new texture is bigger than the previous one, we need to fill in the rest with data |
| 656 | // from the CPU. | 660 | // from the CPU. |
| 657 | if (src_params.size_in_bytes_total < dst_params.size_in_bytes_total) { | 661 | if (src_params.size_in_bytes < dst_params.size_in_bytes) { |
| 658 | // Upload the rest of the memory. | 662 | // Upload the rest of the memory. |
| 659 | if (dst_params.is_tiled) { | 663 | if (dst_params.is_tiled) { |
| 660 | // TODO(Subv): We might have to de-tile the subtexture and re-tile it with the rest | 664 | // TODO(Subv): We might have to de-tile the subtexture and re-tile it with the rest |
| @@ -664,14 +668,12 @@ static void CopySurface(const Surface& src_surface, const Surface& dst_surface, | |||
| 664 | LOG_DEBUG(HW_GPU, "Trying to upload extra texture data from the CPU during " | 668 | LOG_DEBUG(HW_GPU, "Trying to upload extra texture data from the CPU during " |
| 665 | "reinterpretation but the texture is tiled."); | 669 | "reinterpretation but the texture is tiled."); |
| 666 | } | 670 | } |
| 667 | std::size_t remaining_size = | 671 | std::size_t remaining_size = dst_params.size_in_bytes - src_params.size_in_bytes; |
| 668 | dst_params.size_in_bytes_total - src_params.size_in_bytes_total; | ||
| 669 | std::vector<u8> data(remaining_size); | 672 | std::vector<u8> data(remaining_size); |
| 670 | std::memcpy(data.data(), | 673 | std::memcpy(data.data(), Memory::GetPointer(dst_params.addr + src_params.size_in_bytes), |
| 671 | Memory::GetPointer(dst_params.addr + src_params.size_in_bytes_total), | ||
| 672 | data.size()); | 674 | data.size()); |
| 673 | 675 | ||
| 674 | glBufferSubData(GL_PIXEL_PACK_BUFFER, src_params.size_in_bytes_total, remaining_size, | 676 | glBufferSubData(GL_PIXEL_PACK_BUFFER, src_params.size_in_bytes, remaining_size, |
| 675 | data.data()); | 677 | data.data()); |
| 676 | } | 678 | } |
| 677 | 679 | ||
| @@ -873,20 +875,10 @@ static void ConvertFormatAsNeeded_FlushGLBuffer(std::vector<u8>& data, PixelForm | |||
| 873 | 875 | ||
| 874 | MICROPROFILE_DEFINE(OpenGL_SurfaceLoad, "OpenGL", "Surface Load", MP_RGB(128, 64, 192)); | 876 | MICROPROFILE_DEFINE(OpenGL_SurfaceLoad, "OpenGL", "Surface Load", MP_RGB(128, 64, 192)); |
| 875 | void CachedSurface::LoadGLBuffer() { | 877 | void CachedSurface::LoadGLBuffer() { |
| 876 | ASSERT(params.type != SurfaceType::Fill); | ||
| 877 | |||
| 878 | const u8* const texture_src_data = Memory::GetPointer(params.addr); | ||
| 879 | |||
| 880 | ASSERT(texture_src_data); | ||
| 881 | |||
| 882 | const u32 bytes_per_pixel = SurfaceParams::GetBytesPerPixel(params.pixel_format); | ||
| 883 | const u32 copy_size = params.width * params.height * bytes_per_pixel; | ||
| 884 | const std::size_t total_size = copy_size * params.depth; | ||
| 885 | |||
| 886 | MICROPROFILE_SCOPE(OpenGL_SurfaceLoad); | 878 | MICROPROFILE_SCOPE(OpenGL_SurfaceLoad); |
| 887 | 879 | ||
| 880 | gl_buffer.resize(params.size_in_bytes_gl); | ||
| 888 | if (params.is_tiled) { | 881 | if (params.is_tiled) { |
| 889 | gl_buffer.resize(total_size); | ||
| 890 | u32 depth = params.depth; | 882 | u32 depth = params.depth; |
| 891 | u32 block_depth = params.block_depth; | 883 | u32 block_depth = params.block_depth; |
| 892 | 884 | ||
| @@ -899,13 +891,12 @@ void CachedSurface::LoadGLBuffer() { | |||
| 899 | block_depth = 1U; | 891 | block_depth = 1U; |
| 900 | } | 892 | } |
| 901 | 893 | ||
| 902 | const std::size_t size = copy_size * depth; | ||
| 903 | |||
| 904 | morton_to_gl_fns[static_cast<std::size_t>(params.pixel_format)]( | 894 | morton_to_gl_fns[static_cast<std::size_t>(params.pixel_format)]( |
| 905 | params.width, params.block_height, params.height, block_depth, depth, gl_buffer.data(), | 895 | params.width, params.block_height, params.height, block_depth, depth, gl_buffer.data(), |
| 906 | size, params.addr); | 896 | gl_buffer.size(), params.addr); |
| 907 | } else { | 897 | } else { |
| 908 | const u8* const texture_src_data_end{texture_src_data + total_size}; | 898 | const auto texture_src_data{Memory::GetPointer(params.addr)}; |
| 899 | const auto texture_src_data_end{texture_src_data + params.size_in_bytes_gl}; | ||
| 909 | gl_buffer.assign(texture_src_data, texture_src_data_end); | 900 | gl_buffer.assign(texture_src_data, texture_src_data_end); |
| 910 | } | 901 | } |
| 911 | 902 | ||
| @@ -918,10 +909,11 @@ MICROPROFILE_DEFINE(OpenGL_SurfaceFlush, "OpenGL", "Surface Flush", MP_RGB(128, | |||
| 918 | void CachedSurface::FlushGLBuffer() { | 909 | void CachedSurface::FlushGLBuffer() { |
| 919 | MICROPROFILE_SCOPE(OpenGL_SurfaceFlush); | 910 | MICROPROFILE_SCOPE(OpenGL_SurfaceFlush); |
| 920 | 911 | ||
| 921 | // Load data from memory to the surface | 912 | ASSERT_MSG(!IsPixelFormatASTC(params.pixel_format), "Unimplemented"); |
| 922 | const u32 bytes_per_pixel = SurfaceParams::GetBytesPerPixel(params.pixel_format); | 913 | |
| 923 | const u32 copy_size = params.width * params.height * bytes_per_pixel; | 914 | // OpenGL temporary buffer needs to be big enough to store raw texture size |
| 924 | gl_buffer.resize(static_cast<size_t>(params.depth) * copy_size); | 915 | gl_buffer.resize(params.size_in_bytes); |
| 916 | |||
| 925 | const FormatTuple& tuple = GetFormatTuple(params.pixel_format, params.component_type); | 917 | const FormatTuple& tuple = GetFormatTuple(params.pixel_format, params.component_type); |
| 926 | // Ensure no bad interactions with GL_UNPACK_ALIGNMENT | 918 | // Ensure no bad interactions with GL_UNPACK_ALIGNMENT |
| 927 | ASSERT(params.width * SurfaceParams::GetBytesPerPixel(params.pixel_format) % 4 == 0); | 919 | ASSERT(params.width * SurfaceParams::GetBytesPerPixel(params.pixel_format) % 4 == 0); |
| @@ -950,7 +942,7 @@ void CachedSurface::FlushGLBuffer() { | |||
| 950 | } | 942 | } |
| 951 | gl_to_morton_fns[static_cast<size_t>(params.pixel_format)]( | 943 | gl_to_morton_fns[static_cast<size_t>(params.pixel_format)]( |
| 952 | params.width, params.block_height, params.height, block_depth, depth, gl_buffer.data(), | 944 | params.width, params.block_height, params.height, block_depth, depth, gl_buffer.data(), |
| 953 | copy_size, GetAddr()); | 945 | gl_buffer.size(), GetAddr()); |
| 954 | } else { | 946 | } else { |
| 955 | std::memcpy(Memory::GetPointer(GetAddr()), gl_buffer.data(), GetSizeInBytes()); | 947 | std::memcpy(Memory::GetPointer(GetAddr()), gl_buffer.data(), GetSizeInBytes()); |
| 956 | } | 948 | } |
| @@ -963,10 +955,6 @@ void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle | |||
| 963 | 955 | ||
| 964 | MICROPROFILE_SCOPE(OpenGL_TextureUL); | 956 | MICROPROFILE_SCOPE(OpenGL_TextureUL); |
| 965 | 957 | ||
| 966 | ASSERT(gl_buffer.size() == static_cast<std::size_t>(params.width) * params.height * | ||
| 967 | SurfaceParams::GetBytesPerPixel(params.pixel_format) * | ||
| 968 | params.depth); | ||
| 969 | |||
| 970 | const auto& rect{params.GetRect()}; | 958 | const auto& rect{params.GetRect()}; |
| 971 | 959 | ||
| 972 | // Load data from memory to the surface | 960 | // Load data from memory to the surface |
| @@ -1001,7 +989,7 @@ void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle | |||
| 1001 | glCompressedTexImage2D( | 989 | glCompressedTexImage2D( |
| 1002 | SurfaceTargetToGL(params.target), 0, tuple.internal_format, | 990 | SurfaceTargetToGL(params.target), 0, tuple.internal_format, |
| 1003 | static_cast<GLsizei>(params.width), static_cast<GLsizei>(params.height), 0, | 991 | static_cast<GLsizei>(params.width), static_cast<GLsizei>(params.height), 0, |
| 1004 | static_cast<GLsizei>(params.size_in_bytes_2d), &gl_buffer[buffer_offset]); | 992 | static_cast<GLsizei>(params.size_in_bytes_gl), &gl_buffer[buffer_offset]); |
| 1005 | break; | 993 | break; |
| 1006 | case SurfaceParams::SurfaceTarget::Texture3D: | 994 | case SurfaceParams::SurfaceTarget::Texture3D: |
| 1007 | case SurfaceParams::SurfaceTarget::Texture2DArray: | 995 | case SurfaceParams::SurfaceTarget::Texture2DArray: |
| @@ -1009,16 +997,16 @@ void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle | |||
| 1009 | SurfaceTargetToGL(params.target), 0, tuple.internal_format, | 997 | SurfaceTargetToGL(params.target), 0, tuple.internal_format, |
| 1010 | static_cast<GLsizei>(params.width), static_cast<GLsizei>(params.height), | 998 | static_cast<GLsizei>(params.width), static_cast<GLsizei>(params.height), |
| 1011 | static_cast<GLsizei>(params.depth), 0, | 999 | static_cast<GLsizei>(params.depth), 0, |
| 1012 | static_cast<GLsizei>(params.size_in_bytes_total), &gl_buffer[buffer_offset]); | 1000 | static_cast<GLsizei>(params.size_in_bytes_gl), &gl_buffer[buffer_offset]); |
| 1013 | break; | 1001 | break; |
| 1014 | case SurfaceParams::SurfaceTarget::TextureCubemap: | 1002 | case SurfaceParams::SurfaceTarget::TextureCubemap: |
| 1015 | for (std::size_t face = 0; face < params.depth; ++face) { | 1003 | for (std::size_t face = 0; face < params.depth; ++face) { |
| 1016 | glCompressedTexImage2D(static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face), | 1004 | glCompressedTexImage2D(static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face), |
| 1017 | 0, tuple.internal_format, static_cast<GLsizei>(params.width), | 1005 | 0, tuple.internal_format, static_cast<GLsizei>(params.width), |
| 1018 | static_cast<GLsizei>(params.height), 0, | 1006 | static_cast<GLsizei>(params.height), 0, |
| 1019 | static_cast<GLsizei>(params.size_in_bytes_2d), | 1007 | static_cast<GLsizei>(params.SizeInBytesCubeFaceGL()), |
| 1020 | &gl_buffer[buffer_offset]); | 1008 | &gl_buffer[buffer_offset]); |
| 1021 | buffer_offset += params.size_in_bytes_2d; | 1009 | buffer_offset += params.SizeInBytesCubeFace(); |
| 1022 | } | 1010 | } |
| 1023 | break; | 1011 | break; |
| 1024 | default: | 1012 | default: |
| @@ -1028,7 +1016,7 @@ void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle | |||
| 1028 | glCompressedTexImage2D( | 1016 | glCompressedTexImage2D( |
| 1029 | GL_TEXTURE_2D, 0, tuple.internal_format, static_cast<GLsizei>(params.width), | 1017 | GL_TEXTURE_2D, 0, tuple.internal_format, static_cast<GLsizei>(params.width), |
| 1030 | static_cast<GLsizei>(params.height), 0, | 1018 | static_cast<GLsizei>(params.height), 0, |
| 1031 | static_cast<GLsizei>(params.size_in_bytes_2d), &gl_buffer[buffer_offset]); | 1019 | static_cast<GLsizei>(params.size_in_bytes_gl), &gl_buffer[buffer_offset]); |
| 1032 | } | 1020 | } |
| 1033 | } else { | 1021 | } else { |
| 1034 | 1022 | ||
| @@ -1057,7 +1045,7 @@ void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle | |||
| 1057 | y0, static_cast<GLsizei>(rect.GetWidth()), | 1045 | y0, static_cast<GLsizei>(rect.GetWidth()), |
| 1058 | static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type, | 1046 | static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type, |
| 1059 | &gl_buffer[buffer_offset]); | 1047 | &gl_buffer[buffer_offset]); |
| 1060 | buffer_offset += params.size_in_bytes_2d; | 1048 | buffer_offset += params.SizeInBytesCubeFace(); |
| 1061 | } | 1049 | } |
| 1062 | break; | 1050 | break; |
| 1063 | default: | 1051 | default: |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 5dbef0c89..843f18cea 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include "video_core/rasterizer_cache.h" | 18 | #include "video_core/rasterizer_cache.h" |
| 19 | #include "video_core/renderer_opengl/gl_resource_manager.h" | 19 | #include "video_core/renderer_opengl/gl_resource_manager.h" |
| 20 | #include "video_core/renderer_opengl/gl_shader_gen.h" | 20 | #include "video_core/renderer_opengl/gl_shader_gen.h" |
| 21 | #include "video_core/textures/decoders.h" | ||
| 21 | #include "video_core/textures/texture.h" | 22 | #include "video_core/textures/texture.h" |
| 22 | 23 | ||
| 23 | namespace OpenGL { | 24 | namespace OpenGL { |
| @@ -712,18 +713,31 @@ struct SurfaceParams { | |||
| 712 | /// Returns the rectangle corresponding to this surface | 713 | /// Returns the rectangle corresponding to this surface |
| 713 | MathUtil::Rectangle<u32> GetRect() const; | 714 | MathUtil::Rectangle<u32> GetRect() const; |
| 714 | 715 | ||
| 715 | /// Returns the size of this surface as a 2D texture in bytes, adjusted for compression | 716 | /// Returns the total size of this surface in bytes, adjusted for compression |
| 716 | std::size_t SizeInBytes2D() const { | 717 | std::size_t SizeInBytesRaw(bool ignore_tiled = false) const { |
| 717 | const u32 compression_factor{GetCompressionFactor(pixel_format)}; | 718 | const u32 compression_factor{GetCompressionFactor(pixel_format)}; |
| 718 | ASSERT(width % compression_factor == 0); | 719 | const u32 bytes_per_pixel{GetBytesPerPixel(pixel_format)}; |
| 719 | ASSERT(height % compression_factor == 0); | 720 | const size_t uncompressed_size{ |
| 720 | return (width / compression_factor) * (height / compression_factor) * | 721 | Tegra::Texture::CalculateSize((ignore_tiled ? false : is_tiled), bytes_per_pixel, width, |
| 721 | GetFormatBpp(pixel_format) / CHAR_BIT; | 722 | height, depth, block_height, block_depth)}; |
| 723 | |||
| 724 | // Divide by compression_factor^2, as height and width are factored by this | ||
| 725 | return uncompressed_size / (compression_factor * compression_factor); | ||
| 722 | } | 726 | } |
| 723 | 727 | ||
| 724 | /// Returns the total size of this surface in bytes, adjusted for compression | 728 | /// Returns the size of this surface as an OpenGL texture in bytes |
| 725 | std::size_t SizeInBytesTotal() const { | 729 | std::size_t SizeInBytesGL() const { |
| 726 | return SizeInBytes2D() * depth; | 730 | return SizeInBytesRaw(true); |
| 731 | } | ||
| 732 | |||
| 733 | /// Returns the size of this surface as a cube face in bytes | ||
| 734 | std::size_t SizeInBytesCubeFace() const { | ||
| 735 | return size_in_bytes / 6; | ||
| 736 | } | ||
| 737 | |||
| 738 | /// Returns the size of this surface as an OpenGL cube face in bytes | ||
| 739 | std::size_t SizeInBytesCubeFaceGL() const { | ||
| 740 | return size_in_bytes_gl / 6; | ||
| 727 | } | 741 | } |
| 728 | 742 | ||
| 729 | /// Creates SurfaceParams from a texture configuration | 743 | /// Creates SurfaceParams from a texture configuration |
| @@ -769,8 +783,8 @@ struct SurfaceParams { | |||
| 769 | 783 | ||
| 770 | // Parameters used for caching | 784 | // Parameters used for caching |
| 771 | VAddr addr; | 785 | VAddr addr; |
| 772 | std::size_t size_in_bytes_total; | 786 | std::size_t size_in_bytes; |
| 773 | std::size_t size_in_bytes_2d; | 787 | std::size_t size_in_bytes_gl; |
| 774 | 788 | ||
| 775 | // Render target specific parameters, not used in caching | 789 | // Render target specific parameters, not used in caching |
| 776 | struct { | 790 | struct { |
| @@ -812,7 +826,7 @@ public: | |||
| 812 | } | 826 | } |
| 813 | 827 | ||
| 814 | std::size_t GetSizeInBytes() const { | 828 | std::size_t GetSizeInBytes() const { |
| 815 | return params.size_in_bytes_total; | 829 | return params.size_in_bytes; |
| 816 | } | 830 | } |
| 817 | 831 | ||
| 818 | void Flush() { | 832 | void Flush() { |