summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2018-09-14 11:33:55 -0400
committerGravatar bunnei2018-09-30 14:31:56 -0400
commitce452049d3053662b3a0af6ad26eb267a699c742 (patch)
tree9936d625086dbbf001d24983aa3ac6f2e0336184 /src
parentMerge pull request #1418 from FearlessTobi/port-4269 (diff)
downloadyuzu-ce452049d3053662b3a0af6ad26eb267a699c742.tar.gz
yuzu-ce452049d3053662b3a0af6ad26eb267a699c742.tar.xz
yuzu-ce452049d3053662b3a0af6ad26eb267a699c742.zip
gl_rasterizer_cache: Keep track of surface 2D size separately from total size.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp60
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h18
2 files changed, 46 insertions, 32 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index 24a540258..b11206925 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -71,7 +71,8 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) {
71 break; 71 break;
72 } 72 }
73 73
74 params.size_in_bytes = params.SizeInBytes(); 74 params.size_in_bytes_total = params.SizeInBytesTotal();
75 params.size_in_bytes_2d = params.SizeInBytes2D();
75 return params; 76 return params;
76} 77}
77 78
@@ -89,7 +90,8 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) {
89 params.unaligned_height = config.height; 90 params.unaligned_height = config.height;
90 params.target = SurfaceTarget::Texture2D; 91 params.target = SurfaceTarget::Texture2D;
91 params.depth = 1; 92 params.depth = 1;
92 params.size_in_bytes = params.SizeInBytes(); 93 params.size_in_bytes_total = params.SizeInBytesTotal();
94 params.size_in_bytes_2d = params.SizeInBytes2D();
93 return params; 95 return params;
94} 96}
95 97
@@ -108,7 +110,8 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) {
108 params.unaligned_height = zeta_height; 110 params.unaligned_height = zeta_height;
109 params.target = SurfaceTarget::Texture2D; 111 params.target = SurfaceTarget::Texture2D;
110 params.depth = 1; 112 params.depth = 1;
111 params.size_in_bytes = params.SizeInBytes(); 113 params.size_in_bytes_total = params.SizeInBytesTotal();
114 params.size_in_bytes_2d = params.SizeInBytes2D();
112 return params; 115 return params;
113} 116}
114 117
@@ -585,10 +588,13 @@ void CachedSurface::LoadGLBuffer() {
585 588
586 const u32 bytes_per_pixel = GetGLBytesPerPixel(params.pixel_format); 589 const u32 bytes_per_pixel = GetGLBytesPerPixel(params.pixel_format);
587 const u32 copy_size = params.width * params.height * bytes_per_pixel; 590 const u32 copy_size = params.width * params.height * bytes_per_pixel;
591 const std::size_t total_size = copy_size * params.depth;
588 592
589 MICROPROFILE_SCOPE(OpenGL_SurfaceLoad); 593 MICROPROFILE_SCOPE(OpenGL_SurfaceLoad);
590 594
591 if (params.is_tiled) { 595 if (params.is_tiled) {
596 gl_buffer.resize(total_size);
597
592 // TODO(bunnei): This only unswizzles and copies a 2D texture - we do not yet know how to do 598 // TODO(bunnei): This only unswizzles and copies a 2D texture - we do not yet know how to do
593 // this for 3D textures, etc. 599 // this for 3D textures, etc.
594 switch (params.target) { 600 switch (params.target) {
@@ -601,13 +607,11 @@ void CachedSurface::LoadGLBuffer() {
601 UNREACHABLE(); 607 UNREACHABLE();
602 } 608 }
603 609
604 gl_buffer.resize(static_cast<std::size_t>(params.depth) * copy_size);
605 morton_to_gl_fns[static_cast<std::size_t>(params.pixel_format)]( 610 morton_to_gl_fns[static_cast<std::size_t>(params.pixel_format)](
606 params.width, params.block_height, params.height, gl_buffer.data(), copy_size, 611 params.width, params.block_height, params.height, gl_buffer.data(), copy_size,
607 params.addr); 612 params.addr);
608 } else { 613 } else {
609 const u8* const texture_src_data_end{texture_src_data + 614 const u8* const texture_src_data_end{texture_src_data + total_size};
610 (static_cast<std::size_t>(params.depth) * copy_size)};
611 gl_buffer.assign(texture_src_data, texture_src_data_end); 615 gl_buffer.assign(texture_src_data, texture_src_data_end);
612 } 616 }
613 617
@@ -663,15 +667,15 @@ void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle
663 glCompressedTexImage2D( 667 glCompressedTexImage2D(
664 SurfaceTargetToGL(params.target), 0, tuple.internal_format, 668 SurfaceTargetToGL(params.target), 0, tuple.internal_format,
665 static_cast<GLsizei>(params.width), static_cast<GLsizei>(params.height), 0, 669 static_cast<GLsizei>(params.width), static_cast<GLsizei>(params.height), 0,
666 static_cast<GLsizei>(params.size_in_bytes), &gl_buffer[buffer_offset]); 670 static_cast<GLsizei>(params.size_in_bytes_2d), &gl_buffer[buffer_offset]);
667 break; 671 break;
668 case SurfaceParams::SurfaceTarget::Texture3D: 672 case SurfaceParams::SurfaceTarget::Texture3D:
669 case SurfaceParams::SurfaceTarget::Texture2DArray: 673 case SurfaceParams::SurfaceTarget::Texture2DArray:
670 glCompressedTexImage3D( 674 glCompressedTexImage3D(
671 SurfaceTargetToGL(params.target), 0, tuple.internal_format, 675 SurfaceTargetToGL(params.target), 0, tuple.internal_format,
672 static_cast<GLsizei>(params.width), static_cast<GLsizei>(params.height), 676 static_cast<GLsizei>(params.width), static_cast<GLsizei>(params.height),
673 static_cast<GLsizei>(params.depth), 0, static_cast<GLsizei>(params.size_in_bytes), 677 static_cast<GLsizei>(params.depth), 0,
674 &gl_buffer[buffer_offset]); 678 static_cast<GLsizei>(params.size_in_bytes_total), &gl_buffer[buffer_offset]);
675 break; 679 break;
676 default: 680 default:
677 LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}", 681 LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}",
@@ -679,8 +683,8 @@ void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle
679 UNREACHABLE(); 683 UNREACHABLE();
680 glCompressedTexImage2D( 684 glCompressedTexImage2D(
681 GL_TEXTURE_2D, 0, tuple.internal_format, static_cast<GLsizei>(params.width), 685 GL_TEXTURE_2D, 0, tuple.internal_format, static_cast<GLsizei>(params.width),
682 static_cast<GLsizei>(params.height), 0, static_cast<GLsizei>(params.size_in_bytes), 686 static_cast<GLsizei>(params.height), 0,
683 &gl_buffer[buffer_offset]); 687 static_cast<GLsizei>(params.size_in_bytes_2d), &gl_buffer[buffer_offset]);
684 } 688 }
685 } else { 689 } else {
686 690
@@ -811,15 +815,15 @@ Surface RasterizerCacheOpenGL::GetUncachedSurface(const SurfaceParams& params) {
811 return surface; 815 return surface;
812} 816}
813 817
814Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& surface, 818Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& old_surface,
815 const SurfaceParams& new_params) { 819 const SurfaceParams& new_params) {
816 // Verify surface is compatible for blitting 820 // Verify surface is compatible for blitting
817 const auto& params{surface->GetSurfaceParams()}; 821 const auto& old_params{old_surface->GetSurfaceParams()};
818 822
819 // Get a new surface with the new parameters, and blit the previous surface to it 823 // Get a new surface with the new parameters, and blit the previous surface to it
820 Surface new_surface{GetUncachedSurface(new_params)}; 824 Surface new_surface{GetUncachedSurface(new_params)};
821 825
822 if (params.pixel_format == new_params.pixel_format || 826 if (old_params.pixel_format == new_params.pixel_format ||
823 !Settings::values.use_accurate_framebuffers) { 827 !Settings::values.use_accurate_framebuffers) {
824 // If the format is the same, just do a framebuffer blit. This is significantly faster than 828 // If the format is the same, just do a framebuffer blit. This is significantly faster than
825 // using PBOs. The is also likely less accurate, as textures will be converted rather than 829 // 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,
833 // where pixels are reinterpreted as a new format (without conversion). This code path uses 837 // where pixels are reinterpreted as a new format (without conversion). This code path uses
834 // OpenGL PBOs and is quite slow. 838 // OpenGL PBOs and is quite slow.
835 839
836 auto source_format = GetFormatTuple(params.pixel_format, params.component_type); 840 auto source_format = GetFormatTuple(old_params.pixel_format, old_params.component_type);
837 auto dest_format = GetFormatTuple(new_params.pixel_format, new_params.component_type); 841 auto dest_format = GetFormatTuple(new_params.pixel_format, new_params.component_type);
838 842
839 std::size_t buffer_size = std::max(params.SizeInBytes(), new_params.SizeInBytes()); 843 std::size_t buffer_size =
844 std::max(old_params.size_in_bytes_total, new_params.size_in_bytes_total);
840 845
841 glBindBuffer(GL_PIXEL_PACK_BUFFER, copy_pbo.handle); 846 glBindBuffer(GL_PIXEL_PACK_BUFFER, copy_pbo.handle);
842 glBufferData(GL_PIXEL_PACK_BUFFER, buffer_size, nullptr, GL_STREAM_DRAW_ARB); 847 glBufferData(GL_PIXEL_PACK_BUFFER, buffer_size, nullptr, GL_STREAM_DRAW_ARB);
843 if (source_format.compressed) { 848 if (source_format.compressed) {
844 glGetCompressedTextureImage(surface->Texture().handle, 0, 849 glGetCompressedTextureImage(old_surface->Texture().handle, 0,
845 static_cast<GLsizei>(params.SizeInBytes()), nullptr); 850 static_cast<GLsizei>(old_params.size_in_bytes_total),
851 nullptr);
846 } else { 852 } else {
847 glGetTextureImage(surface->Texture().handle, 0, source_format.format, 853 glGetTextureImage(old_surface->Texture().handle, 0, source_format.format,
848 source_format.type, static_cast<GLsizei>(params.SizeInBytes()), 854 source_format.type,
849 nullptr); 855 static_cast<GLsizei>(old_params.size_in_bytes_total), nullptr);
850 } 856 }
851 // If the new texture is bigger than the previous one, we need to fill in the rest with data 857 // If the new texture is bigger than the previous one, we need to fill in the rest with data
852 // from the CPU. 858 // from the CPU.
853 if (params.SizeInBytes() < new_params.SizeInBytes()) { 859 if (old_params.size_in_bytes_total < new_params.size_in_bytes_total) {
854 // Upload the rest of the memory. 860 // Upload the rest of the memory.
855 if (new_params.is_tiled) { 861 if (new_params.is_tiled) {
856 // TODO(Subv): We might have to de-tile the subtexture and re-tile it with the rest 862 // 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,
860 LOG_DEBUG(HW_GPU, "Trying to upload extra texture data from the CPU during " 866 LOG_DEBUG(HW_GPU, "Trying to upload extra texture data from the CPU during "
861 "reinterpretation but the texture is tiled."); 867 "reinterpretation but the texture is tiled.");
862 } 868 }
863 std::size_t remaining_size = new_params.SizeInBytes() - params.SizeInBytes(); 869 std::size_t remaining_size =
870 new_params.size_in_bytes_total - old_params.size_in_bytes_total;
864 std::vector<u8> data(remaining_size); 871 std::vector<u8> data(remaining_size);
865 Memory::ReadBlock(new_params.addr + params.SizeInBytes(), data.data(), data.size()); 872 Memory::ReadBlock(new_params.addr + old_params.size_in_bytes_total, data.data(),
866 glBufferSubData(GL_PIXEL_PACK_BUFFER, params.SizeInBytes(), remaining_size, 873 data.size());
874 glBufferSubData(GL_PIXEL_PACK_BUFFER, old_params.size_in_bytes_total, remaining_size,
867 data.data()); 875 data.data());
868 } 876 }
869 877
@@ -898,7 +906,7 @@ Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& surface,
898 break; 906 break;
899 default: 907 default:
900 LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}", 908 LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}",
901 static_cast<u32>(params.target)); 909 static_cast<u32>(new_params.target));
902 UNREACHABLE(); 910 UNREACHABLE();
903 } 911 }
904 } 912 }
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
index 80c5f324b..9df909d01 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
@@ -689,13 +689,18 @@ struct SurfaceParams {
689 /// Returns the rectangle corresponding to this surface 689 /// Returns the rectangle corresponding to this surface
690 MathUtil::Rectangle<u32> GetRect() const; 690 MathUtil::Rectangle<u32> GetRect() const;
691 691
692 /// Returns the size of this surface in bytes, adjusted for compression 692 /// Returns the size of this surface as a 2D texture in bytes, adjusted for compression
693 std::size_t SizeInBytes() const { 693 std::size_t SizeInBytes2D() const {
694 const u32 compression_factor{GetCompressionFactor(pixel_format)}; 694 const u32 compression_factor{GetCompressionFactor(pixel_format)};
695 ASSERT(width % compression_factor == 0); 695 ASSERT(width % compression_factor == 0);
696 ASSERT(height % compression_factor == 0); 696 ASSERT(height % compression_factor == 0);
697 return (width / compression_factor) * (height / compression_factor) * 697 return (width / compression_factor) * (height / compression_factor) *
698 GetFormatBpp(pixel_format) * depth / CHAR_BIT; 698 GetFormatBpp(pixel_format) / CHAR_BIT;
699 }
700
701 /// Returns the total size of this surface in bytes, adjusted for compression
702 std::size_t SizeInBytesTotal() const {
703 return SizeInBytes2D() * depth;
699 } 704 }
700 705
701 /// Creates SurfaceParams from a texture configuration 706 /// Creates SurfaceParams from a texture configuration
@@ -725,7 +730,8 @@ struct SurfaceParams {
725 u32 height; 730 u32 height;
726 u32 depth; 731 u32 depth;
727 u32 unaligned_height; 732 u32 unaligned_height;
728 std::size_t size_in_bytes; 733 std::size_t size_in_bytes_total;
734 std::size_t size_in_bytes_2d;
729 SurfaceTarget target; 735 SurfaceTarget target;
730}; 736};
731 737
@@ -759,7 +765,7 @@ public:
759 } 765 }
760 766
761 std::size_t GetSizeInBytes() const { 767 std::size_t GetSizeInBytes() const {
762 return params.size_in_bytes; 768 return params.size_in_bytes_total;
763 } 769 }
764 770
765 const OGLTexture& Texture() const { 771 const OGLTexture& Texture() const {
@@ -822,7 +828,7 @@ private:
822 Surface GetUncachedSurface(const SurfaceParams& params); 828 Surface GetUncachedSurface(const SurfaceParams& params);
823 829
824 /// Recreates a surface with new parameters 830 /// Recreates a surface with new parameters
825 Surface RecreateSurface(const Surface& surface, const SurfaceParams& new_params); 831 Surface RecreateSurface(const Surface& old_surface, const SurfaceParams& new_params);
826 832
827 /// Reserves a unique surface that can be reused later 833 /// Reserves a unique surface that can be reused later
828 void ReserveSurface(const Surface& surface); 834 void ReserveSurface(const Surface& surface);