diff options
Diffstat (limited to 'src/video_core')
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 85 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 17 |
2 files changed, 51 insertions, 51 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 58e6dc824..1f84026cd 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include <algorithm> +#include <optional> #include <glad/glad.h> #include "common/alignment.h" @@ -1000,7 +1001,7 @@ Surface RasterizerCacheOpenGL::GetSurface(const SurfaceParams& params, bool pres Surface surface{TryGet(params.addr)}; if (surface) { if (surface->GetSurfaceParams().IsCompatibleSurface(params)) { - // Use the cached surface as-is + // Use the cached surface as-is unless it's not synced with memory if (surface->MustReload()) LoadSurface(surface); return surface; @@ -1298,44 +1299,47 @@ Surface RasterizerCacheOpenGL::TryGetReservedSurface(const SurfaceParams& params return {}; } -bool FindBestMipMap(std::size_t memory, const SurfaceParams params, u32 height, u32& mipmap) { - for (u32 i = 0; i < params.max_mip_level; i++) +static std::optional<u32> TryFindBestMipMap(std::size_t memory, const SurfaceParams params, + u32 height) { + for (u32 i = 0; i < params.max_mip_level; i++) { if (memory == params.GetMipmapSingleSize(i) && params.MipHeight(i) == height) { - mipmap = i; - return true; + return {i}; } - return false; + } + return {}; } -bool FindBestLayer(VAddr addr, const SurfaceParams params, u32 mipmap, u32& layer) { - std::size_t size = params.LayerMemorySize(); +static std::optional<u32> TryFindBestLayer(VAddr addr, const SurfaceParams params, u32 mipmap) { + const std::size_t size = params.LayerMemorySize(); VAddr start = params.addr + params.GetMipmapLevelOffset(mipmap); for (u32 i = 0; i < params.depth; i++) { if (start == addr) { - layer = i; - return true; + return {i}; } start += size; } - return false; + return {}; } -bool LayerFitReinterpretSurface(RasterizerCacheOpenGL& cache, const Surface render_surface, - const Surface blitted_surface) { - const auto dst_params = blitted_surface->GetSurfaceParams(); - const auto src_params = render_surface->GetSurfaceParams(); - u32 level = 0; - std::size_t src_memory_size = src_params.size_in_bytes; - if (FindBestMipMap(src_memory_size, dst_params, src_params.height, level)) { - if (src_params.width == dst_params.MipWidthGobAligned(level) && - src_params.height == dst_params.MipHeight(level) && - src_params.block_height >= dst_params.MipBlockHeight(level)) { - u32 slot = 0; - if (FindBestLayer(render_surface->GetAddr(), dst_params, level, slot)) { - glCopyImageSubData( - render_surface->Texture().handle, SurfaceTargetToGL(src_params.target), 0, 0, 0, - 0, blitted_surface->Texture().handle, SurfaceTargetToGL(dst_params.target), - level, 0, 0, slot, dst_params.MipWidth(level), dst_params.MipHeight(level), 1); +static bool LayerFitReinterpretSurface(RasterizerCacheOpenGL& cache, const Surface render_surface, + const Surface blitted_surface) { + const auto& dst_params = blitted_surface->GetSurfaceParams(); + const auto& src_params = render_surface->GetSurfaceParams(); + const std::size_t src_memory_size = src_params.size_in_bytes; + const std::optional<u32> level = + TryFindBestMipMap(src_memory_size, dst_params, src_params.height); + if (level.has_value()) { + if (src_params.width == dst_params.MipWidthGobAligned(*level) && + src_params.height == dst_params.MipHeight(*level) && + src_params.block_height >= dst_params.MipBlockHeight(*level)) { + const std::optional<u32> slot = + TryFindBestLayer(render_surface->GetAddr(), dst_params, *level); + if (slot.has_value()) { + glCopyImageSubData(render_surface->Texture().handle, + SurfaceTargetToGL(src_params.target), 0, 0, 0, 0, + blitted_surface->Texture().handle, + SurfaceTargetToGL(dst_params.target), *level, 0, 0, *slot, + dst_params.MipWidth(*level), dst_params.MipHeight(*level), 1); blitted_surface->MarkAsModified(true, cache); return true; } @@ -1344,24 +1348,21 @@ bool LayerFitReinterpretSurface(RasterizerCacheOpenGL& cache, const Surface rend return false; } -bool IsReinterpretInvalid(const Surface render_surface, const Surface blitted_surface) { - VAddr bound1 = blitted_surface->GetAddr() + blitted_surface->GetMemorySize(); - VAddr bound2 = render_surface->GetAddr() + render_surface->GetMemorySize(); +static bool IsReinterpretInvalid(const Surface render_surface, const Surface blitted_surface) { + const VAddr bound1 = blitted_surface->GetAddr() + blitted_surface->GetMemorySize(); + const VAddr bound2 = render_surface->GetAddr() + render_surface->GetMemorySize(); if (bound2 > bound1) return true; - const auto dst_params = blitted_surface->GetSurfaceParams(); - const auto src_params = render_surface->GetSurfaceParams(); - if (dst_params.component_type != src_params.component_type) - return true; - return false; + const auto& dst_params = blitted_surface->GetSurfaceParams(); + const auto& src_params = render_surface->GetSurfaceParams(); + return (dst_params.component_type != src_params.component_type); } -bool IsReinterpretInvalidSecond(const Surface render_surface, const Surface blitted_surface) { - const auto dst_params = blitted_surface->GetSurfaceParams(); - const auto src_params = render_surface->GetSurfaceParams(); - if (dst_params.height > src_params.height && dst_params.width > src_params.width) - return false; - return true; +static bool IsReinterpretInvalidSecond(const Surface render_surface, + const Surface blitted_surface) { + const auto& dst_params = blitted_surface->GetSurfaceParams(); + const auto& src_params = render_surface->GetSurfaceParams(); + return (dst_params.height > src_params.height && dst_params.width > src_params.width); } bool RasterizerCacheOpenGL::PartialReinterpretSurface(Surface triggering_surface, @@ -1383,7 +1384,7 @@ bool RasterizerCacheOpenGL::PartialReinterpretSurface(Surface triggering_surface } void RasterizerCacheOpenGL::SignalPreDrawCall() { - if (texception) { + if (texception && GLAD_GL_ARB_texture_barrier) { glTextureBarrier(); } texception = false; diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index ed180a683..d530d64d4 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -412,7 +412,7 @@ public: reinterpreted = true; } - bool IsReinterpreted() { + bool IsReinterpreted() const { return reinterpreted; } @@ -420,11 +420,11 @@ public: must_reload = reload; } - bool MustReload() { + bool MustReload() const { return must_reload; } - bool IsUploaded() { + bool IsUploaded() const { return params.identity == SurfaceParams::SurfaceClass::Uploaded; } @@ -489,6 +489,7 @@ private: Surface TryGetReservedSurface(const SurfaceParams& params); // Partialy reinterpret a surface based on a triggering_surface that collides with it. + // returns true if the reinterpret was successful, false in case it was not. bool PartialReinterpretSurface(Surface triggering_surface, Surface intersect); /// Performs a slow but accurate surface copy, flushing to RAM and reinterpreting the data @@ -528,10 +529,10 @@ private: // Reinterpreted surfaces are very fragil as the game may keep rendering into them. SurfaceIntervalCache reinterpreted_surfaces; - void RegisterReinterpretSurface(Surface r_surface) { - auto interval = GetReinterpretInterval(r_surface); - reinterpreted_surfaces.insert({interval, r_surface}); - r_surface->MarkReinterpreted(); + void RegisterReinterpretSurface(Surface reinterpret_surface) { + auto interval = GetReinterpretInterval(reinterpret_surface); + reinterpreted_surfaces.insert({interval, reinterpret_surface}); + reinterpret_surface->MarkReinterpreted(); } Surface CollideOnReinterpretedSurface(VAddr addr) const { @@ -543,14 +544,12 @@ private: return nullptr; } -protected: void Register(const Surface& object) { RasterizerCache<Surface>::Register(object); } /// Unregisters an object from the cache void Unregister(const Surface& object) { - const auto& params = object->GetSurfaceParams(); if (object->IsReinterpreted()) { auto interval = GetReinterpretInterval(object); reinterpreted_surfaces.erase(interval); |