diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 68 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 4 |
2 files changed, 45 insertions, 27 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index e9fd67d00..360fb0cd5 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | 7 | ||
| 8 | #include "common/alignment.h" | 8 | #include "common/alignment.h" |
| 9 | #include "common/assert.h" | 9 | #include "common/assert.h" |
| 10 | #include "common/logging/log.h" | ||
| 10 | #include "common/microprofile.h" | 11 | #include "common/microprofile.h" |
| 11 | #include "common/scope_exit.h" | 12 | #include "common/scope_exit.h" |
| 12 | #include "core/core.h" | 13 | #include "core/core.h" |
| @@ -54,8 +55,8 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) { | |||
| 54 | params.depth = config.tic.Depth(); | 55 | params.depth = config.tic.Depth(); |
| 55 | params.unaligned_height = config.tic.Height(); | 56 | params.unaligned_height = config.tic.Height(); |
| 56 | params.size_in_bytes = params.SizeInBytes(); | 57 | params.size_in_bytes = params.SizeInBytes(); |
| 57 | params.cache_width = Common::AlignUp(params.width, 16); | 58 | params.cache_width = Common::AlignUp(params.width, 8); |
| 58 | params.cache_height = Common::AlignUp(params.height, 16); | 59 | params.cache_height = Common::AlignUp(params.height, 8); |
| 59 | params.target = SurfaceTargetFromTextureType(config.tic.texture_type); | 60 | params.target = SurfaceTargetFromTextureType(config.tic.texture_type); |
| 60 | return params; | 61 | return params; |
| 61 | } | 62 | } |
| @@ -74,8 +75,8 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) { | |||
| 74 | params.depth = 1; | 75 | params.depth = 1; |
| 75 | params.unaligned_height = config.height; | 76 | params.unaligned_height = config.height; |
| 76 | params.size_in_bytes = params.SizeInBytes(); | 77 | params.size_in_bytes = params.SizeInBytes(); |
| 77 | params.cache_width = Common::AlignUp(params.width, 16); | 78 | params.cache_width = Common::AlignUp(params.width, 8); |
| 78 | params.cache_height = Common::AlignUp(params.height, 16); | 79 | params.cache_height = Common::AlignUp(params.height, 8); |
| 79 | params.target = SurfaceTarget::Texture2D; | 80 | params.target = SurfaceTarget::Texture2D; |
| 80 | return params; | 81 | return params; |
| 81 | } | 82 | } |
| @@ -95,8 +96,8 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) { | |||
| 95 | params.depth = 1; | 96 | params.depth = 1; |
| 96 | params.unaligned_height = zeta_height; | 97 | params.unaligned_height = zeta_height; |
| 97 | params.size_in_bytes = params.SizeInBytes(); | 98 | params.size_in_bytes = params.SizeInBytes(); |
| 98 | params.cache_width = Common::AlignUp(params.width, 16); | 99 | params.cache_width = Common::AlignUp(params.width, 8); |
| 99 | params.cache_height = Common::AlignUp(params.height, 16); | 100 | params.cache_height = Common::AlignUp(params.height, 8); |
| 100 | params.target = SurfaceTarget::Texture2D; | 101 | params.target = SurfaceTarget::Texture2D; |
| 101 | return params; | 102 | return params; |
| 102 | } | 103 | } |
| @@ -697,6 +698,7 @@ void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle | |||
| 697 | RasterizerCacheOpenGL::RasterizerCacheOpenGL() { | 698 | RasterizerCacheOpenGL::RasterizerCacheOpenGL() { |
| 698 | read_framebuffer.Create(); | 699 | read_framebuffer.Create(); |
| 699 | draw_framebuffer.Create(); | 700 | draw_framebuffer.Create(); |
| 701 | copy_pbo.Create(); | ||
| 700 | } | 702 | } |
| 701 | 703 | ||
| 702 | Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextureInfo& config) { | 704 | Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextureInfo& config) { |
| @@ -827,8 +829,8 @@ Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& surface, | |||
| 827 | // If format is unchanged, we can do a faster blit without reinterpreting pixel data | 829 | // If format is unchanged, we can do a faster blit without reinterpreting pixel data |
| 828 | if (params.pixel_format == new_params.pixel_format) { | 830 | if (params.pixel_format == new_params.pixel_format) { |
| 829 | BlitTextures(surface->Texture().handle, params.GetRect(), new_surface->Texture().handle, | 831 | BlitTextures(surface->Texture().handle, params.GetRect(), new_surface->Texture().handle, |
| 830 | new_surface->GetSurfaceParams().GetRect(), params.type, | 832 | params.GetRect(), params.type, read_framebuffer.handle, |
| 831 | read_framebuffer.handle, draw_framebuffer.handle); | 833 | draw_framebuffer.handle); |
| 832 | return new_surface; | 834 | return new_surface; |
| 833 | } | 835 | } |
| 834 | 836 | ||
| @@ -839,12 +841,7 @@ Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& surface, | |||
| 839 | 841 | ||
| 840 | size_t buffer_size = std::max(params.SizeInBytes(), new_params.SizeInBytes()); | 842 | size_t buffer_size = std::max(params.SizeInBytes(), new_params.SizeInBytes()); |
| 841 | 843 | ||
| 842 | // Use a Pixel Buffer Object to download the previous texture and then upload it to the new | 844 | glBindBuffer(GL_PIXEL_PACK_BUFFER, copy_pbo.handle); |
| 843 | // one using the new format. | ||
| 844 | OGLBuffer pbo; | ||
| 845 | pbo.Create(); | ||
| 846 | |||
| 847 | glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo.handle); | ||
| 848 | glBufferData(GL_PIXEL_PACK_BUFFER, buffer_size, nullptr, GL_STREAM_DRAW_ARB); | 845 | glBufferData(GL_PIXEL_PACK_BUFFER, buffer_size, nullptr, GL_STREAM_DRAW_ARB); |
| 849 | if (source_format.compressed) { | 846 | if (source_format.compressed) { |
| 850 | glGetCompressedTextureImage(surface->Texture().handle, 0, | 847 | glGetCompressedTextureImage(surface->Texture().handle, 0, |
| @@ -863,8 +860,8 @@ Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& surface, | |||
| 863 | // of the data in this case. Games like Super Mario Odyssey seem to hit this case | 860 | // of the data in this case. Games like Super Mario Odyssey seem to hit this case |
| 864 | // when drawing, it re-uses the memory of a previous texture as a bigger framebuffer | 861 | // when drawing, it re-uses the memory of a previous texture as a bigger framebuffer |
| 865 | // but it doesn't clear it beforehand, the texture is already full of zeros. | 862 | // but it doesn't clear it beforehand, the texture is already full of zeros. |
| 866 | LOG_CRITICAL(HW_GPU, "Trying to upload extra texture data from the CPU during " | 863 | LOG_DEBUG(HW_GPU, "Trying to upload extra texture data from the CPU during " |
| 867 | "reinterpretation but the texture is tiled."); | 864 | "reinterpretation but the texture is tiled."); |
| 868 | } | 865 | } |
| 869 | size_t remaining_size = new_params.SizeInBytes() - params.SizeInBytes(); | 866 | size_t remaining_size = new_params.SizeInBytes() - params.SizeInBytes(); |
| 870 | std::vector<u8> data(remaining_size); | 867 | std::vector<u8> data(remaining_size); |
| @@ -877,21 +874,38 @@ Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& surface, | |||
| 877 | 874 | ||
| 878 | const auto& dest_rect{new_params.GetRect()}; | 875 | const auto& dest_rect{new_params.GetRect()}; |
| 879 | 876 | ||
| 880 | glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo.handle); | 877 | glBindBuffer(GL_PIXEL_UNPACK_BUFFER, copy_pbo.handle); |
| 881 | if (dest_format.compressed) { | 878 | if (dest_format.compressed) { |
| 882 | glCompressedTexSubImage2D( | 879 | LOG_CRITICAL(HW_GPU, "Compressed copy is unimplemented!"); |
| 883 | GL_TEXTURE_2D, 0, 0, 0, static_cast<GLsizei>(dest_rect.GetWidth()), | 880 | UNREACHABLE(); |
| 884 | static_cast<GLsizei>(dest_rect.GetHeight()), dest_format.format, | ||
| 885 | static_cast<GLsizei>(new_params.SizeInBytes()), nullptr); | ||
| 886 | } else { | 881 | } else { |
| 887 | glTextureSubImage2D(new_surface->Texture().handle, 0, 0, 0, | 882 | switch (new_params.target) { |
| 888 | static_cast<GLsizei>(dest_rect.GetWidth()), | 883 | case SurfaceParams::SurfaceTarget::Texture1D: |
| 889 | static_cast<GLsizei>(dest_rect.GetHeight()), dest_format.format, | 884 | glTextureSubImage1D(new_surface->Texture().handle, 0, 0, |
| 890 | dest_format.type, nullptr); | 885 | static_cast<GLsizei>(dest_rect.GetWidth()), dest_format.format, |
| 886 | dest_format.type, nullptr); | ||
| 887 | break; | ||
| 888 | case SurfaceParams::SurfaceTarget::Texture2D: | ||
| 889 | glTextureSubImage2D(new_surface->Texture().handle, 0, 0, 0, | ||
| 890 | static_cast<GLsizei>(dest_rect.GetWidth()), | ||
| 891 | static_cast<GLsizei>(dest_rect.GetHeight()), dest_format.format, | ||
| 892 | dest_format.type, nullptr); | ||
| 893 | break; | ||
| 894 | case SurfaceParams::SurfaceTarget::Texture3D: | ||
| 895 | case SurfaceParams::SurfaceTarget::Texture2DArray: | ||
| 896 | glTextureSubImage3D(new_surface->Texture().handle, 0, 0, 0, 0, | ||
| 897 | static_cast<GLsizei>(dest_rect.GetWidth()), | ||
| 898 | static_cast<GLsizei>(dest_rect.GetHeight()), | ||
| 899 | static_cast<GLsizei>(new_params.depth), dest_format.format, | ||
| 900 | dest_format.type, nullptr); | ||
| 901 | break; | ||
| 902 | default: | ||
| 903 | LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}", | ||
| 904 | static_cast<u32>(params.target)); | ||
| 905 | UNREACHABLE(); | ||
| 906 | } | ||
| 891 | } | 907 | } |
| 892 | glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); | 908 | glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); |
| 893 | |||
| 894 | pbo.Release(); | ||
| 895 | } | 909 | } |
| 896 | 910 | ||
| 897 | return new_surface; | 911 | return new_surface; |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 56022ea01..8312b2c7a 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h | |||
| @@ -807,6 +807,10 @@ private: | |||
| 807 | 807 | ||
| 808 | OGLFramebuffer read_framebuffer; | 808 | OGLFramebuffer read_framebuffer; |
| 809 | OGLFramebuffer draw_framebuffer; | 809 | OGLFramebuffer draw_framebuffer; |
| 810 | |||
| 811 | /// Use a Pixel Buffer Object to download the previous texture and then upload it to the new one | ||
| 812 | /// using the new format. | ||
| 813 | OGLBuffer copy_pbo; | ||
| 810 | }; | 814 | }; |
| 811 | 815 | ||
| 812 | } // namespace OpenGL | 816 | } // namespace OpenGL |