summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_opengl
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/renderer_opengl')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp24
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp41
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h38
3 files changed, 46 insertions, 57 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index c4ce57f1c..56d9c575b 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -413,11 +413,13 @@ void RasterizerOpenGL::Clear() {
glClear(clear_mask);
// Mark framebuffer surfaces as dirty
- if (dirty_color_surface != nullptr) {
- res_cache.MarkSurfaceAsDirty(dirty_color_surface);
- }
- if (dirty_depth_surface != nullptr) {
- res_cache.MarkSurfaceAsDirty(dirty_depth_surface);
+ if (Settings::values.use_accurate_framebuffers) {
+ if (dirty_color_surface != nullptr) {
+ res_cache.FlushSurface(dirty_color_surface);
+ }
+ if (dirty_depth_surface != nullptr) {
+ res_cache.FlushSurface(dirty_depth_surface);
+ }
}
}
@@ -520,11 +522,13 @@ void RasterizerOpenGL::DrawArrays() {
state.Apply();
// Mark framebuffer surfaces as dirty
- if (dirty_color_surface != nullptr) {
- res_cache.MarkSurfaceAsDirty(dirty_color_surface);
- }
- if (dirty_depth_surface != nullptr) {
- res_cache.MarkSurfaceAsDirty(dirty_depth_surface);
+ if (Settings::values.use_accurate_framebuffers) {
+ if (dirty_color_surface != nullptr) {
+ res_cache.FlushSurface(dirty_color_surface);
+ }
+ if (dirty_depth_surface != nullptr) {
+ res_cache.FlushSurface(dirty_depth_surface);
+ }
}
}
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index 672eb2990..bb53a2821 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -565,17 +565,9 @@ void RasterizerCacheOpenGL::LoadSurface(const Surface& surface) {
surface->UploadGLTexture(read_framebuffer.handle, draw_framebuffer.handle);
}
-void RasterizerCacheOpenGL::MarkSurfaceAsDirty(const Surface& surface) {
- if (Settings::values.use_accurate_framebuffers) {
- // If enabled, always flush dirty surfaces
- surface->DownloadGLTexture(read_framebuffer.handle, draw_framebuffer.handle);
- surface->FlushGLBuffer();
- } else {
- // Otherwise, don't mark surfaces that we write to as cached, because the resulting loads
- // and flushes are very slow and do not seem to improve accuracy
- const auto& params{surface->GetSurfaceParams()};
- Memory::RasterizerMarkRegionCached(params.addr, params.size_in_bytes, false);
- }
+void RasterizerCacheOpenGL::FlushSurface(const Surface& surface) {
+ surface->DownloadGLTexture(read_framebuffer.handle, draw_framebuffer.handle);
+ surface->FlushGLBuffer();
}
Surface RasterizerCacheOpenGL::GetSurface(const SurfaceParams& params) {
@@ -589,21 +581,22 @@ Surface RasterizerCacheOpenGL::GetSurface(const SurfaceParams& params) {
return {};
// Check for an exact match in existing surfaces
- const auto& surface_key{SurfaceKey::Create(params)};
- const auto& search{surface_cache.find(surface_key)};
+ const auto& search{surface_cache.find(params.addr)};
Surface surface;
if (search != surface_cache.end()) {
surface = search->second;
- if (Settings::values.use_accurate_framebuffers) {
- // Reload the surface from Switch memory
- LoadSurface(surface);
+ if (surface->GetSurfaceParams() != params || Settings::values.use_accurate_framebuffers) {
+ FlushSurface(surface);
+ UnregisterSurface(surface);
+ } else {
+ return surface;
}
- } else {
- surface = std::make_shared<CachedSurface>(params);
- RegisterSurface(surface);
- LoadSurface(surface);
}
+ surface = std::make_shared<CachedSurface>(params);
+ RegisterSurface(surface);
+ LoadSurface(surface);
+
return surface;
}
@@ -652,22 +645,20 @@ void RasterizerCacheOpenGL::InvalidateRegion(Tegra::GPUVAddr addr, size_t size)
void RasterizerCacheOpenGL::RegisterSurface(const Surface& surface) {
const auto& params{surface->GetSurfaceParams()};
- const auto& surface_key{SurfaceKey::Create(params)};
- const auto& search{surface_cache.find(surface_key)};
+ const auto& search{surface_cache.find(params.addr)};
if (search != surface_cache.end()) {
// Registered already
return;
}
- surface_cache[surface_key] = surface;
+ surface_cache[params.addr] = surface;
UpdatePagesCachedCount(params.addr, params.size_in_bytes, 1);
}
void RasterizerCacheOpenGL::UnregisterSurface(const Surface& surface) {
const auto& params{surface->GetSurfaceParams()};
- const auto& surface_key{SurfaceKey::Create(params)};
- const auto& search{surface_cache.find(surface_key)};
+ const auto& search{surface_cache.find(params.addr)};
if (search == surface_cache.end()) {
// Unregistered already
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
index d00746e8c..5124199b2 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
@@ -10,7 +10,6 @@
#include <vector>
#include <boost/icl/interval_map.hpp>
#include "common/common_types.h"
-#include "common/hash.h"
#include "common/math_util.h"
#include "video_core/engines/maxwell_3d.h"
#include "video_core/renderer_opengl/gl_resource_manager.h"
@@ -137,6 +136,7 @@ struct SurfaceParams {
ASSERT(static_cast<size_t>(format) < bpp_table.size());
return bpp_table[static_cast<size_t>(format)];
}
+
u32 GetFormatBpp() const {
return GetFormatBpp(pixel_format);
}
@@ -369,6 +369,18 @@ struct SurfaceParams {
Tegra::GPUVAddr zeta_address,
Tegra::DepthFormat format);
+ bool operator==(const SurfaceParams& other) const {
+ return std::tie(addr, is_tiled, block_height, pixel_format, component_type, type, width,
+ height, unaligned_height, size_in_bytes) ==
+ std::tie(other.addr, other.is_tiled, other.block_height, other.pixel_format,
+ other.component_type, other.type, other.width, other.height,
+ other.unaligned_height, other.size_in_bytes);
+ }
+
+ bool operator!=(const SurfaceParams& other) const {
+ return !operator==(other);
+ }
+
Tegra::GPUVAddr addr;
bool is_tiled;
u32 block_height;
@@ -381,24 +393,6 @@ struct SurfaceParams {
size_t size_in_bytes;
};
-/// Hashable variation of SurfaceParams, used for a key in the surface cache
-struct SurfaceKey : Common::HashableStruct<SurfaceParams> {
- static SurfaceKey Create(const SurfaceParams& params) {
- SurfaceKey res;
- res.state = params;
- return res;
- }
-};
-
-namespace std {
-template <>
-struct hash<SurfaceKey> {
- size_t operator()(const SurfaceKey& k) const {
- return k.Hash();
- }
-};
-} // namespace std
-
class CachedSurface final {
public:
CachedSurface(const SurfaceParams& params);
@@ -444,8 +438,8 @@ public:
SurfaceSurfaceRect_Tuple GetFramebufferSurfaces(bool using_color_fb, bool using_depth_fb,
const MathUtil::Rectangle<s32>& viewport);
- /// Marks the specified surface as "dirty", in that it is out of sync with Switch memory
- void MarkSurfaceAsDirty(const Surface& surface);
+ /// Flushes the surface to Switch memory
+ void FlushSurface(const Surface& surface);
/// Tries to find a framebuffer GPU address based on the provided CPU address
Surface TryFindFramebufferSurface(VAddr cpu_addr) const;
@@ -469,7 +463,7 @@ private:
/// Increase/decrease the number of surface in pages touching the specified region
void UpdatePagesCachedCount(Tegra::GPUVAddr addr, u64 size, int delta);
- std::unordered_map<SurfaceKey, Surface> surface_cache;
+ std::unordered_map<Tegra::GPUVAddr, Surface> surface_cache;
PageMap cached_pages;
OGLFramebuffer read_framebuffer;