diff options
| author | 2018-08-30 20:27:23 -0400 | |
|---|---|---|
| committer | 2018-08-31 13:07:28 -0400 | |
| commit | 7f7eb29323795d34237395a257160d69cbb08d1e (patch) | |
| tree | d06ab2b0bd2f426a8fb129cea437ed99e29ed5e9 /src | |
| parent | gl_rasterizer_cache: Also use reserve cache for RecreateSurface. (diff) | |
| download | yuzu-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.cpp | 20 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 107 |
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 | ||
| 447 | std::pair<u8*, GLintptr> RasterizerOpenGL::AlignBuffer(u8* buffer_ptr, GLintptr buffer_offset, | 437 | std::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 | ||
| 572 | void RasterizerOpenGL::NotifyMaxwellRegisterChanged(u32 method) {} | 552 | void 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 | } |