diff options
| author | 2018-09-14 11:33:55 -0400 | |
|---|---|---|
| committer | 2018-09-30 14:31:56 -0400 | |
| commit | ce452049d3053662b3a0af6ad26eb267a699c742 (patch) | |
| tree | 9936d625086dbbf001d24983aa3ac6f2e0336184 /src | |
| parent | Merge pull request #1418 from FearlessTobi/port-4269 (diff) | |
| download | yuzu-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.cpp | 60 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 18 |
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 | ||
| 814 | Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& surface, | 818 | Surface 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); |