diff options
| author | 2019-04-20 20:01:26 -0300 | |
|---|---|---|
| committer | 2019-06-20 21:36:11 -0300 | |
| commit | 2787a0c2875c6c686a50a03e446099124824b17f (patch) | |
| tree | a025917ee353401e5880089e0038a0ea953ffb37 /src | |
| parent | gl_texture_cache: Minor changes (diff) | |
| download | yuzu-2787a0c2875c6c686a50a03e446099124824b17f.tar.gz yuzu-2787a0c2875c6c686a50a03e446099124824b17f.tar.xz yuzu-2787a0c2875c6c686a50a03e446099124824b17f.zip | |
texture_cache: Flush 3D textures in the order they are drawn
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.cpp | 5 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.h | 6 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 1 | ||||
| -rw-r--r-- | src/video_core/texture_cache.cpp | 11 | ||||
| -rw-r--r-- | src/video_core/texture_cache.h | 40 |
5 files changed, 44 insertions, 19 deletions
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index da2d1e63a..362f4019c 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp | |||
| @@ -235,8 +235,9 @@ void SwizzleFunc(MortonSwizzleMode mode, u8* memory, const SurfaceParams& params | |||
| 235 | 235 | ||
| 236 | } // Anonymous namespace | 236 | } // Anonymous namespace |
| 237 | 237 | ||
| 238 | CachedSurface::CachedSurface(const SurfaceParams& params) | 238 | CachedSurface::CachedSurface(TextureCacheOpenGL& texture_cache, const SurfaceParams& params) |
| 239 | : VideoCommon::SurfaceBaseContextless<CachedSurfaceView>{params} { | 239 | : VideoCommon::SurfaceBaseContextless<TextureCacheOpenGL, CachedSurfaceView>{texture_cache, |
| 240 | params} { | ||
| 240 | const auto& tuple{GetFormatTuple(params.GetPixelFormat(), params.GetComponentType())}; | 241 | const auto& tuple{GetFormatTuple(params.GetPixelFormat(), params.GetComponentType())}; |
| 241 | internal_format = tuple.internal_format; | 242 | internal_format = tuple.internal_format; |
| 242 | format = tuple.format; | 243 | format = tuple.format; |
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h index 8705db74c..e6448c6f8 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.h +++ b/src/video_core/renderer_opengl/gl_texture_cache.h | |||
| @@ -26,15 +26,17 @@ using VideoCore::Surface::SurfaceType; | |||
| 26 | 26 | ||
| 27 | class CachedSurfaceView; | 27 | class CachedSurfaceView; |
| 28 | class CachedSurface; | 28 | class CachedSurface; |
| 29 | class TextureCacheOpenGL; | ||
| 29 | 30 | ||
| 30 | using Surface = std::shared_ptr<CachedSurface>; | 31 | using Surface = std::shared_ptr<CachedSurface>; |
| 31 | using TextureCacheBase = VideoCommon::TextureCacheContextless<CachedSurface, CachedSurfaceView>; | 32 | using TextureCacheBase = VideoCommon::TextureCacheContextless<CachedSurface, CachedSurfaceView>; |
| 32 | 33 | ||
| 33 | class CachedSurface final : public VideoCommon::SurfaceBaseContextless<CachedSurfaceView> { | 34 | class CachedSurface final |
| 35 | : public VideoCommon::SurfaceBaseContextless<TextureCacheOpenGL, CachedSurfaceView> { | ||
| 34 | friend CachedSurfaceView; | 36 | friend CachedSurfaceView; |
| 35 | 37 | ||
| 36 | public: | 38 | public: |
| 37 | explicit CachedSurface(const SurfaceParams& params); | 39 | explicit CachedSurface(TextureCacheOpenGL& texture_cache, const SurfaceParams& params); |
| 38 | ~CachedSurface(); | 40 | ~CachedSurface(); |
| 39 | 41 | ||
| 40 | void LoadBuffer(); | 42 | void LoadBuffer(); |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 710bf8303..aafd6f31b 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
| @@ -460,7 +460,6 @@ static void APIENTRY DebugHandler(GLenum source, GLenum type, GLuint id, GLenum | |||
| 460 | switch (severity) { | 460 | switch (severity) { |
| 461 | case GL_DEBUG_SEVERITY_HIGH: | 461 | case GL_DEBUG_SEVERITY_HIGH: |
| 462 | LOG_CRITICAL(Render_OpenGL, format, str_source, str_type, id, message); | 462 | LOG_CRITICAL(Render_OpenGL, format, str_source, str_type, id, message); |
| 463 | __debugbreak(); | ||
| 464 | break; | 463 | break; |
| 465 | case GL_DEBUG_SEVERITY_MEDIUM: | 464 | case GL_DEBUG_SEVERITY_MEDIUM: |
| 466 | LOG_WARNING(Render_OpenGL, format, str_source, str_type, id, message); | 465 | LOG_WARNING(Render_OpenGL, format, str_source, str_type, id, message); |
diff --git a/src/video_core/texture_cache.cpp b/src/video_core/texture_cache.cpp index b47ce6b98..b78a7d951 100644 --- a/src/video_core/texture_cache.cpp +++ b/src/video_core/texture_cache.cpp | |||
| @@ -154,8 +154,8 @@ bool SurfaceParams::IsLayered() const { | |||
| 154 | switch (target) { | 154 | switch (target) { |
| 155 | case SurfaceTarget::Texture1DArray: | 155 | case SurfaceTarget::Texture1DArray: |
| 156 | case SurfaceTarget::Texture2DArray: | 156 | case SurfaceTarget::Texture2DArray: |
| 157 | case SurfaceTarget::TextureCubeArray: | ||
| 158 | case SurfaceTarget::TextureCubemap: | 157 | case SurfaceTarget::TextureCubemap: |
| 158 | case SurfaceTarget::TextureCubeArray: | ||
| 159 | return true; | 159 | return true; |
| 160 | default: | 160 | default: |
| 161 | return false; | 161 | return false; |
| @@ -192,9 +192,11 @@ u32 SurfaceParams::GetMipBlockDepth(u32 level) const { | |||
| 192 | while (block_depth > 1 && depth * 2 <= block_depth) { | 192 | while (block_depth > 1 && depth * 2 <= block_depth) { |
| 193 | block_depth >>= 1; | 193 | block_depth >>= 1; |
| 194 | } | 194 | } |
| 195 | |||
| 195 | if (block_depth == 32 && GetMipBlockHeight(level) >= 4) { | 196 | if (block_depth == 32 && GetMipBlockHeight(level) >= 4) { |
| 196 | return 16; | 197 | return 16; |
| 197 | } | 198 | } |
| 199 | |||
| 198 | return block_depth; | 200 | return block_depth; |
| 199 | } | 201 | } |
| 200 | 202 | ||
| @@ -227,7 +229,7 @@ std::size_t SurfaceParams::GetLayerSize(bool as_host_size, bool uncompressed) co | |||
| 227 | for (u32 level = 0; level < num_levels; ++level) { | 229 | for (u32 level = 0; level < num_levels; ++level) { |
| 228 | size += GetInnerMipmapMemorySize(level, as_host_size, uncompressed); | 230 | size += GetInnerMipmapMemorySize(level, as_host_size, uncompressed); |
| 229 | } | 231 | } |
| 230 | if (is_tiled && IsLayered()) { | 232 | if (is_tiled && (IsLayered() || target == SurfaceTarget::Texture3D)) { |
| 231 | return Common::AlignUp(size, Tegra::Texture::GetGOBSize() * block_height * block_depth); | 233 | return Common::AlignUp(size, Tegra::Texture::GetGOBSize() * block_height * block_depth); |
| 232 | } | 234 | } |
| 233 | return size; | 235 | return size; |
| @@ -312,9 +314,10 @@ void SurfaceParams::CalculateCachedValues() { | |||
| 312 | 314 | ||
| 313 | guest_size_in_bytes = GetInnerMemorySize(false, false, false); | 315 | guest_size_in_bytes = GetInnerMemorySize(false, false, false); |
| 314 | 316 | ||
| 315 | // ASTC is uncompressed in software, in emulated as RGBA8 | ||
| 316 | if (IsPixelFormatASTC(pixel_format)) { | 317 | if (IsPixelFormatASTC(pixel_format)) { |
| 317 | host_size_in_bytes = static_cast<std::size_t>(width * height * depth * 4U); | 318 | // ASTC is uncompressed in software, in emulated as RGBA8 |
| 319 | host_size_in_bytes = static_cast<std::size_t>(width) * static_cast<std::size_t>(height) * | ||
| 320 | static_cast<std::size_t>(depth) * 4ULL; | ||
| 318 | } else { | 321 | } else { |
| 319 | host_size_in_bytes = GetInnerMemorySize(true, false, false); | 322 | host_size_in_bytes = GetInnerMemorySize(true, false, false); |
| 320 | } | 323 | } |
diff --git a/src/video_core/texture_cache.h b/src/video_core/texture_cache.h index 0e289d378..f22e8e776 100644 --- a/src/video_core/texture_cache.h +++ b/src/video_core/texture_cache.h | |||
| @@ -273,7 +273,7 @@ struct hash<VideoCommon::ViewKey> { | |||
| 273 | 273 | ||
| 274 | namespace VideoCommon { | 274 | namespace VideoCommon { |
| 275 | 275 | ||
| 276 | template <typename TView, typename TExecutionContext> | 276 | template <typename TTextureCache, typename TView, typename TExecutionContext> |
| 277 | class SurfaceBase { | 277 | class SurfaceBase { |
| 278 | static_assert(std::is_trivially_copyable_v<TExecutionContext>); | 278 | static_assert(std::is_trivially_copyable_v<TExecutionContext>); |
| 279 | 279 | ||
| @@ -331,6 +331,9 @@ public: | |||
| 331 | 331 | ||
| 332 | void MarkAsModified(bool is_modified_) { | 332 | void MarkAsModified(bool is_modified_) { |
| 333 | is_modified = is_modified_; | 333 | is_modified = is_modified_; |
| 334 | if (is_modified_) { | ||
| 335 | modification_tick = texture_cache.Tick(); | ||
| 336 | } | ||
| 334 | } | 337 | } |
| 335 | 338 | ||
| 336 | const SurfaceParams& GetSurfaceParams() const { | 339 | const SurfaceParams& GetSurfaceParams() const { |
| @@ -358,13 +361,18 @@ public: | |||
| 358 | is_registered = false; | 361 | is_registered = false; |
| 359 | } | 362 | } |
| 360 | 363 | ||
| 364 | u64 GetModificationTick() const { | ||
| 365 | return modification_tick; | ||
| 366 | } | ||
| 367 | |||
| 361 | bool IsRegistered() const { | 368 | bool IsRegistered() const { |
| 362 | return is_registered; | 369 | return is_registered; |
| 363 | } | 370 | } |
| 364 | 371 | ||
| 365 | protected: | 372 | protected: |
| 366 | explicit SurfaceBase(const SurfaceParams& params) | 373 | explicit SurfaceBase(TTextureCache& texture_cache, const SurfaceParams& params) |
| 367 | : params{params}, view_offset_map{params.CreateViewOffsetMap()} {} | 374 | : params{params}, texture_cache{texture_cache}, view_offset_map{ |
| 375 | params.CreateViewOffsetMap()} {} | ||
| 368 | 376 | ||
| 369 | ~SurfaceBase() = default; | 377 | ~SurfaceBase() = default; |
| 370 | 378 | ||
| @@ -389,12 +397,14 @@ private: | |||
| 389 | return view.get(); | 397 | return view.get(); |
| 390 | } | 398 | } |
| 391 | 399 | ||
| 400 | TTextureCache& texture_cache; | ||
| 392 | const std::map<u64, std::pair<u32, u32>> view_offset_map; | 401 | const std::map<u64, std::pair<u32, u32>> view_offset_map; |
| 393 | 402 | ||
| 394 | GPUVAddr gpu_addr{}; | 403 | GPUVAddr gpu_addr{}; |
| 395 | VAddr cpu_addr{}; | 404 | VAddr cpu_addr{}; |
| 396 | u8* host_ptr{}; | 405 | u8* host_ptr{}; |
| 397 | CacheAddr cache_addr{}; | 406 | CacheAddr cache_addr{}; |
| 407 | u64 modification_tick{}; | ||
| 398 | bool is_modified{}; | 408 | bool is_modified{}; |
| 399 | bool is_registered{}; | 409 | bool is_registered{}; |
| 400 | std::unordered_map<ViewKey, std::unique_ptr<TView>> views; | 410 | std::unordered_map<ViewKey, std::unique_ptr<TView>> views; |
| @@ -475,6 +485,10 @@ public: | |||
| 475 | return it != registered_surfaces.end() ? *it->second.begin() : nullptr; | 485 | return it != registered_surfaces.end() ? *it->second.begin() : nullptr; |
| 476 | } | 486 | } |
| 477 | 487 | ||
| 488 | u64 Tick() { | ||
| 489 | return ++ticks; | ||
| 490 | } | ||
| 491 | |||
| 478 | protected: | 492 | protected: |
| 479 | TextureCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer) | 493 | TextureCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer) |
| 480 | : system{system}, rasterizer{rasterizer} {} | 494 | : system{system}, rasterizer{rasterizer} {} |
| @@ -521,7 +535,7 @@ private: | |||
| 521 | 535 | ||
| 522 | const auto host_ptr{memory_manager.GetPointer(gpu_addr)}; | 536 | const auto host_ptr{memory_manager.GetPointer(gpu_addr)}; |
| 523 | const auto cache_addr{ToCacheAddr(host_ptr)}; | 537 | const auto cache_addr{ToCacheAddr(host_ptr)}; |
| 524 | const auto overlaps{GetSurfacesInRegion(cache_addr, params.GetGuestSizeInBytes())}; | 538 | auto overlaps{GetSurfacesInRegion(cache_addr, params.GetGuestSizeInBytes())}; |
| 525 | if (overlaps.empty()) { | 539 | if (overlaps.empty()) { |
| 526 | return LoadSurfaceView(exctx, gpu_addr, *cpu_addr, host_ptr, params, preserve_contents); | 540 | return LoadSurfaceView(exctx, gpu_addr, *cpu_addr, host_ptr, params, preserve_contents); |
| 527 | } | 541 | } |
| @@ -544,8 +558,8 @@ private: | |||
| 544 | 558 | ||
| 545 | for (const auto& surface : overlaps) { | 559 | for (const auto& surface : overlaps) { |
| 546 | if (!fast_view) { | 560 | if (!fast_view) { |
| 547 | // Flush even when we don't care about the contents, to preserve memory not written | 561 | // Flush even when we don't care about the contents, to preserve memory not |
| 548 | // by the new surface. | 562 | // written by the new surface. |
| 549 | exctx = surface->FlushBuffer(exctx); | 563 | exctx = surface->FlushBuffer(exctx); |
| 550 | } | 564 | } |
| 551 | Unregister(surface); | 565 | Unregister(surface); |
| @@ -614,6 +628,8 @@ private: | |||
| 614 | 628 | ||
| 615 | VideoCore::RasterizerInterface& rasterizer; | 629 | VideoCore::RasterizerInterface& rasterizer; |
| 616 | 630 | ||
| 631 | u64 ticks{}; | ||
| 632 | |||
| 617 | IntervalMap registered_surfaces; | 633 | IntervalMap registered_surfaces; |
| 618 | 634 | ||
| 619 | /// The surface reserve is a "backup" cache, this is where we put unique surfaces that have | 635 | /// The surface reserve is a "backup" cache, this is where we put unique surfaces that have |
| @@ -653,6 +669,10 @@ public: | |||
| 653 | return Base::TryFindFramebufferSurface(host_ptr); | 669 | return Base::TryFindFramebufferSurface(host_ptr); |
| 654 | } | 670 | } |
| 655 | 671 | ||
| 672 | u64 Tick() { | ||
| 673 | return Base::Tick(); | ||
| 674 | } | ||
| 675 | |||
| 656 | protected: | 676 | protected: |
| 657 | explicit TextureCacheContextless(Core::System& system, | 677 | explicit TextureCacheContextless(Core::System& system, |
| 658 | VideoCore::RasterizerInterface& rasterizer) | 678 | VideoCore::RasterizerInterface& rasterizer) |
| @@ -678,8 +698,8 @@ private: | |||
| 678 | } | 698 | } |
| 679 | }; | 699 | }; |
| 680 | 700 | ||
| 681 | template <typename TView> | 701 | template <typename TTextureCache, typename TView> |
| 682 | class SurfaceBaseContextless : public SurfaceBase<TView, DummyExecutionContext> { | 702 | class SurfaceBaseContextless : public SurfaceBase<TTextureCache, TView, DummyExecutionContext> { |
| 683 | public: | 703 | public: |
| 684 | DummyExecutionContext FlushBuffer(DummyExecutionContext) { | 704 | DummyExecutionContext FlushBuffer(DummyExecutionContext) { |
| 685 | FlushBufferImpl(); | 705 | FlushBufferImpl(); |
| @@ -692,8 +712,8 @@ public: | |||
| 692 | } | 712 | } |
| 693 | 713 | ||
| 694 | protected: | 714 | protected: |
| 695 | explicit SurfaceBaseContextless(const SurfaceParams& params) | 715 | explicit SurfaceBaseContextless(TTextureCache& texture_cache, const SurfaceParams& params) |
| 696 | : SurfaceBase<TView, DummyExecutionContext>{params} {} | 716 | : SurfaceBase<TTextureCache, TView, DummyExecutionContext>{texture_cache, params} {} |
| 697 | 717 | ||
| 698 | virtual void FlushBufferImpl() = 0; | 718 | virtual void FlushBufferImpl() = 0; |
| 699 | 719 | ||