diff options
| author | 2019-05-08 10:32:30 -0400 | |
|---|---|---|
| committer | 2019-06-20 21:36:12 -0300 | |
| commit | ba677ccb5a8ae0c889751fcdd40b0c9e818ad992 (patch) | |
| tree | 79a5166a90d59fb0f00a88136697252fe42cb731 /src/video_core/texture_cache | |
| parent | Fixes to mipmap's process and reconstruct process (diff) | |
| download | yuzu-ba677ccb5a8ae0c889751fcdd40b0c9e818ad992.tar.gz yuzu-ba677ccb5a8ae0c889751fcdd40b0c9e818ad992.tar.xz yuzu-ba677ccb5a8ae0c889751fcdd40b0c9e818ad992.zip | |
texture_cache: Implement guest flushing
Diffstat (limited to 'src/video_core/texture_cache')
| -rw-r--r-- | src/video_core/texture_cache/surface_base.cpp | 19 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache.h | 14 |
2 files changed, 25 insertions, 8 deletions
diff --git a/src/video_core/texture_cache/surface_base.cpp b/src/video_core/texture_cache/surface_base.cpp index 5e994cf08..dc5013240 100644 --- a/src/video_core/texture_cache/surface_base.cpp +++ b/src/video_core/texture_cache/surface_base.cpp | |||
| @@ -63,6 +63,9 @@ void SurfaceBaseImpl::LoadBuffer(Tegra::MemoryManager& memory_manager, | |||
| 63 | std::vector<u8>& staging_buffer) { | 63 | std::vector<u8>& staging_buffer) { |
| 64 | MICROPROFILE_SCOPE(GPU_Load_Texture); | 64 | MICROPROFILE_SCOPE(GPU_Load_Texture); |
| 65 | const auto host_ptr{memory_manager.GetPointer(gpu_addr)}; | 65 | const auto host_ptr{memory_manager.GetPointer(gpu_addr)}; |
| 66 | if (!host_ptr) { | ||
| 67 | return; | ||
| 68 | } | ||
| 66 | if (params.is_tiled) { | 69 | if (params.is_tiled) { |
| 67 | ASSERT_MSG(params.block_width == 1, "Block width is defined as {} on texture target {}", | 70 | ASSERT_MSG(params.block_width == 1, "Block width is defined as {} on texture target {}", |
| 68 | params.block_width, static_cast<u32>(params.target)); | 71 | params.block_width, static_cast<u32>(params.target)); |
| @@ -103,7 +106,10 @@ void SurfaceBaseImpl::LoadBuffer(Tegra::MemoryManager& memory_manager, | |||
| 103 | void SurfaceBaseImpl::FlushBuffer(Tegra::MemoryManager& memory_manager, | 106 | void SurfaceBaseImpl::FlushBuffer(Tegra::MemoryManager& memory_manager, |
| 104 | std::vector<u8>& staging_buffer) { | 107 | std::vector<u8>& staging_buffer) { |
| 105 | MICROPROFILE_SCOPE(GPU_Flush_Texture); | 108 | MICROPROFILE_SCOPE(GPU_Flush_Texture); |
| 106 | auto host_ptr = memory_manager.GetPointer(gpu_addr); | 109 | const auto host_ptr{memory_manager.GetPointer(gpu_addr)}; |
| 110 | if (!host_ptr) { | ||
| 111 | return; | ||
| 112 | } | ||
| 107 | if (params.is_tiled) { | 113 | if (params.is_tiled) { |
| 108 | ASSERT_MSG(params.block_width == 1, "Block width is defined as {}", params.block_width); | 114 | ASSERT_MSG(params.block_width == 1, "Block width is defined as {}", params.block_width); |
| 109 | for (u32 level = 0; level < params.num_levels; ++level) { | 115 | for (u32 level = 0; level < params.num_levels; ++level) { |
| @@ -112,25 +118,22 @@ void SurfaceBaseImpl::FlushBuffer(Tegra::MemoryManager& memory_manager, | |||
| 112 | staging_buffer.data() + host_offset, level); | 118 | staging_buffer.data() + host_offset, level); |
| 113 | } | 119 | } |
| 114 | } else { | 120 | } else { |
| 115 | UNIMPLEMENTED(); | ||
| 116 | /* | ||
| 117 | ASSERT(params.target == SurfaceTarget::Texture2D); | 121 | ASSERT(params.target == SurfaceTarget::Texture2D); |
| 118 | ASSERT(params.num_levels == 1); | 122 | ASSERT(params.num_levels == 1); |
| 119 | 123 | ||
| 120 | const u32 bpp{params.GetFormatBpp() / 8}; | 124 | const u32 bpp{params.GetBytesPerPixel()}; |
| 121 | const u32 copy_size{params.width * bpp}; | 125 | const u32 copy_size{params.width * bpp}; |
| 122 | if (params.pitch == copy_size) { | 126 | if (params.pitch == copy_size) { |
| 123 | std::memcpy(host_ptr, staging_buffer.data(), memory_size); | 127 | std::memcpy(host_ptr, staging_buffer.data(), guest_memory_size); |
| 124 | } else { | 128 | } else { |
| 125 | u8* start{host_ptr}; | 129 | u8* start{host_ptr}; |
| 126 | const u8* read_to{staging_buffer.data()}; | 130 | const u8* read_to{staging_buffer.data()}; |
| 127 | for (u32 h = params.GetHeight(); h > 0; --h) { | 131 | for (u32 h = params.height; h > 0; --h) { |
| 128 | std::memcpy(start, read_to, copy_size); | 132 | std::memcpy(start, read_to, copy_size); |
| 129 | start += params.GetPitch(); | 133 | start += params.pitch; |
| 130 | read_to += copy_size; | 134 | read_to += copy_size; |
| 131 | } | 135 | } |
| 132 | } | 136 | } |
| 133 | */ | ||
| 134 | } | 137 | } |
| 135 | } | 138 | } |
| 136 | 139 | ||
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 554b9a228..422bf3e58 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
| @@ -61,6 +61,20 @@ public: | |||
| 61 | } | 61 | } |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | void FlushRegion(CacheAddr addr, std::size_t size) { | ||
| 65 | auto surfaces = GetSurfacesInRegion(addr, size); | ||
| 66 | if (surfaces.empty()) { | ||
| 67 | return; | ||
| 68 | } | ||
| 69 | std::sort(surfaces.begin(), surfaces.end(), | ||
| 70 | [](const TSurface& a, const TSurface& b) -> bool { | ||
| 71 | return a->GetModificationTick() < b->GetModificationTick(); | ||
| 72 | }); | ||
| 73 | for (const auto& surface : surfaces) { | ||
| 74 | FlushSurface(surface); | ||
| 75 | } | ||
| 76 | } | ||
| 77 | |||
| 64 | TView GetTextureSurface(const Tegra::Texture::FullTextureInfo& config, | 78 | TView GetTextureSurface(const Tegra::Texture::FullTextureInfo& config, |
| 65 | const VideoCommon::Shader::Sampler& entry) { | 79 | const VideoCommon::Shader::Sampler& entry) { |
| 66 | const auto gpu_addr{config.tic.Address()}; | 80 | const auto gpu_addr{config.tic.Address()}; |