summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2018-08-30 20:27:23 -0400
committerGravatar bunnei2018-08-31 13:07:28 -0400
commit7f7eb29323795d34237395a257160d69cbb08d1e (patch)
treed06ab2b0bd2f426a8fb129cea437ed99e29ed5e9 /src
parentgl_rasterizer_cache: Also use reserve cache for RecreateSurface. (diff)
downloadyuzu-7f7eb29323795d34237395a257160d69cbb08d1e.tar.gz
yuzu-7f7eb29323795d34237395a257160d69cbb08d1e.tar.xz
yuzu-7f7eb29323795d34237395a257160d69cbb08d1e.zip
gl_rasterizer_cache: Use accurate framebuffer setting for accurate copies.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp20
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp107
2 files changed, 54 insertions, 73 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index cab6cf53e..7ce969f73 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -432,16 +432,6 @@ void RasterizerOpenGL::Clear() {
432 glClearStencil(regs.clear_stencil); 432 glClearStencil(regs.clear_stencil);
433 433
434 glClear(clear_mask); 434 glClear(clear_mask);
435
436 // Mark framebuffer surfaces as dirty
437 if (Settings::values.use_accurate_framebuffers) {
438 if (dirty_color_surface != nullptr) {
439 res_cache.FlushSurface(dirty_color_surface);
440 }
441 if (dirty_depth_surface != nullptr) {
442 res_cache.FlushSurface(dirty_depth_surface);
443 }
444 }
445} 435}
446 436
447std::pair<u8*, GLintptr> RasterizerOpenGL::AlignBuffer(u8* buffer_ptr, GLintptr buffer_offset, 437std::pair<u8*, GLintptr> RasterizerOpenGL::AlignBuffer(u8* buffer_ptr, GLintptr buffer_offset,
@@ -557,16 +547,6 @@ void RasterizerOpenGL::DrawArrays() {
557 texture_unit.Unbind(); 547 texture_unit.Unbind();
558 } 548 }
559 state.Apply(); 549 state.Apply();
560
561 // Mark framebuffer surfaces as dirty
562 if (Settings::values.use_accurate_framebuffers) {
563 if (dirty_color_surface != nullptr) {
564 res_cache.FlushSurface(dirty_color_surface);
565 }
566 if (dirty_depth_surface != nullptr) {
567 res_cache.FlushSurface(dirty_depth_surface);
568 }
569 }
570} 550}
571 551
572void RasterizerOpenGL::NotifyMaxwellRegisterChanged(u32 method) {} 552void RasterizerOpenGL::NotifyMaxwellRegisterChanged(u32 method) {}
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index b13fbd144..1965ab7d5 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -760,11 +760,7 @@ Surface RasterizerCacheOpenGL::GetSurface(const SurfaceParams& params, bool pres
760 // Look up surface in the cache based on address 760 // Look up surface in the cache based on address
761 Surface surface{TryGet(params.addr)}; 761 Surface surface{TryGet(params.addr)};
762 if (surface) { 762 if (surface) {
763 if (Settings::values.use_accurate_framebuffers) { 763 if (surface->GetSurfaceParams().IsCompatibleSurface(params)) {
764 // If use_accurate_framebuffers is enabled, always load from memory
765 FlushSurface(surface);
766 Unregister(surface);
767 } else if (surface->GetSurfaceParams().IsCompatibleSurface(params)) {
768 // Use the cached surface as-is 764 // Use the cached surface as-is
769 return surface; 765 return surface;
770 } else if (preserve_contents) { 766 } else if (preserve_contents) {
@@ -818,62 +814,67 @@ Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& surface,
818 return new_surface; 814 return new_surface;
819 } 815 }
820 816
821 auto source_format = GetFormatTuple(params.pixel_format, params.component_type); 817 // When using accurate framebuffers, always copy old data to new surface, regardless of format
822 auto dest_format = GetFormatTuple(new_params.pixel_format, new_params.component_type); 818 if (Settings::values.use_accurate_framebuffers) {
819 auto source_format = GetFormatTuple(params.pixel_format, params.component_type);
820 auto dest_format = GetFormatTuple(new_params.pixel_format, new_params.component_type);
823 821
824 size_t buffer_size = std::max(params.SizeInBytes(), new_params.SizeInBytes()); 822 size_t buffer_size = std::max(params.SizeInBytes(), new_params.SizeInBytes());
825 823
826 // Use a Pixel Buffer Object to download the previous texture and then upload it to the new one 824 // Use a Pixel Buffer Object to download the previous texture and then upload it to the new
827 // using the new format. 825 // one using the new format.
828 OGLBuffer pbo; 826 OGLBuffer pbo;
829 pbo.Create(); 827 pbo.Create();
830 828
831 glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo.handle); 829 glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo.handle);
832 glBufferData(GL_PIXEL_PACK_BUFFER, buffer_size, nullptr, GL_STREAM_DRAW_ARB); 830 glBufferData(GL_PIXEL_PACK_BUFFER, buffer_size, nullptr, GL_STREAM_DRAW_ARB);
833 if (source_format.compressed) { 831 if (source_format.compressed) {
834 glGetCompressedTextureImage(surface->Texture().handle, 0, 832 glGetCompressedTextureImage(surface->Texture().handle, 0,
835 static_cast<GLsizei>(params.SizeInBytes()), nullptr); 833 static_cast<GLsizei>(params.SizeInBytes()), nullptr);
836 } else { 834 } else {
837 glGetTextureImage(surface->Texture().handle, 0, source_format.format, source_format.type, 835 glGetTextureImage(surface->Texture().handle, 0, source_format.format,
838 static_cast<GLsizei>(params.SizeInBytes()), nullptr); 836 source_format.type, static_cast<GLsizei>(params.SizeInBytes()),
839 } 837 nullptr);
840 // If the new texture is bigger than the previous one, we need to fill in the rest with data 838 }
841 // from the CPU. 839 // If the new texture is bigger than the previous one, we need to fill in the rest with data
842 if (params.SizeInBytes() < new_params.SizeInBytes()) { 840 // from the CPU.
843 // Upload the rest of the memory. 841 if (params.SizeInBytes() < new_params.SizeInBytes()) {
844 if (new_params.is_tiled) { 842 // Upload the rest of the memory.
845 // TODO(Subv): We might have to de-tile the subtexture and re-tile it with the rest of 843 if (new_params.is_tiled) {
846 // the data in this case. Games like Super Mario Odyssey seem to hit this case when 844 // TODO(Subv): We might have to de-tile the subtexture and re-tile it with the rest
847 // drawing, it re-uses the memory of a previous texture as a bigger framebuffer but it 845 // of the data in this case. Games like Super Mario Odyssey seem to hit this case
848 // doesn't clear it beforehand, the texture is already full of zeros. 846 // when drawing, it re-uses the memory of a previous texture as a bigger framebuffer
849 LOG_CRITICAL(HW_GPU, "Trying to upload extra texture data from the CPU during " 847 // but it doesn't clear it beforehand, the texture is already full of zeros.
850 "reinterpretation but the texture is tiled."); 848 LOG_CRITICAL(HW_GPU, "Trying to upload extra texture data from the CPU during "
849 "reinterpretation but the texture is tiled.");
850 }
851 size_t remaining_size = new_params.SizeInBytes() - params.SizeInBytes();
852 std::vector<u8> data(remaining_size);
853 Memory::ReadBlock(new_params.addr + params.SizeInBytes(), data.data(), data.size());
854 glBufferSubData(GL_PIXEL_PACK_BUFFER, params.SizeInBytes(), remaining_size,
855 data.data());
851 } 856 }
852 size_t remaining_size = new_params.SizeInBytes() - params.SizeInBytes();
853 std::vector<u8> data(remaining_size);
854 Memory::ReadBlock(new_params.addr + params.SizeInBytes(), data.data(), data.size());
855 glBufferSubData(GL_PIXEL_PACK_BUFFER, params.SizeInBytes(), remaining_size, data.data());
856 }
857 857
858 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); 858 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
859 859
860 const auto& dest_rect{new_params.GetRect()}; 860 const auto& dest_rect{new_params.GetRect()};
861 861
862 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo.handle); 862 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo.handle);
863 if (dest_format.compressed) { 863 if (dest_format.compressed) {
864 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 864 glCompressedTexSubImage2D(
865 static_cast<GLsizei>(dest_rect.GetWidth()), 865 GL_TEXTURE_2D, 0, 0, 0, static_cast<GLsizei>(dest_rect.GetWidth()),
866 static_cast<GLsizei>(dest_rect.GetHeight()), dest_format.format, 866 static_cast<GLsizei>(dest_rect.GetHeight()), dest_format.format,
867 static_cast<GLsizei>(new_params.SizeInBytes()), nullptr); 867 static_cast<GLsizei>(new_params.SizeInBytes()), nullptr);
868 } else { 868 } else {
869 glTextureSubImage2D(new_surface->Texture().handle, 0, 0, 0, 869 glTextureSubImage2D(new_surface->Texture().handle, 0, 0, 0,
870 static_cast<GLsizei>(dest_rect.GetWidth()), 870 static_cast<GLsizei>(dest_rect.GetWidth()),
871 static_cast<GLsizei>(dest_rect.GetHeight()), dest_format.format, 871 static_cast<GLsizei>(dest_rect.GetHeight()), dest_format.format,
872 dest_format.type, nullptr); 872 dest_format.type, nullptr);
873 } 873 }
874 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); 874 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
875 875
876 pbo.Release(); 876 pbo.Release();
877 }
877 878
878 return new_surface; 879 return new_surface;
879} 880}