summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp68
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h4
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
697RasterizerCacheOpenGL::RasterizerCacheOpenGL() { 698RasterizerCacheOpenGL::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
702Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextureInfo& config) { 704Surface 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