diff options
Diffstat (limited to '')
| -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 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <algorithm> | 5 | #include <algorithm> |
| 6 | #include <optional> | ||
| 6 | #include <glad/glad.h> | 7 | #include <glad/glad.h> |
| 7 | 8 | ||
| 8 | #include "common/alignment.h" | 9 | #include "common/alignment.h" |
| @@ -1000,7 +1001,7 @@ Surface RasterizerCacheOpenGL::GetSurface(const SurfaceParams& params, bool pres | |||
| 1000 | Surface surface{TryGet(params.addr)}; | 1001 | Surface surface{TryGet(params.addr)}; |
| 1001 | if (surface) { | 1002 | if (surface) { |
| 1002 | if (surface->GetSurfaceParams().IsCompatibleSurface(params)) { | 1003 | if (surface->GetSurfaceParams().IsCompatibleSurface(params)) { |
| 1003 | // Use the cached surface as-is | 1004 | // Use the cached surface as-is unless it's not synced with memory |
| 1004 | if (surface->MustReload()) | 1005 | if (surface->MustReload()) |
| 1005 | LoadSurface(surface); | 1006 | LoadSurface(surface); |
| 1006 | return surface; | 1007 | return surface; |
| @@ -1298,44 +1299,47 @@ Surface RasterizerCacheOpenGL::TryGetReservedSurface(const SurfaceParams& params | |||
| 1298 | return {}; | 1299 | return {}; |
| 1299 | } | 1300 | } |
| 1300 | 1301 | ||
| 1301 | bool FindBestMipMap(std::size_t memory, const SurfaceParams params, u32 height, u32& mipmap) { | 1302 | static std::optional<u32> TryFindBestMipMap(std::size_t memory, const SurfaceParams params, |
| 1302 | for (u32 i = 0; i < params.max_mip_level; i++) | 1303 | u32 height) { |
| 1304 | for (u32 i = 0; i < params.max_mip_level; i++) { | ||
| 1303 | if (memory == params.GetMipmapSingleSize(i) && params.MipHeight(i) == height) { | 1305 | if (memory == params.GetMipmapSingleSize(i) && params.MipHeight(i) == height) { |
| 1304 | mipmap = i; | 1306 | return {i}; |
| 1305 | return true; | ||
| 1306 | } | 1307 | } |
| 1307 | return false; | 1308 | } |
| 1309 | return {}; | ||
| 1308 | } | 1310 | } |
| 1309 | 1311 | ||
| 1310 | bool FindBestLayer(VAddr addr, const SurfaceParams params, u32 mipmap, u32& layer) { | 1312 | static std::optional<u32> TryFindBestLayer(VAddr addr, const SurfaceParams params, u32 mipmap) { |
| 1311 | std::size_t size = params.LayerMemorySize(); | 1313 | const std::size_t size = params.LayerMemorySize(); |
| 1312 | VAddr start = params.addr + params.GetMipmapLevelOffset(mipmap); | 1314 | VAddr start = params.addr + params.GetMipmapLevelOffset(mipmap); |
| 1313 | for (u32 i = 0; i < params.depth; i++) { | 1315 | for (u32 i = 0; i < params.depth; i++) { |
| 1314 | if (start == addr) { | 1316 | if (start == addr) { |
| 1315 | layer = i; | 1317 | return {i}; |
| 1316 | return true; | ||
| 1317 | } | 1318 | } |
| 1318 | start += size; | 1319 | start += size; |
| 1319 | } | 1320 | } |
| 1320 | return false; | 1321 | return {}; |
| 1321 | } | 1322 | } |
| 1322 | 1323 | ||
| 1323 | bool LayerFitReinterpretSurface(RasterizerCacheOpenGL& cache, const Surface render_surface, | 1324 | static bool LayerFitReinterpretSurface(RasterizerCacheOpenGL& cache, const Surface render_surface, |
| 1324 | const Surface blitted_surface) { | 1325 | const Surface blitted_surface) { |
| 1325 | const auto dst_params = blitted_surface->GetSurfaceParams(); | 1326 | const auto& dst_params = blitted_surface->GetSurfaceParams(); |
| 1326 | const auto src_params = render_surface->GetSurfaceParams(); | 1327 | const auto& src_params = render_surface->GetSurfaceParams(); |
| 1327 | u32 level = 0; | 1328 | const std::size_t src_memory_size = src_params.size_in_bytes; |
| 1328 | std::size_t src_memory_size = src_params.size_in_bytes; | 1329 | const std::optional<u32> level = |
| 1329 | if (FindBestMipMap(src_memory_size, dst_params, src_params.height, level)) { | 1330 | TryFindBestMipMap(src_memory_size, dst_params, src_params.height); |
| 1330 | if (src_params.width == dst_params.MipWidthGobAligned(level) && | 1331 | if (level.has_value()) { |
| 1331 | src_params.height == dst_params.MipHeight(level) && | 1332 | if (src_params.width == dst_params.MipWidthGobAligned(*level) && |
| 1332 | src_params.block_height >= dst_params.MipBlockHeight(level)) { | 1333 | src_params.height == dst_params.MipHeight(*level) && |
| 1333 | u32 slot = 0; | 1334 | src_params.block_height >= dst_params.MipBlockHeight(*level)) { |
| 1334 | if (FindBestLayer(render_surface->GetAddr(), dst_params, level, slot)) { | 1335 | const std::optional<u32> slot = |
| 1335 | glCopyImageSubData( | 1336 | TryFindBestLayer(render_surface->GetAddr(), dst_params, *level); |
| 1336 | render_surface->Texture().handle, SurfaceTargetToGL(src_params.target), 0, 0, 0, | 1337 | if (slot.has_value()) { |
| 1337 | 0, blitted_surface->Texture().handle, SurfaceTargetToGL(dst_params.target), | 1338 | glCopyImageSubData(render_surface->Texture().handle, |
| 1338 | level, 0, 0, slot, dst_params.MipWidth(level), dst_params.MipHeight(level), 1); | 1339 | SurfaceTargetToGL(src_params.target), 0, 0, 0, 0, |
| 1340 | blitted_surface->Texture().handle, | ||
| 1341 | SurfaceTargetToGL(dst_params.target), *level, 0, 0, *slot, | ||
| 1342 | dst_params.MipWidth(*level), dst_params.MipHeight(*level), 1); | ||
| 1339 | blitted_surface->MarkAsModified(true, cache); | 1343 | blitted_surface->MarkAsModified(true, cache); |
| 1340 | return true; | 1344 | return true; |
| 1341 | } | 1345 | } |
| @@ -1344,24 +1348,21 @@ bool LayerFitReinterpretSurface(RasterizerCacheOpenGL& cache, const Surface rend | |||
| 1344 | return false; | 1348 | return false; |
| 1345 | } | 1349 | } |
| 1346 | 1350 | ||
| 1347 | bool IsReinterpretInvalid(const Surface render_surface, const Surface blitted_surface) { | 1351 | static bool IsReinterpretInvalid(const Surface render_surface, const Surface blitted_surface) { |
| 1348 | VAddr bound1 = blitted_surface->GetAddr() + blitted_surface->GetMemorySize(); | 1352 | const VAddr bound1 = blitted_surface->GetAddr() + blitted_surface->GetMemorySize(); |
| 1349 | VAddr bound2 = render_surface->GetAddr() + render_surface->GetMemorySize(); | 1353 | const VAddr bound2 = render_surface->GetAddr() + render_surface->GetMemorySize(); |
| 1350 | if (bound2 > bound1) | 1354 | if (bound2 > bound1) |
| 1351 | return true; | 1355 | return true; |
| 1352 | const auto dst_params = blitted_surface->GetSurfaceParams(); | 1356 | const auto& dst_params = blitted_surface->GetSurfaceParams(); |
| 1353 | const auto src_params = render_surface->GetSurfaceParams(); | 1357 | const auto& src_params = render_surface->GetSurfaceParams(); |
| 1354 | if (dst_params.component_type != src_params.component_type) | 1358 | return (dst_params.component_type != src_params.component_type); |
| 1355 | return true; | ||
| 1356 | return false; | ||
| 1357 | } | 1359 | } |
| 1358 | 1360 | ||
| 1359 | bool IsReinterpretInvalidSecond(const Surface render_surface, const Surface blitted_surface) { | 1361 | static bool IsReinterpretInvalidSecond(const Surface render_surface, |
| 1360 | const auto dst_params = blitted_surface->GetSurfaceParams(); | 1362 | const Surface blitted_surface) { |
| 1361 | const auto src_params = render_surface->GetSurfaceParams(); | 1363 | const auto& dst_params = blitted_surface->GetSurfaceParams(); |
| 1362 | if (dst_params.height > src_params.height && dst_params.width > src_params.width) | 1364 | const auto& src_params = render_surface->GetSurfaceParams(); |
| 1363 | return false; | 1365 | return (dst_params.height > src_params.height && dst_params.width > src_params.width); |
| 1364 | return true; | ||
| 1365 | } | 1366 | } |
| 1366 | 1367 | ||
| 1367 | bool RasterizerCacheOpenGL::PartialReinterpretSurface(Surface triggering_surface, | 1368 | bool RasterizerCacheOpenGL::PartialReinterpretSurface(Surface triggering_surface, |
| @@ -1383,7 +1384,7 @@ bool RasterizerCacheOpenGL::PartialReinterpretSurface(Surface triggering_surface | |||
| 1383 | } | 1384 | } |
| 1384 | 1385 | ||
| 1385 | void RasterizerCacheOpenGL::SignalPreDrawCall() { | 1386 | void RasterizerCacheOpenGL::SignalPreDrawCall() { |
| 1386 | if (texception) { | 1387 | if (texception && GLAD_GL_ARB_texture_barrier) { |
| 1387 | glTextureBarrier(); | 1388 | glTextureBarrier(); |
| 1388 | } | 1389 | } |
| 1389 | texception = false; | 1390 | 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: | |||
| 412 | reinterpreted = true; | 412 | reinterpreted = true; |
| 413 | } | 413 | } |
| 414 | 414 | ||
| 415 | bool IsReinterpreted() { | 415 | bool IsReinterpreted() const { |
| 416 | return reinterpreted; | 416 | return reinterpreted; |
| 417 | } | 417 | } |
| 418 | 418 | ||
| @@ -420,11 +420,11 @@ public: | |||
| 420 | must_reload = reload; | 420 | must_reload = reload; |
| 421 | } | 421 | } |
| 422 | 422 | ||
| 423 | bool MustReload() { | 423 | bool MustReload() const { |
| 424 | return must_reload; | 424 | return must_reload; |
| 425 | } | 425 | } |
| 426 | 426 | ||
| 427 | bool IsUploaded() { | 427 | bool IsUploaded() const { |
| 428 | return params.identity == SurfaceParams::SurfaceClass::Uploaded; | 428 | return params.identity == SurfaceParams::SurfaceClass::Uploaded; |
| 429 | } | 429 | } |
| 430 | 430 | ||
| @@ -489,6 +489,7 @@ private: | |||
| 489 | Surface TryGetReservedSurface(const SurfaceParams& params); | 489 | Surface TryGetReservedSurface(const SurfaceParams& params); |
| 490 | 490 | ||
| 491 | // Partialy reinterpret a surface based on a triggering_surface that collides with it. | 491 | // Partialy reinterpret a surface based on a triggering_surface that collides with it. |
| 492 | // returns true if the reinterpret was successful, false in case it was not. | ||
| 492 | bool PartialReinterpretSurface(Surface triggering_surface, Surface intersect); | 493 | bool PartialReinterpretSurface(Surface triggering_surface, Surface intersect); |
| 493 | 494 | ||
| 494 | /// Performs a slow but accurate surface copy, flushing to RAM and reinterpreting the data | 495 | /// Performs a slow but accurate surface copy, flushing to RAM and reinterpreting the data |
| @@ -528,10 +529,10 @@ private: | |||
| 528 | // Reinterpreted surfaces are very fragil as the game may keep rendering into them. | 529 | // Reinterpreted surfaces are very fragil as the game may keep rendering into them. |
| 529 | SurfaceIntervalCache reinterpreted_surfaces; | 530 | SurfaceIntervalCache reinterpreted_surfaces; |
| 530 | 531 | ||
| 531 | void RegisterReinterpretSurface(Surface r_surface) { | 532 | void RegisterReinterpretSurface(Surface reinterpret_surface) { |
| 532 | auto interval = GetReinterpretInterval(r_surface); | 533 | auto interval = GetReinterpretInterval(reinterpret_surface); |
| 533 | reinterpreted_surfaces.insert({interval, r_surface}); | 534 | reinterpreted_surfaces.insert({interval, reinterpret_surface}); |
| 534 | r_surface->MarkReinterpreted(); | 535 | reinterpret_surface->MarkReinterpreted(); |
| 535 | } | 536 | } |
| 536 | 537 | ||
| 537 | Surface CollideOnReinterpretedSurface(VAddr addr) const { | 538 | Surface CollideOnReinterpretedSurface(VAddr addr) const { |
| @@ -543,14 +544,12 @@ private: | |||
| 543 | return nullptr; | 544 | return nullptr; |
| 544 | } | 545 | } |
| 545 | 546 | ||
| 546 | protected: | ||
| 547 | void Register(const Surface& object) { | 547 | void Register(const Surface& object) { |
| 548 | RasterizerCache<Surface>::Register(object); | 548 | RasterizerCache<Surface>::Register(object); |
| 549 | } | 549 | } |
| 550 | 550 | ||
| 551 | /// Unregisters an object from the cache | 551 | /// Unregisters an object from the cache |
| 552 | void Unregister(const Surface& object) { | 552 | void Unregister(const Surface& object) { |
| 553 | const auto& params = object->GetSurfaceParams(); | ||
| 554 | if (object->IsReinterpreted()) { | 553 | if (object->IsReinterpreted()) { |
| 555 | auto interval = GetReinterpretInterval(object); | 554 | auto interval = GetReinterpretInterval(object); |
| 556 | reinterpreted_surfaces.erase(interval); | 555 | reinterpreted_surfaces.erase(interval); |